(三) MdbCluster分布式内存数据库——节点状态变化及分片调整
(三) MdbCluster分布式内存数据库——节点状态变化及分片调整
上一篇: (二) MdbCluster分布式内存数据库——分布式架构
昨天我们在测试节点动态扩缩容时,发现了一个小bug。开始时我想当然“头疼医头,脚疼医脚”地安排开发在问题发生的地方修掉这个bug。早上刚好要一起开会,顺便讨论起这个bug。我们在白板画出了系统的架构图,从bug的发生点,一个环节一个环节的往上追溯原因。意外的发现bug的源头离bug发生的地方已经过5,6个环节了。如果没有这个会,开发修bug的时候可能会从最下面开始一个环节一个环节向上修,也许一个星期后才会发现最终的问题。
这里想分享的两点:
1. 当一个系统变得庞大,已超过一个人维护能力,并且有一组人不断在为这个系统贡献新代码时。一旦发现程序运行不如预期,一定有很多的方式来修复这个bug。但能找到bug的根源,在离bug最近的地方,用最少的代码进行修复,体现了一个程序员对这个系统的驾驭能力。这样做最大也最直接的好处是可以减少修复旧bug时引入新bug,并避免大规模的回归测试。
2. 调试程序不一定要通过debug工具或者加调试日志的办法。如果有幸这个系统是自己写的,通过bug的现象,回忆自己写过的代码或设计方案,可以更快的分析定位出问题的根本原因。我自己经常用这个办法,并且屡试不爽。之前总流传一个好的程序员和一个差的程序员效率可以差10倍,现实中我也经常看到这种情况,应该这也是其中的原因之一吧。
我想这就是《人月神话》里面说的: “程序员,就像诗人一样,几乎仅仅工作在单纯的思考中。程序员凭空地运用自己的想象,来建造自己的城堡。”
我们接着讨论上节列出的问题:
三、当某个节点状态和数量发生变化时,其它节点如何感知?
考虑到节点主备切换、扩缩容时,节点的状态,分区(slot)数据的状态变化很多。我们增加了一个MdbRedux进程,专门用于通知各种状态的变化,以及节点的状态查询。节点内的MdbRedux与集群的每个MdbAgent都有通讯链路,可以保证状态变更通知的广播。可能有人会问,节点间链路是怎么发现和建立的?我们的系统是基于博客前面文章提到的《c++分布式应用框架》开发的。链路是可以自动发现和建立的。
举个主备切换的例子。当MDB1节点发生异常时,备节点 MDB2的MdbRWNode感知到异常,通知MdbAgent,MdbAgent更新自己的状态,并通知MdbRedux对其它节点的MdbAgent进行状态更新广播。从而达到每个节点的状态一致。最后,MdbAgent会通过serverpush,将状态变更推送给MdbClient。
四、扩容和缩容时,分片是如何调整的?
扩缩容的时候分为两步,一是根据扩缩容的情况生成执行计划。二是根据生成的执行计划,迁移数据。
这边举一个最简单的由2个节点扩容为3个节点的场景。生成执行计划的算法的目的也很简单:通过尽量少的迁移来使每个节点承担的数据尽量平均。例子里面的算法从Node1迁移[5461, 8190]到Node3,从Node2迁移[13653,16383]到Node3。从而使3个节点的slot数大概为5461。这个算法避免了从Node1到Node2的数据迁移。
同理由2个点节扩容为4个节点时,仅发生Node1到Node3和Node2到Node4的迁移。此时还附带了另一个好处,这样的迁移是可以并行执行的。
可见,随着扩缩容的次数和节点个数不同,每个分片里面的slot会被切得不连续,片段会很多。当然这在系统里面是没有问题的。因为每个slot都是单独管理的。但算法为了维护时候简单一些,每次做扩缩容生成执行计划的时候,都会尽量去考虑合并相临的slot,如果某个slot单独落在某个节点,也会进行调整。以最大程度保证分片数据的清晰简洁。
关于数据迁移的部分,我们后面单独列章节来讲。
相关文章
- JVM初探(一):jvm内存结构[通俗易懂]
- JMM内存模型
- 世界上最快的内存数据库横空出世,比 Redis 快 25 倍,Star 数飙升,杀疯了!
- C语言内存讲解-详说内存分布和heap空间
- Linux下内存问题排查利器
- JVM堆内存导致的FGC问题排查
- 内存数据库 mysql-mysql in memory_In-Memory:内存数据库
- 【C数据存储】整型在内存中的存储(进阶版)
- Linux 内存中的缓冲区(Buffer)与缓存(Cache)
- 【Linux 内核 内存管理】memblock 分配器 ③ ( memblock_region 内存块区域 | memblock_region 结构体成员分析 | memblock 分配器标志位 )
- SQLServer 错误 41349 警告:为包含具有持续性 SCHEMA_AND_DATA 的一个或多个内存优化表的数据库启用了加密。 不会对这些内存优化表中的数据加密。 故障 处理 修复 支持远程
- Redis:使用内存数据库解决问题(redis内存数据库)
- 使用 Redis 提升数据库性能(redis内存数据库)
- 快速存储:Redis 内存数据库(redis内存数据库)
- Redis:加速系统性能的内存数据库(redis内存数据库)
- 如何使用 Redis 内存快照功能,保障数据的安全与备份?(redis内存快照)
- MySQL优化:构建高性能内存数据库(mysql内存数据库)
- 优化MySQL内存数据库性能(mysql内存库)
- 优化MySQL数据库内存优化技巧(mysql数据库内存)
- Redis内存分配的实现及其优化策略(redis内存分配)
- Linux内存占用排序:了解系统资源使用情况(linux内存占用排序)
- Linux Alloca:快速内存管理的新希望(linuxalloca)
- Linux内存:最低8G开启无限可能(linux 内存多少g)
- 内存如何查看Redis内存占用情况(怎么查看redis)
- 1G内存足以运行MySQL数据库(1g 内存 mysql)
- 深入浅出 Redis全面了解这一全内存数据库系统(全面了解redis)
- Redis从性能冲突到内存转义(redis 转义)
- Oracle 10 的内存调整实践(oracle10内存调整)