In sharded clusters, if you do not use the _id field as the shard key, then your application must ensure the uniqueness of the values in the _id field to prevent errors.

This is most-often done by using a standard auto-generated ObjectId.

在分片中,也要保证object id的唯一性

整理自:

https://www.cnblogs.com/chenmh/p/8954584.html

https://cloud.tencent.com/developer/article/1451897

《MongoDB权威指南》

MongoDB拆分数据常用的数据分发方式有三种:

升序片键

随机分发片键

基于位置片键

一、升序片键

1.1 什么是升序片键

升序片键通常有点类似于date字段或者时objectId,是一种随着时间稳定增长的字段。

1.2 升序片键数据插入表现

升序片键在数据插入会带来一些属性,通常是不良属性

1、最大快现象

假设要建立一个新文档,它会位于哪个块?答案是范围为objectId("5115aa552cascsa222")到

$maxkey的块。这个块叫做最大快。因为此块包含$maxkey。

所有的写都会被路由到一个分片中。该块是唯一一个不断增长和拆分的块,因为他是唯一一个能够接收到插入请求的块。

随着新数据的不断插入,该最大块会不断拆分处新的小块。

2、分片内的数据块不均匀

这种模式经常导致MongoDB的数据均匀处理变得更为困难,因为所有的新块都是由同一分片创建。因此,

MongoDB必须不断将一些块移入其他分片,而不能像在一个比较均匀的分发系统中那样,只需纠正那些

比较小的不均衡就好了。

二、随机分发的片键

2.1 什么是随机分发片键

随即分发的键可以是用户名、邮件地址、UDID(唯一设备标识符)、MD5散列值,或者是数据集中其他一些

没有规律的键。

2.2 随即分发片键数据插入表现

1、写入数据是随机分发,各个片键增长速度应大致相同,减少了需要进行迁移的次数

2、随即分发唯一弊端在于

MongoDB在随机访问超出RAM大小的数据失效率不高。然而,如果拥有足够多的RAM或者是并不介意系统

性能的话,使用随机片键在集群上分配负载是非常好的。

三、基于位置的片键

3.1 什么是基于位置的片键

基于位置的片键可以是用户的IP、经纬度、或者是地址。

位置片键不必与实际的物理位置字段相关:这里的位置比较抽象,数据会依据这个位置进行分组。无论

如何,所有与该键值比较接近的文档都会被保存在同一范围的块中。这样可以比较方便的将数据与相应的

用户,以及相关联的数据保存在一起。

3.2 基于位置的片键数据插入表现

1、使用tag将特定范围的块出现在特定的分片中。

比如:IP段,让“56.*.*.*"(美国邮政署的IP段)出现在shard0000,让"17.*.*.*"(苹果公司的IP段)出现在

shard0000或者shard0002上。

>sh.addShardTag("shard0000","USPS")

>sh.addShardTag("shard0000","Apple")

>sh.addShardTag("shard0002","Apple")

四、片键策略

针对不同类型应用程序的几种片键选项

4.1 散列片键

1、散列片键特性

优点:

如果追求数据加载速度的极致,那么散列片键(Hashed Shard Key)是最佳选择。

散列片键可使其他任何键随机分发,因此,如果打算在大量查询中使用升序键,但同时又希望写入

数据随机分发的话,散列片键是个非常好的选择。

弊端:

无法使用散列片键做指定目标的范围查询。如果无需做范围查询,那么散列片键就非常适合。

2、创建一个散列片键

1)数据库启用分片

>sh.enableSharding("app")

2)在已经存在集合上面使用散列片键

创建散列索引

>sh.users.ensureIndex({"username":"hashed"})

然后对集合分片

>sh.shardCollection("app.users",{"username":"hashed"})

3)在不存在的集合上面使用散列片键

语法同上,但是有如下注意点

MongoDB假设我们希望对数据块进行均衡分发,所以他会立即创建一些空的块,并将这些块分发在集群

中。

3、散列分片的局限

