一直以来,在多地多中心的消息发送场景下,如何保障数据的完整性和一致性是一个技术难点。在 RocketMQ 4.5 版本之前,RocketMQ 只有 Master/Slave 一种部署方式,一组 broker 中有一个 Master ,有零到多个
为白云等地区用户提供了全套网页设计制作服务,及白云网站建设行业解决方案。主营业务为网站制作、成都网站建设、白云网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
Slave,Slave 通过同步复制或异步复制的方式去同步 Master 数据。Master/Slave 部署模式,提供了一定的高可用性。
但这样的部署模式,有一定缺陷。比如故障转移方面,如果主节点挂了,还需要人为手动进行重启或者切换,无法自动将一个从节点转换为主节点。那么什么样的多副本架构可以来解决这个问题呢?首先我们来看看多副本技术的演进。
多副本最早的是 Master/Slave 架构,即简单地用 Slave 去同步 Master 的数据,RocketMQ 最早也是这种实现。分为同步模式(Sync Mode)和异步模式(Async Mode),区别就是 Master 是否等数据同步到 Slave 之后再返回 Client。这两种方式目前在 RocketMQ 社区广泛使用的版本中都有支持,也可以看我前面分享的文章。
随着分布式领域开启了快速发展。在 Hadoop 生态中,诞生了一个基于 Paxos 算法选举 Leader 的分布式协调服务 ZooKeeper。
由于 ZooKeeper 本身拥有高可用和高可靠的特性,随之诞生了很多基于 ZooKeeper 的高可用高可靠的系统。
具体做法如下图所示:
Based on Zookeeper/Etcd
如图所示,假如系统里有 3 个节点,通过 ZooKeeper 提供的一些接口,可以从 3 个节点中自动的选出一个 Master 来。选出一个 Master 后,另外两个没成功的就自然变成 Slave。选完之后,后续过程与传统实现方式中的复制一样。故基于 ZooKeeper 的系统与基于 Master/Slave 系统最大的区别就是:选 Master 的过程由手动选举变成依赖一个第三方的服务(比如 ZooKeeper 或 Etcd)的选举。
但是基于 ZooKeeper 的服务也带来一个比较严重的问题:依赖加重。因为运维 ZooKeeper 是一件很复杂的事情。
因为 ZooKeeper 的复杂性,又有了以下 Raft 的方式。Raft 可以认为是 Paxos 的简化版。基于 Raft 的方式如下图 4 所示,与上述两种方式最大的区别是:leader 的选举是由自己完成的。比如一个系统有 3 个节点,这 3 个节点的 leader 是利用 Raft 的算法通过协调选举自己去完成的,选举完成之后,Master 到 Slave 同步的过程仍然与传统方式类似。最大的好处就是去除了依赖,即本身变得很简单,可以自己完成自己的协调
Master/Slave,Based on ZooKeeper/Etcd 和 Raft,这三种是目前分布式系统中,做到高可靠和高可用的基本的实现方法,各有优劣。
优点:实现简单
缺点:不能自动控制节点切换,一旦出了问题,需要人为介入。
优点:可以自动切换节点
缺点:运维成本很高,因为 ZooKeeper 本身就很难运维。
优点:可以自己协调,并且去除依赖。
缺点:实现 Raft,在编码上比较困难。
多副本架构首先需要解决自动故障转移的问题,本质上来说是自动选主的问题。这个问题的解决方案基本可以分为两种:
目前很多中间件都使用了raft 协议或使用了变种的raft协议,如mongodb .还有新版的kafka,放弃了zookeeper,
将元数据存储在 Kafka 本身,而不是存储 ZooKeeper 这样的外部系统中。新版kafka的Quorum 控制器使用新的 KRaft 协议来确保元数据在仲裁中被精确地复制。这个协议在很多方面与 ZooKeeper 的 ZAB 协议和 Raft 相似。
RocketMQ也选择用 raft 协议来解决这个问题。
我们知道在分布式领域,始终都要面临的一个挑战就是:数据一致性.
Paxos。如今它是业界公认此类问题的最有效解。虽然Paxos在理论界得到了高度认可,但是却给工程界带来了难题。因为这个算法本身比较晦涩,并且抽象,缺少很多实现细节。这让许多工程师大为头疼
Raft是为解决Paxos难以理解和实现的问题而提出的。
Raft在 保序性、共识性、持久性都能很好的支持这就能证明:
在假定领导永不宕机的前提下,Raft是能够保证集群数据一致性的。
Leader在非正常运行情况下,推选出的新Leader至少拥有所有已提交的日志,从而保证数据一致性。
因为Raft规定:一切写入操作必须由Leader管控,所以选主这段时间客户端的写入会被告知失败或者进行不断重试。这里其实一定程度上牺牲了集群的可用性来保证一致性。然而就像CAP定理告诉我们的,分布式系统不能既保证一致性C,又保证可用性A。而Raft集群选择了 C和 P,也就一定程度失去了A。
所以,Raft算法能保证集群的数据一致性。
DLedger 就是一个基于 raft 协议的 commitlog 存储库,
Dledger 作为一个轻量级的 Java Library,它的作用就是将 Raft 有关于算法方面的内容全部抽象掉,开发人员只需要关心业务即可也是 RocketMQ 实现新的高可用多副本架构的关键。
如上图所示,Dledger 只做一件事情,就是 CommitLog。Etcd 虽然也实现了 Raft 协议,但它是自己封装的一个服务,对外提供的接口全是跟它自己的业务相关的。在这种对 Raft 的抽象中,可以简单理解为有一个 StateMachine 和 CommitLog。CommitLog 是具体的写入日志、操作记录,StateMachine 是根据这些操作记录构建出来的系统的状态。在这样抽象之后,Etcd 对外提供的是自己的 StateMachine 的一些服务。Dledger 的定位就是把上一层的 StateMachine 给去除,只留下 CommitLog。这样的话,系统就只需要实现一件事:就是把操作日志变得高可用和高可靠。
从前面介绍的多副本技术的演进可以知道,我们要做的主要有两件事:选举和复制,对应到上面的架构图中,也就是两个核心类:DLedgerLeaderElector 和 DLedgerStore,选举和文件存储。选出 leader 后,再由 leader 去接收数据的写入,同时同步到其他的 follower,这样就完成了整个 Raft 的写入过程。
Raft 协议复制过程可以分为四步,先是发送消息给 leader,leader 除了本地存储之外,会把消息复制给 follower,然后等待follower 确认,如果得到多数节点确认,该消息就可以被提交,并向客户端返回发送成功的确认。
DLedger对于复制过程有以下优化:
通过以上3点,优化这一复制过程。
在可靠性方面DLedger也对网络分区做了优化,而且也对DLedger 做了可靠性测试:
DLedger对网络分区的优化
如果出现上图的网络分区,n2与集群中的其他节点发生了网络隔离,按照 raft 论文实现,n2会一直请求投票,但得不到多数的投票,term 一直增大。一旦网络恢复后,n2就会去打断正在正常复制的n1和n3,进行重新选举。为了解决这种情况,DLedger 的实现改进了 raft 协议,请求投票过程分成了多个阶段,其中有两个重要阶段:WAIT_TO_REVOTE和WAIT_TO_VOTE_NEXT。WAIT_TO_REVOTE是初始状态,这个状态请求投票时不会增加 term,WAIT_TO_VOTE_NEXT则会在下一轮请求投票开始前增加 term。对于图中n2情况,当有效的投票数量没有达到多数量时。可以将节点状态设置WAIT_TO_REVOTE,term 就不会增加。通过这个方法,提高了Dledger对网络分区的容忍性。
DLedger 可靠性测试
官方不仅测试对称网络分区故障,还测试了其他故障下 Dledger 表现情况,包括随机杀死节点,随机暂停一些节点的进程模拟慢节点的状况,以及 bridge、partition-majorities-ring 等复杂的非对称网络分区。在这些故障下,DLedger 都保证了一致性,验证了 DLedger 有很好可靠性。
RocketMQ 4.5 版本发布后,可以采用 RocketMQ on DLedger 方式进行部署。DLedger commitlog 代替了原来的 commitlog,使得 commitlog 拥有了选举复制能力,然后通过角色透传的方式,raft 角色透传给外部 broker 角色,leader 对应原来的 master,follower 和 candidate 对应原来的 slave。
因此 RocketMQ 的 broker 拥有了自动故障转移的能力。在一组 broker 中, Master 挂了以后,依靠 DLedger 自动选主能力,会重新选出 leader,然后通过角色透传变成新的 Master。
DLedger 还可以构建高可用的嵌入式 KV 存储。
我们没有一个嵌入式且高可用的解决方案。RocksDB 可以直接用,但是它本身不支持高可用。(Rocks DB 是Facebook开源的单机版数据库)
有了 DLedger 之后,我们把对一些数据的操作记录到 DLedger 中,然后根据数据量或者实际需求,恢复到hashmap 或者 rocksdb 中,从而构建一致的、高可用的 KV 存储系统,应用到元信息管理等场景。
参考:
https://developer.aliyun.com/article/713017
https://blog.csdn.net/csdn_lhs/article/details/108029978
网页题目:高可用的升级-RocketMQ知识体系7
当前链接:http://www.mswzjz.cn/qtweb/news10/31110.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能