MongoDB sharding迁移那些事(一)

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 如果不了解 MongoDB Sharded Cluster 原理,请先阅读 MongoDB Sharded cluster架构原理 关于MongoDB Sharding,你应该知道的 关于 sharding 迁移,会分3个部分来介绍,本文为第一部分 负载均衡及迁移策略 chunk 迁移
+关注继续查看

如果不了解 MongoDB Sharded Cluster 原理,请先阅读

关于 sharding 迁移,会分3个部分来介绍,本文为第一部分

  1. 负载均衡及迁移策略
  2. chunk 迁移流程
  3. Balancer 运维管理

为什么要进行 chunk 迁移?

MongoDB sharding 主要有3个场景需要进行 chunk 迁移

场景1

当多个 shard 上 chunk 数量分布不均时,MongoDB 会自动的在 shard 间迁移 chunk,尽可能让各个 shard 上 chunk 数量均匀分布,就是大家经常说到的负载均衡。

场景2

用户调用 removeShard 命令后,被移除 shard 上的 chunk 就需要被迁移到其他的 shard 上,等该 shard 上没有数据后,安全下线。(注意: shard 上没有分片的集合,需要手动的 movePrimary 来迁移,系统不会自动的迁移)。

场景3

MongoDB sharding 支持 shard tag功能,可以对 shard、及shard key range 打标签,系统会自动将对应 range 的数据迁移到拥有相同 tag 的 shard 上。例如

mongos> sh.addShardTag("shard-hz", "hangzhou")
mongos> sh.addShardTag("shard-sh", "shanghai")
mongos> sh.addTagRange("shtest.coll", {x: 1}, {x: 1000}, "hangzhou")
mongos> sh.addTagRange("shtest.coll", {x: 2000}, {x: 5000}, "shanghai")

对2个 shard 添加了标签,对某个集合的shard key range 也添加了标签,这样该集合里 x 值为[1, 1000)的文档都会分布到 shard-hz,而 x 值为[2000, 5000)的文档则会分布到 shard-sh 里。

迁移工作谁来做?

3.2版本里,Mongos 有个后台的 Balancer 任务,该任务不断对针对上述3种场景来判断是否需要迁移 chunk,如果需要,则发送 moveChunk 命令到源 shard 上开始迁移,整个迁移过程比较复杂,将在第二部分进行专门的介绍。

除了上述场景会触发自动 chunk 迁移,MongoDB 也提供了 moveChunk 命令,让用户能主动的触发数据迁移。

Balancer 如何工作?

一个 Sharded Cluster 里可能有很多个 mongos,如果所有的 mongos 的 Balancer 同时去触发迁移,整个集群就乱了,为了不出乱子,同一时刻只能让一个 Balancer 去做负载均衡。

Balancer 在开始负载均衡前,会先抢锁,抢到锁的 Balancer 继续干活,没抢到锁的则继续等待,一段时间后再尝试抢锁。

这里的锁实际上是config server里 config.locks集合下的一个特殊文档,Balancer 使用 findAndModify 命令去更新文档的 state 字段(类似set state=1 if state==0的逻辑),更新成功即为抢锁成功。

抢锁成功后,Balancer 就开始遍历所有分片的集合,针对每个集合,执行下述步骤,看是否需要 进行 chunk 迁移。

Step1: 获取集合对应的 chunk 分布信息

获取 shard 的元信息 (draining代表 shard 是否正在被移除)

shard 名 maxSize draining tag host
shard0 100G false tag0 replset0
shard1 100G false tag1 replset1

获取集合的 chunk 分布信息

shard 名 chunk 列表
shard0 chunk(min, -100), chunk(-100, 0)
shard1 chunk(0, 100), chunk(100, max)

获取集合对应的 tag 信息

Range tag
(20, 80) tag0

Step2: 检查是否需要 chunk 分裂

如果集合没有设置 tag range,这个步骤不需要做任何事情。其主要是检查 TagRange 跟 chunk 是否存在存在交叉,如果有,则以 Range.min(Range 的下限)为分割点,对 chunk 进行 split。例如