1)不能使用unique选项

2)与其他分片键一样,不能使用数组字段

3)浮点型的值会被取证,然后才进行散列,所以1和1.999会得到形同的散列值

4.2 Ranged Sharding 范围片键

通过分片键的值来将数据分成不同的范围。它可以提供比较快的范围查询,但是当分片键选择不好的时候,也会降低读写性能 。 如果没有配置Hashed Sharding或者zones(https://docs.mongodb.com/manual/core/zone-sharding/#zone-sharding)它是默认的分片键方法。

sh.shardCollection( "database.collection", { <shard key> } )

大致分布见下图:

4.3zones sharding(列表分区)

The following image illustrates a sharded cluster with three shards and two zones. The A zone represents a range with a lower boundary of 1 and an upper bound of 10. The B zone represents a range with a lower boundary of 10 and an upper boundary of 20. Shards Alpha and Beta have the A zone. Shard Beta also has the B zone. Shard Charlie has no zones associated with it. The cluster is in a steady state and no chunks violate any of the zones.

For example, given a shard key { a : 1, b : 2, c : 3 }, creating or updating a zone to cover values of b requires including a as the prefix. Creating or updating a zone to covers values of c requires including a and b as the prefix. 创建shard tag:

sh.addShardTag("shard0000", "NYC")sh.addShardTag("shard0001", "NYC")sh.addShardTag("shard0002", "SFO")sh.addShardTag("shard0002", "NRT")

创建zone rang:

sh.addTagRange("records.users", { zipcode: "10001" }, { zipcode: "10281" }, "NYC")sh.addTagRange("records.users", { zipcode: "11201" }, { zipcode: "11240" }, "NYC")sh.addTagRange("records.users", { zipcode: "94102" }, { zipcode: "94135" }, "SFO")

参考:https://docs.mongodb.com/manual/tutorial/manage-shard-zone/

与hashed shard key一起使用时,zone的范围一般要覆盖minKey和maxKey才可以。 参考:https://docs.mongodb.com/manual/core/zone-sharding/#zone-sharding

比如对于一些日志非查询文档,可以通过标签将其只插入到某个分片中。例如

sh.addTagRange("test.log",{ "_id" : { "$minKey" : 1 }  }, { "_id" : { "$maxKey" : 1 } },"tag_rs-a");

可以在config库中的tag文档中查看设置的标签信息。

use config

db.tags.find();

4.4 组合片键

数据库中没有比较合适的片键供选择,或者是打算使用的片键基数太小(即变化少如星期只有7天可变化),可以选另一个字段使用组合片键,甚至可以添加冗余字段来组合。一般是粗粒度+细粒度进行组合。

组合片键的创建,对GridFS的chunks集合使用files_id和n组合分片。

组合分片是比较好的一种分片的选择,好的组合分片可以同时解决热点和随机读IO问题。例

1)数据库启用分片

sh.enableSharding("test")

2)集合设置分片键(新建分片情况)
sh.shardCollection("test.bbbb",{"username":1,"_id":1}); 3)查分片信息
sh.status()

