分片间的数据块迁移¶
分片间数据块的迁移是 均衡器 过程的一部分.
数据块迁移¶
为了维持 sharded cluster 中的数据均衡,MongoDB在分片间迁移数据,迁移可以是以下两种情况:
手工进行.只有在极少数情况下才需要手动迁移数据块,比如在批量写入时进行数据分发.参见 手动迁移数据块 获得更多细节.
所有的数据迁移都包含以下过程:
均衡器将 moveChunk 命令发送到源分片上.
源分片使用内部命令 moveChunk 开始迁移数据过程,在迁移过程中,对迁移数据块的请求都被分发到源分片.
目标分片开始向源分片请求要迁移的数据块的数据,接收并保存.
在所有文档都接收完成后,目标分片开始同步过程,以保证迁移期间对迁移数据块的所有更改都可以同步过来.
当同步结束之后,目标分片通知 config database 并使用数据块的新位置更新集群的元信息.
在目标分片更新完成元信息之后,一旦源分片的数据块中没有打开的游标,源分片会删除这部分重复的数据.
在 2.4 版更改: 如果源分片需要继续进行数据迁移,迁移过程可以立刻开始,而不需要等待删除数据完成,参见 数据块迁移排队.
数据迁移可以保证一致性,并且尽力保证数据块在迁移过程中的可用性.
数据块迁移排队¶
在 2.4 版更改.
如果需要从一个分片迁移多个数据块到其他分片,每次只能迁移一个.不过,下一次迁移会在上一次迁移开始删除数据时就开始.参见 数据块迁移 获得更多数据块迁移和删除阶段的信息.
数据块迁移排队的行为可以在发生严重数据不均衡的情况下,分片更快的进行数据迁移,比如在一开始写入数据且集群没有进行预分配数据块时,或者新增一个分片时.
这种行为也同样影响 moveChunk 命令,这个命令也会因此变得更快.
在某些情况下,删除数据阶段会持续很久.如果多个删除数据任务在排队但是没有完成,分片中复制集主节点的异常关闭会导致孤儿文档的产生.
数据块迁移与复制集¶
默认情况下,每条被迁移的文档都必须被同步打牌至少一个从节点上之后,下一条文档才能开始迁移.
将 _secondaryThrottle 参数设置为false可以改变这种行为,使迁移不用等待数据同步到从节点便可以继续进行.参见 改变数据块迁移时的复制集行为(Secondary Throttle) 获取如何更新 _secondaryThrottle 的信息.
与 secondaryThrottle 设置无关,迁移中的一些阶段遵循一下的复制集策略:
在更新配置服务器的集群元信息时,MongoDB会短暂地暂停掉源分片的所有写入,更新完成之后恢复.在将数据块迁移提交到配置服务器之前与之后,都需要确保所有写入被复制集的大多数节点所同步.
当迁移即将结束并进去数据清理阶段时,所有的写入都必须同步到复制集的大多数节点之后,之后的数据清理(来自其他的数据迁移)或者新的迁移才可以进行.
在 2.4 版更改: 在之前的版本里,均衡器并不会等待数据在复制集中被同步到从节点,参见 Secondary Throttle in the v2.2 Manual 以获得更多信息.