MongoDB多个复制集到分片集群的数据同步
目录
背景
某服务升级,计划将原来多个v2.4复制集升级为v3.0分片集群。
问题
在多个rs的增量同步过程中,发现分片集群的机器负载很高,在服务高峰时期,oplog追的慢,同步开始滞后,延迟时间有上升趋势。
整个同步过程包含两个阶段:
-
初始同步
- 目标是全部集合
- insert 10w/s,大小取决于目标分片集群的性能
-
增量同步
- 目标是oplog
- update 3w/s,大小取决于全部源端rs的update
分析
机器负载高,完全不符合预期,问题出在哪里?为什么初始同步没问题,增量同步会出现性能瓶颈?
从两个方面考虑:
-
增量同步的特殊性
复制集中,
_id
保证文档的唯一性,所有对于该文档的update/delete操作,体现在oplog,均是以_id
作为条件。 -
分片集群
同步目标是分片集群,集合做了分片,片键(shard key)是什么?对于update/remove操作的oplog,如果片键是
_id
,oplog回放可以利用片键;如果片键不是_id
,那么oplog回放无法利用片键。
回到问题本身,目标集合的片键非_id
,对于一个update/remove操作的oplog,其回放不能直接定位到目标shard,那么该oplog将在所有shard上都执行一次,尽管这条操作仅在目标shard(包含_id指定的文档)上执行成功,但是在其他shard上会执行一次query,这里发生了不必要的性能消耗。
至于为什么insert不会有瓶颈,因为insert操作中包含文档的所有field,自然能够利用片键:)
解决方法
一般情况下,片键不会是_id
,如果源端rs的update/remove的OPS高,可考虑分批导入到分片集群,比如新集群计划容纳10个rs,可以先导入5个rs,等业务切换完成,再导入其余5个rs。