MongoDB 分片键分类与数据分发的更多相关文章

  1. MongoDB 分片键的选择与案例

    MongoDB版本:3.6 一.分片键类别 1.升序片键 升序片键例如:日期时间字段.自增字段. 2.随机分发片键 随机分发片键例如:用户名.邮件名.UUID.MD5值或者是其它的一些没有规律的值的列 ...

  2. MongoDB 分片集群技术

    在了解分片集群之前,务必要先了解复制集技术! 1.1 MongoDB复制集简介 一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合.复制集提供了数据冗余和高等级的可靠性,这 ...

  3. MongoDB分片(Sharding)技术

    分片(sharding)是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法.尽管分片起源于关系型数据库分区,但MongoDB分片完全又是另一回事. 和MySQL分区方案相比 ...

  4. (转)MongoDB 分片集群技术

    1.1 MongoDB复制集简介 一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合.复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础. 1.1.1 复制集的目的 ...

  5. MogoDB 分片键

    MongoDB 根据分片键分割 collection 中的文档,然后分配到分片集群的成员中. 分片键可以是一个存在于每个文件中的索引字段或者复合索引字段. MongoDB 使用不同范围的分片键值来分割 ...

  6. TiDB和MongoDB分片集群架构比较

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近阅读了TiDB源码的说明文档,跟MongoDB的分片集群做了下简单对比. 首先展示TiDB的整体架构 M ...

  7. MongoDB 数据分发

    在MongoDB(版本 3.2.9)中,数据的分发是指将collection的数据拆分成块(chunk),分布到不同的分片(shard)上,数据分发主要有2种方式:基于数据块(chunk)数量的均衡分 ...

  8. MongoDB 分片管理(四)数据均衡 -- 特大快

    1.1 特大快形成 如果用date字段作为片键,集合中date是一个日期字符串,如:year/month/day,也就是说,mongoDB一天创建一个块.因块内所有文档的片键一样,因此这些块是不可拆分 ...

  9. MongoDB分片之数据分割方式

    随着移动互联网的发展,大量的非结构化数据随之产生,不仅对数据库存储大数据提出了新的要求,同时对于查询数据和进行大数据分析也提出了苛刻的要求,这些显然是单服务器处理能力无法满足的,自然建立一个集群是不可 ...

随机推荐

  1. ASP.Net Core 返回的json数据,自定义日期格式

    //代码位置:Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddMvc() .Ad ...

  2. input 被checked时和label配合的妙用

    input 和label配合的妙用 1:作为文字隐藏与否的开关: 如下代码:对div里面所包含的文字较多,一开始只展示小部分,当用户点击按钮时,进行全部内容的展示(按钮是以向下隐藏箭头的图片) htm ...

  3. Jerry Wang从2017年到2019年的自由泳学习笔记

    打腿 把注意力调整到脚部,尽量不要让他打出水面,因为在空气中大腿完全是无用功,但是如果只是脚跟出水一点,倒也没什么关心,但是主观上,要控制一下,如果你听到你的打腿是"咚咚咚咚"这样 ...

  4. nginx 作为静态资源web服务

    Nginx作为静态资源web服务 静态资源web服务-CDN场景 Nginx资源存储中心会把静态资源分发给“北京Nginx”,“湖南Nginx”,“山东Nginx”. 然后北京User发送静态资源请求 ...

  5. docker 推送镜像到阿里云

    1. 登录阿里云Docker Registry $ sudo docker login --username=www.18860363800@hotmail.com registry.cn-beiji ...

  6. Linux安装java环境和maven

    安装OpenJDK软件包: apt-get install openjdk-8-jdk 查看版本信息java -version 则代表安装成功 安装maven可以使用自己本机下载好的mavan使用Xf ...

  7. Django+bootstrap+注册登录系统

    转自:https://www.cnblogs.com/robindong/p/9610057.html Robin_D 博客园 首页 新随笔 联系 订阅 管理 随笔 - 10  文章 - 0  评论 ...

  8. Linux proc filesystem (procfs)

    参考:/proc /proc简介 本文着重关注/proc目录,查看其中文件并熟悉它. /proc目录存在于所有Linux系统上,无论什么发行版或体系结构.首先,必须澄清一个误解: 就文件系统这一术语而 ...

  9. kvm虚拟化环境的搭建

    首先搭建kvm的虚拟化环境,我选择的环境是在vmvare上的Centos 7的虚拟机,在该环境上搭建kvm的虚拟化环境 1:安装虚拟机(该过程自行安装) 2:操作系统环境的设置 (1)修改内核模式为兼 ...

  10. visual studio 使用技巧——vs技巧

    vs(visual studio)使用技巧: 1,vs有多个断点时,调试时,如果不想命中断点,可以在调试菜单下禁用所有断点: 2,高版本(比如vs2015)的vs支持javascript中使用F12转 ...