MongoDB 5.0.16/6.3.0开始支持多线程数据均衡。这次我们说的是真多线程,不是以前那种源和目标不同的时候才能并行的伪多线程。
回顾
正文开始前,让我水一点字数,我们先回顾一下均衡器的前世今生。
- 2.0开始,MongoDB引入的分片机制,均衡器伴随着分片诞生了。此时的均衡器在全局上同一时间只允许一个chunk被迁移;
- 2.2开始对均衡器做了一些调整,支持
secondaryThrottle
参数:- 取值为false时(默认),在迁移文档时使用
{w: 1}
(实际上是不安全的); - 取值为true时,在迁移文档时使用
{w: 2}
;
- 取值为false时(默认),在迁移文档时使用
- 2.4开始将
secondaryThrottle
的默认值设置为true
,提高了迁移时的数据持久化程度。但显然,这样会进一步降低均衡的性能; - 3.2开始,为了提升均衡器性能,实现了一个伪多线程均衡方案,即在源和目标都不同时,允许迁移并行完成,大大提升了均衡效率;
- 4.2开始,又对每个均衡线程的均衡速度下手了。因为在早期MongoDB内部实现的一些瑕疵,在迁移的一些阶段均衡器无法掌握准确的时机来完成任务。怎么办呢,在均衡线程中遇到有问题的地方
sleep
足够的时间,保证竞争条件下任务能够按照正确的顺序完成。然而这些问题在引入WT引擎后被逐一解决了,所以大量不必要的等待时间被移除,单一线程中的均衡速度最高提升达到40%。
再接下来就是我们今天要说的真多线程均衡。
多线程均衡器
真多线程均衡并没有想象中那么简单,不是简单一开多线程就能解决的问题。稍加思考不难发现,至少在以下问题上多线程迁移都会面临挑战:
- 迁移过程中的数据一致性;
- 迁移与迁移之间的竞争;
- 如何选择源和目标; 这也是为什么时至今日才实现的原因。 在新版本中,将支持一个新参数chunkMigrationConcurrency来调整迁移的并行程度。这个参数可以添加在配置文件中,参考setParameter。也可以在线修改:
db.adminCommand( { setParameter: 1, chunkMigrationConcurrency: 5 } )
- 默认值1,表示不并行;
- 最大支持500;
- 推荐值:非SSD硬盘小于32,通常可以设置为CPU数量的一半;SSD可以视情况调整到更高;
注意事项
如前所述,这并不只是一个多线程的问题。迁移是一个很重的任务,它在同时做几件事情:
- 从源分片中读取大量文档;
- 在目标分片中写入大量文档;
- 迁移完成后从源分片中删除已经迁移的文档;
这些都会对机器资源,特别是I/O资源造成不可忽视的压力。所以调整时一定是从小到大逐步提升,确保系统能够承受,再视情况调整到更大值。
典型使用场景
添加新分片时
在以往的场景中,我们常常建议用户成倍增加分片,因为这样我们可以保证伪多线程均衡以最高效的方式开展。但是现在,即使只加了一个分片,我们也可以大大提升数据向新分片的迁移速度;
需要紧急调整均衡时
以往我们遇到过这样的场景,用户的分片集已经严重不均衡,影响到了正常使用。不均衡可能由于以下原因导致:
- 片键选择不当;
- 原来未分片的表增长到一定大小,开启了分片;
- 某些原因导致均衡器长时间没有工作;
在这些情况下,用户往往愿意花一定的维护时间,停止外部压力来让数据快速均衡以解决问题。但是在以前的版本中我们无法让均衡发生得更快,即使在没有外界其他压力的情况下也是如此。新版本中,则可以使用更多的线程在更短的时间内进一步压榨机器性能,以最快的速度完成均衡。
其他需要快速均衡的所有场景
(废话)
总结
在你需要快速均衡的时候,在系统硬件能够承受的前提下,使用多线程均衡来加速均衡的完成吧!
评论前必须登录!
注册