MongoDB 分片集群机制及原理


MongoDB 常见部署架构

MongoDB 有三种常见的部署架构:

  • 单机版:只有一个单节点,一般用来做开发和测试
  • 复制集:绝大部分 MongoDB 实例上线的时候都使用复制集、高可用模式,1主2从(或更多从节点),至少是三个节点的架构
  • 分片集群:节点数明显增多,一般有 9 个实例

绝大部分使用场景是复制集

为什么要使用分片集群?

  • 数据容量日益增大,访问性能日渐降低,怎么办?
  • 新品上线异常火爆,如何支撑更多的并发用户?
  • 单库已有 10TB 数据,恢复需要1-2天,如何加速?
  • 地理分布数据,你的数据需要服务全球用户

分片如何解决?

假设现在交易表中已经有 10 亿条数据,刚开始放到一个 mongod 实例表中,发现读写很慢。

  • 把数据分成两半,放到2个库物理里

    把交易号 0 ~ 500000000 的交易数据放到第一台 mongodb 机器中中,500000000 ~ 1000000000 的交易号数据放到第二台 mongodb 实例中。

  • 把数据分成4部分,放到4个物理库里

  • 完整的分片集群

以上是一个完整的 4 分片的 mongodb 集群,有 PrimarySecondary 数据节点,有 mongos 路由节点,有 config 配置节点,有应用程序和驱动程序。

分片集群解剖

路由节点 mongos

mongs 作用:

  • 为应用程序提供一个集群单一入口,一般情况下只使用一个 mongos,其它的 mongos 作为高可用存在
  • 你的数据可能存在多个分片(shard)上,mongos 能够转发你的请求到相应的分片服务器上,并且把结果进行合并再返回给应用端
  • mongs 至少有两个,目的是做高可用,更多的 mongos 可以做 Load Balance 的效果

配置节点 config

配置节点就是一个标准的普通的 mongodb 实例产生而来,它就是一个普通的复制集(3个节点),3个节点的目的是提供高可用,在 mongodb 集群中是没有单点故障的,所有的地方都是高可用的。

3个配置节点存储的数据是相同的,它存储的数据是集群中的元数据,配置节点中最重要的一张表就是 Shard表,它存储了 key 的范围和 Shard 的映射关系,即一段数值的文档是存在哪一个分片上,比如编号是 0 ~ 1000 的文档存在 Shard0 上。

LowerUppwerShard
01000Shard0
10012000Shard1

数据节点 mongod

数据节点包含 PrimarySecondary,以复制集为单位(一个分片一个复制集),最大 1024 个分片。

分片中的数据是不重复的,比如有 4 个分片,那么每个分片就占了25%的数据,少了任意一个分片就少了 25 %的数据,所有分片在一起才可完整工作。

分片集群特点

  • 应用全透明,无特殊处理:单复制集的应用程序代码可以无缝升级到分片集群,代码无需更改
  • 数据自动均衡:数据在分片之间是自动均衡的,mongodb 会在背后自动检测各个分片的数据情况,如果发现不均衡的话会自动把数据从一个分片迁移到另一个分片
  • 动态扩容,无须下线:可以先使用一个复制集,在需要的时候在线上无需下线的情况下,把新的节点加到集群中,实现线上动态扩容的机制
  • 提供三种分片方式

分片集群数据分布方式

基于范围

基于范围是最常见的方式,就是选择一个或几个组合字段,把字段的值划分为一个范围空间,然后进行分块,分成 Chunk1、Chunk2、Chunk3,Chunk4等,这个 Chunk 是一个逻辑的分块。

Pros(优点)Cons(缺点)
片键范围查询性能好数据分布可能不均匀
优化读容易有热点,比如用自增ID值划分Chunk,那么新进来的数据都会写到同一个分片上

基于 Hash

hash 是按某个字段值进行 hash,这样写入的时候就可以把文档写到不同的分块上。

Pros(优点)Cons(缺点)
数据分布均匀,写优化范围查询效率低

基于 zone / tag

通过给分片打标签的方式,可以把地域化的数据组织到当地的分片上。

总结

  • 分片集群可以有效解决性能瓶颈及系统扩容问题
  • 分片额外消耗较多,成本高,管理复杂,能不分片尽量不要分片

参考


文章作者: 张权
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张权 !
评论
  目录