MongoDB分片迁移原理与源码(1)

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
日志服务 SLS,月写入数据量 50GB 1个月
简介:

MongoDB分片迁移原理与源码

MongoDB架构

单节点

单个节点的MongoDB实例,具备MongoDB基本的功能和服务能力,不过缺乏数据冗余和高可用,以及横向扩展的能力,一般很少在实际生产环境中使用。

副本集

MongoDB的副本集,是指一组具有相同数据的mongod节点服务的集合。副本集架构可以实现数据冗余以及高可用。
一个基本的副本集架构如下:
副本集

一个副本集下,一主多备因为有用相同的数据,这种复制机制可以减少单节点下数据丢失的风险。

另外,副本集内的节点之间是通过异步复制oplog的方式,来实现节点之间数据的一致的。MongoDB的数据一致性是基于Raft协议改进实现的。

MongoDB复制流程与Raft协议有一些基本的差别,包括:

  1. 选举差异。MongoDB的节点可以设置优先级并设置了多种节点角色,Raft无此概念。MongoDB的副本集的心跳是节点两两互发的,而Raft是主节点发,备节点回复。MongoDB的主节点在不能收到大多数节点的心跳的时候,就会自动降级,防止出现多主和过期主,而Raft的主节点再收到更高任期的主节点心跳的时候才会降级。
  2. 日志复制。MongoDB的日志复制是异步过程,主节点收到写操作时,先在本地应用写,再写一个日志后,其他节点去拉取日志把写操作应用到本地节点,而Raft是写一个日志并复制到大多数节点,然后主节点再将写应用到本地后反馈给用户,之后告知其他节点应用写操作。MongoDB中的日志是备节点去主节点拉取,而Raft是主节点推到备节点。MongoDB通过Write concern帮助用户更好的选项配置数据写到哪些节点后返回给用户,而Raft就是日志复制到大多数节点后返回。

参考:

Raft协议图解

Raft与MongoDB复制集协议比较

分片集群

副本集架构虽然提高了数据安全和系统可用性,但是并不能提高数据的容量和大数据量下的服务读写能力。基于分片集群架构的MongoDB,可以实现数据分布在多个不同节点上实现数据的横向扩展以支持大数据量,而同时可以提高服务的整体读写能力。

一个基本的分片集群架构如下:
分片集群

分片集群架构通过将数据进行拆分,部署到不同的shard节点上,将读写压力进行了分摊,同时在增加分片的情况下,可以进一步提高整体服务的读写负载能力。

另外通过添加shard,可以不断提高整体服务的数据容量,实现数据的水平扩容。

最后分片可以提高服务整体的可用性,及时一个分片一部分数据出现问题,其他分片和数据也可以在一定程序下继续提供服务。

分片迁移

数据块管理

在分片集群下,MongoDB提供了分片键的概念,基于该键去进行数据的分布规则,可以基于hash,可以基于range。

但是不管基于hash还是range都可能导致数据分布不均匀,或者分片集群新增shard节点的时候,都需要对数据进行动态调整,以实现数据在各分片的均衡分布,以平衡各shard的服务。

为了解决分片集群中,集合数据分布不均匀的问题,MongoDB提供了balance功能,该功能可以在后台监测各个shard数据块(chunk)的情况,在满足条件的情况下,会将数据块从一个shard(数据库多)迁移到另外一个shard(数据块少),直到集合的数据块在各shard中分布均匀。

MongoDB是依据分片键来管理数据块,每块数据都是整个数据的一个子集。
基于范围的分片

当用户通过mongos访问MongoDB服务进行数据写入的时候,会根据分片键、分片策略等将数据路由到某一个分片,写入保存,生成一个个数据块。而有数据插入和更新导致数据块超过限制的时候,MongoDB会对数据块进行拆分(split chunk)。

MongoDB中默认的数据块大小是64M,该值可以增大或减少。更小的数据块会产生更频繁的数据迁移,可以实现数据更大程度的均衡;更大的数据块会减少迁移,但是存在数据不均衡的风险。

拆分数据块只发生在插入和更新时;如果调低快大小,有可能导致所有数据块都拆分成新的快;如果调高快大小,已有的数据块必须通过插入或修改的方式达到新的大小。拆分不能是未完成状态。

当数据块因为拆分越来越多后,一定条件下会触发move chunk。这个判断和检测是否需要迁移数据块的进程为balancer。balancer会定期检测不同分片的数据块信息,如果含有最多块的分片的块数比含有最少块的分片的块数超过一定大小,就会认为是不均衡的状态,需要进行迁移。

另外当有shard添加到分片集群中,也会发生不均衡(因为有shard块数为0);当要删除一个shard的时候,也会发生不均衡(因为要重新分配该shard上的数据块)。

