深入了解MongoDB 分布式集群


当前第2页 返回上一页

节点间通过“心跳”进行沟通,以此知道彼此的状态。当主节点异常不可用时,从其他有被投票权的节点中投票选出一个升级为主节点,继续保持服务高可用。这里投票采取“大多数”原则,即需要多于总节点数一半的节点同意,才能被选举成主节点。也因此不建议采用偶数个节点组成副本集,因为偶数情况下,如果发生半数节点网络隔离,隔离的半数节点达不到“大多数”的要求,无法选举产生新的主节点。

通过 rs.status() 可以查看副本集,参考《教你快速搭建 mongodb 集群》

分片集

分片就是将全部数据根据一定规则划分成没有交集的数据子集,每个子集就是一个分片,不同分片存放在不同节点上。这里有几个问题:

  • 划分规则也就是分片策略是什么?
  • 分片数据是如何存放的?
  • 数据量越来越大,分片如何动态调整?

数据块 Chunk

chunk 由多个文档组成,一个分片中包含多个 chunk。chunk 是分片间数据迁移的最小单位。实际上,文档是通过分片策略计算出应该存储在哪个 chunk,而 chunk 存放在分片上。

如图,假设按照文档的 x 字段值来进行分片,根据不同取值范围存放在不同的数据块,如25-175在 chunk 3上。

把书比作 mongodb 中的文档,书柜比作数据块,房间比作分片。每本书根据一定规则放到某书柜上,房间中有很多书柜。当某个房间的书柜太多,就需要以书柜为单位,迁移到相对比较宽松的房间。

chunk 的大小默认为 64MB,也可以自定义。chunk 的存在有两个意义:

  • 当某个 chunk 超过大小时,会触发 chunk 分裂。
  • 当分片间的 chunk 数不均衡时,会触发 chunk 迁移。

chunk 迁移由 mongodb 的平衡器来操作,默认平衡器是开启的,是运行在后台的一个进程,也可以手动关闭。

可以通过下面命令来查看平衡器状态:

sh.getBalancerState()

chunk 的大小对集群的影响:

  • 比较小时,chunk 数比较多,数据分布比较均匀,但会引起频繁的数据块分裂与迁移;
  • 比较大时,chunk 数比较少,数据容易分散不均匀,迁移时网络传输量大。

所以要自定义数据块大小时,一定要考虑完备,否则将大大影响集群与应用程序的性能。

片键 Shard Key

mongodb 集群不会自动将数据进行分片,需要客户端告知 mongodb 哪些数据需要进行分片,分片的规则是什么。

某个数据库启用分片:

mongos> sh.enableSharding(<database>)

设置集合的分片规则:

mongos> sh.shardCollection(<database.collection>,<key>,<unique>,<options>)
# unique 与 options 为可选参数

例如,将数据库 mustone 开启分片,并设置库中 myuser 集合的文档根据 _id 字段的散列值来进行划分分片。

sh.enableSharding("mustone")
sh.shardCollection("mustone.myuser",{_id: "hashed"})

这里划分规则体现在 上, 定义了分片策略,分片策略由片键 Shard Key 与分片算法组成。片键就是文档的某一个字段,也可以是复合字段。分片算法分为两种:

  • 基于范围。如 设置为 id:1 表示基于字段 id 的升序进行分片,id:-1 表示基于字段 id 的倒序进行分片,字段 id 就是 shard key(片键)。当集合中文档为空时,设置分片后,会初始化单个 chunk,chunk 的范围为(-∞,+∞)。当不断往其中插入数据到达 chunk 大小上限后,会进行 chunk 分裂与必要迁移。
  • 基于hash。如上面的栗子, 设置为 _id:”hashed”,表示根据字段 _id 的哈希来分片,此时片键为 _id。初始化时会根据分片节点数初始化若干个 chunk,如3个分片节点会初始化6个 chunk,每个 shard 2个 chunk。

每个数据库会分配一个 primary shard,初始化的 chunk 或者没有开启分片的集合都默认放在这个 primary shard 上。

分片策略的选择至关重要,等数据量大了再更改分片策略将会很麻烦。分片策略的原则:

  1. 均匀分布原则。分片的目标就是让数据在各个分片上均匀分布,数据的存取压力也分解到各个分片上。比如以自增长的 id 升序为片键,会导致新数据永远都写在最后的 chunk 上,且 chunk 分裂与迁移也会落在该 chunk 所在分片上,造成该分片压力过大。
  2. 大基数原则。集合的片键可能包含的不同值的个数,称为基数。基数越大,数据就能划分得更细。基数越小,chunk 的个数就有限。比如性别,只有男女,如果作为片键,最多两个 chunk,等数据越来越大后,便无法横向扩展。
  3. 就近原则。尽可能让一次查询的数据分布在同一个 chunk 上,这样提升磁盘读取性能。避免毫无意义的随机片键,虽然分布均匀了,但每次查询都要跨多个 chunk 才能完成,效率低下。

需要说明的是,mongodb 分片集群虽然比较完备,但是存在一些限制,如备份相对困难,分片集合无法做关联查询等。所以要根据实际业务来评估,如果副本集已经够用了,不一定要进行分片存取。

以上就是深入了解MongoDB 分布式集群的详细内容,更多关于MongoDB 分布式集群的资料请关注其它相关文章!


打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...