MdbCluster分布式内存数据库(节点) | 青训营笔记

42 阅读4分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 11 天

  1. 当一个系统变得庞大,已超过一个人维护能力,并且有一组人不断在为这个系统贡献新代码时。一旦发现程序运行不如预期,一定有很多的方式来修复这个bug。但能找到bug的根源,在离bug最近的地方,用最少的代码进行修复,体现了一个程序员对这个系统的驾驭能力。这样做最大也最直接的好处是可以减少修复旧bug时引入新bug,并避免大规模的回归测试。

  2. 调试程序不一定要通过debug工具或者加调试日志的办法。如果有幸这个系统是自己写的,通过bug的现象,回忆自己写过的代码或设计方案,可以更快的分析定位出问题的根本原因。我自己经常用这个办法,并且屡试不爽。之前总流传一个好的程序员和一个差的程序员效率可以差10倍,现实中我也经常看到这种情况,应该这也是其中的原因之一吧。   我想这就是《人月神话》里面说的: “程序员,就像诗人一样,几乎仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的城堡。”     我们接着讨论上节列出的问题:  

  3. 当某个节点状态和数量发生变化时,其它节点如何感知? 考虑到节点主备切换、扩缩容时,节点的状态,分区(slot)数据的状态变化很多。我们增加了一个MdbRedux进程,专门用于通知各种状态的变化,以及节点的状态查询。节点内的MdbRedux与集群的每个MdbAgent都有通讯链路,可以保证状态变更通知的广播。可能有人会问,节点间链路是怎么发现和建立的?我们的系统是基于博客前面文章提到的《c++分布式应用框架》开发的。链路是可以自动发现和建立的。

image.png

举个主备切换的例子。当MDB1节点发生异常时,备节点 MDB2的MdbRWNode感知到异常,通知MdbAgent,MdbAgent更新自己的状态,并通知MdbRedux对其它节点的MdbAgent进行状态更新广播。从而达到每个节点的状态一致。最后,MdbAgent会通过serverpush,将状态变更推送给MdbClient。

  1. 扩容和缩容时,分片是如何调整的?

扩缩容的时候分为两步,一是根据扩缩容的情况生成执行计划。二是根据生成的执行计划,迁移数据。

image.png

这边举一个最简单的由2个节点扩容为3个节点的场景。生成执行计划的算法的目的也很简单:通过尽量少的迁移来使每个节点承担的数据尽量平均。例子里面的算法从Node1迁移[5461, 8190]到Node3,从Node2迁移[13653,16383]到Node3。从而使3个节点的slot数大概为5461。这个算法避免了从Node1到Node2的数据迁移。

同理由2个点节扩容为4个节点时,仅发生Node1到Node3和Node2到Node4的迁移。此时还附带了另一个好处,这样的迁移是可以并行执行的。

image.png

  可见,随着扩缩容的次数和节点个数不同,每个分片里面的slot会被切得不连续,片段会很多。当然这在系统里面是没有问题的。因为每个slot都是单独管理的。但算法为了维护时候简单一些,每次做扩缩容生成执行计划的时候,都会尽量去考虑合并相临的slot,如果某个slot单独落在某个节点,也会进行调整。以最大程度保证分片数据的清晰简洁。

  关于数据迁移的部分,我们后面单独列章节来讲。