上述(20, 80)的 Range的 tag 为『tag0』,跟chunk(0, 100)有交叉的部分,于是就会在20这个点进行分裂,分裂为 chunk(0, 20) 以及 chunk(20, 100),接下来就可以将 chunk(20, 100)从 shard1 迁移到 shard0,就能满足 tag 分布规则了,这个步骤只是为迁移做准备工作,具体的迁移在 Step4 中完成。

Step3: 迁移 draining shard 上的chunk

当用户 removeShard 将某个 shard 移除时,MongoDB 会将该 shard 标记为 draining 状态, Blancer 在做迁移时,如果发现某个 shard 处于 draining 状态,就会主动将shard 上的chunk 迁移到其他 shard。 Blancer 会挑选拥有最少 chunk 的 shard 作为迁移目标,构建迁移任务。

Step4: 迁移 tag 不匹配的 chunk

Step2 时,已经将 chunk 根据 tag range 边界进行了 split,这时 Balancer 只需要检查哪些 chunk 所属 shard 的 tag 与自身的不匹配,如果不匹配,则构建迁移任务,将 chunk 迁移到 tag 匹配的 shard 上。

Step5: 负载均衡迁移

Balancer 还会基于各个 shard 持有的 chunk 数量来做负载均衡迁移,如果一个集合在2个 shard 里的 chunk 数量相差超过一定阈值,则会触发迁移。 (通过对比持有 chunk 最多和最少的 shard)

集合的 chunk 数量 迁移阈值
< 20 2
< 80 4
>=80 8

迁移阈值如上表所示,意思是当集合的 chunk 数量小于20时,如果2个 shard 间 chunk 数量相差大于或等于2时,就会构建迁移任务,将某个 chunk 从『持有 chunk 最多的 shard』迁移到『持有 chunk 最少的 shard』。

Step5:执行迁移

根据 Step 3~5 里构建出的迁移任务,开始真正的迁移。

值得注意的是,Step3、Step4里的迁移虽然是必须要做的,为了确保系统功能正常运转,但其仍然是由 Balancer 来控制的,如果关闭了 Balancer,就可能导致 removeShard、shard tag 逻辑无法正常工作,所以关闭 Balancer 一定要慎重,Balancer 的运维管理将在第三部分详细介绍。

参考资料

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
3月前
|
数据采集 NoSQL 容灾
如何实现MongoDB数据的快速迁移?
为解决用户面临的 MongoDB 迁移问题,玖章算术旗下的云原生智能数据管理平台 NineData 推出了 MongoDB 业务不停服数据迁移能力。NineData 实现了完全自动化的全量数据迁移,以及增量数据的采集复制能力。
|
7月前
|
存储 NoSQL Oracle
「数据库选型」卫报从MongoDB迁移到Amazon RDS上的PostgreSQL
「数据库选型」卫报从MongoDB迁移到Amazon RDS上的PostgreSQL
|
7月前
|
存储 JSON NoSQL
「文档数据库迁移」从MongoDB迁移到Apache CouchDB
「文档数据库迁移」从MongoDB迁移到Apache CouchDB
|
存储 新零售 弹性计算
心动《另一个伊甸》从Amazon DynamoDB迁移MongoDB
阿里云MongoDB提供了很好的保障和性能,使我们的业务成本有了明显的下降
心动《另一个伊甸》从Amazon DynamoDB迁移MongoDB
|
存储 NoSQL Oracle
不遂人愿的“乌托邦式”迁移上云 | 独家专访 MongoDB CTO
“借助 MongoDB,你可以很自然地用自己的语言编程,无需再借助极为复杂的 SQL 转换层。我认为,这是过去十年来数据库技术领域规模最大、最重要的一次转变。”
121 0
不遂人愿的“乌托邦式”迁移上云 | 独家专访 MongoDB CTO
|
消息中间件 存储 缓存
从MongoDB迁移到Elasticsearch后,我们减少了80%的服务器
本文介绍“为什么要从MongoDB迁移到Elasticsearch?”以及“如何从MongoDB迁移到Elasticsearch?”。
17920 0
从MongoDB迁移到Elasticsearch后,我们减少了80%的服务器
相关产品
云数据库 MongoDB 版
推荐文章
更多