块迁移流程

  1. 平衡器进程将move chunk的命令发送到迁移的源shard;
  2. 源shard使用一个内部move chunk命令开始移动。在迁移过程中,对该数据块的操作还路由到源shard,源shard负责对该数据块的写操作的处理;
  3. 目标shard创建所需要的索引;
  4. 目标shard开始请求数据块的文档并接收数据的拷贝;
  5. 再接收完数据块中最后一个文档,目标shard开始同步进程以确保迁移过程中对迁移文档的修改也同步过来了;
  6. 完全同步之后,源shard连接config服务器,使用数据块的新位置更新集群元数据;
  7. 再修改完元数据后,如果源shard上的chunk没有打开的游标了,源shard就会删除这些文档的旧拷贝。

注意:如果balancer需要操作其他块迁移从源shard,那么balancer不用等待这些旧文档删除,就可以立刻进行下一个块迁移操作。因为这些删除操作是异步的。

异步迁移块清理

要从一个分片迁移多个块,平衡器一次迁移一个块。但是,平衡器在开始下一个块迁移之前不会等待当前迁移流程的删除阶段完成。

如果存在大量块需要迁移的时候(比如新shard加入),可以不需要等待上一个chunk的删除,就可以进行下一个chunk迁移,提高整体迁移的速度。

MongoDB提供了一个参数去设置是否异步删除:_waitForDelete。迁移一个 chunk 数据以后,是否同步等待数据删除完毕;默认为 false, 由一个单独的线程异步删除旧数据。

由于块迁移流程的操作不能做到原子性,从在异步流程,如果在上述操作步骤4/5/6/7出现宕机或网络问题等问题导致迁移中断,都可能出现问题,导致数据不一致、孤儿文档等问题,这也是本文章主要关注的点。

未完,待续

参考文档

MongoDB官方文档

孤儿文档是怎样产生的(MongoDB orphaned document)

MongoDB疑难解析:为什么升级之后负载升高了?

由数据迁移至MongoDB导致的数据不一致问题及解决方案

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
23天前
|
存储 缓存 NoSQL
MongoDB内部的存储原理
这篇文章详细介绍了MongoDB的内部存储原理,包括存储引擎WiredTiger的架构、btree与b+tree的比较、cache机制、page结构、写操作流程、checkpoint和WAL日志,以及分布式存储的架构。
34 1
MongoDB内部的存储原理
|
4月前
|
存储 监控 NoSQL
MongoDB索引解析:工作原理、类型选择及优化策略
MongoDB索引解析:工作原理、类型选择及优化策略
|
2天前
|
NoSQL MongoDB 数据库
使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB
使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB
|
18天前
|
存储 监控 NoSQL
*MongoDB的水平扩展主要通过分片技术实
*MongoDB的水平扩展主要通过分片技术实
33 5
|
23天前
|
存储 NoSQL 前端开发
MongoDB 分片总结
这篇文章总结了MongoDB分片的概念、集群结构、分片实例、配置和测试过程。
40 6
|
2月前
|
JSON NoSQL Ubuntu
在Ubuntu 14.04上如何备份、恢复和迁移MongoDB数据库
在Ubuntu 14.04上如何备份、恢复和迁移MongoDB数据库
70 1
|
2月前
|
NoSQL MongoDB 数据库
DTS 的惊天挑战:迁移海量 MongoDB 数据时,捍卫数据准确完整的生死之战!
【8月更文挑战第7天】在数字化时代,大数据量的MongoDB迁移至关重要。DTS(数据传输服务)通过全面的数据评估、可靠的传输机制(如事务保证一致性)、异常处理(如回滚或重试),以及迁移后的数据校验来确保数据准确无损。DTS还处理数据转换与映射,即使面对不同数据库结构也能保持数据完整性,为企业提供可靠的数据迁移解决方案。
48 2
|
3月前
|
存储 NoSQL MongoDB
MongoDB 索引原理与索引优化
MongoDB 索引原理与索引优化
59 1
|
3月前
|
DataWorks NoSQL fastjson
DataWorks操作报错合集之DataX进行MongoDB全量迁移的过程中,DataX的MongoDB Reader插件在初始化阶段找不到Fastjson 2.x版本的类库,该怎么办
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
2月前
|
存储 运维 NoSQL
轻松上手:逐步搭建你的高可用MongoDB集群(分片)
【8月更文挑战第13天】在数据激增的背景下,传统单机数据库难以胜任。MongoDB作为流行NoSQL数据库,采用分片技术实现水平扩展,有效处理海量数据。分片将数据分散存储,提高并发处理能力和容错性,是高可用架构基石。构建MongoDB集群需理解shard、config server和router三组件协同工作原理。通过具体实例演示集群搭建流程,包括各组件的启动及配置,确保数据高可用性和系统稳定性。合理规划与实践可构建高效稳定的MongoDB集群,满足业务需求并支持未来扩展。
66 0