简单的网站更新 关键词优化 关键词互联,wordpress 弹出对话框,西安优秀的集团门户网站建设费用,北京蓝杉网站建设公司尊敬的阿里云用户#xff1a; 您好#xff01;为方便您试用开源 RocketMQ 客户端访问阿里云MQ#xff0c;我们申请了专门的优惠券#xff0c;优惠券可以直接抵扣金额。请填写下您公司账号信息#xff0c;点击上图#xff0c;了解更多哦。
一、DLedger引入目的
在 Rocke…
尊敬的阿里云用户 您好为方便您试用开源 RocketMQ 客户端访问阿里云MQ我们申请了专门的优惠券优惠券可以直接抵扣金额。请填写下您公司账号信息点击上图了解更多哦。
一、DLedger引入目的
在 RocketMQ 4.5 版本之前RocketMQ 只有 Master/Slave 一种部署方式一组 broker 中有一个 Master 有零到多个 SlaveSlave 通过同步复制或异步复制的方式去同步 Master 数据。Master/Slave 部署模式提供了一定的高可用性。 但这样的部署模式有一定缺陷。比如故障转移方面如果主节点挂了还需要人为手动进行重启或者切换无法自动将一个从节点转换为主节点。因此我们希望能有一个新的多副本架构去解决这个问题。
新的多副本架构首先需要解决自动故障转移的问题本质上来说是自动选主的问题。这个问题的解决方案基本可以分为两种
利用第三方协调服务集群完成选主比如 zookeeper 或者 etcd。这种方案会引入了重量级外部组件加重部署运维和故障诊断成本比如在维护 RocketMQ 集群还需要维护 zookeeper 集群并且 zookeeper 集群故障会影响到 RocketMQ 集群。利用 raft 协议来完成一个自动选主raft 协议相比前者的优点是不需要引入外部组件自动选主逻辑集成到各个节点的进程中节点之间通过通信就可以完成选主。
因此最后选择用 raft 协议来解决这个问题而 DLedger 就是一个基于 raft 协议的 commitlog 存储库也是 RocketMQ 实现新的高可用多副本架构的关键。
二、DLedger 设计理念
1. DLedger 定位 Raft 协议是复制状态机的实现这种模型应用到消息系统中就会存在问题。对于消息系统来说它本身是一个中间代理commitlog 状态是系统最终状态并不需要状态机再去完成一次状态构建。因此 DLedger 去掉了 raft 协议中状态机的部分但基于raft协议保证commitlog 是一致的并且是高可用的。 另一方面 DLedger 又是一个轻量级的 java library。它对外提供的 API 非常简单append 和 get。Append 向 DLedger 添加数据并且添加的数据会对应一个递增的索引而 get 可以根据索引去获得相应的数据。因此 DLedger 是一个 append only 的日志系统。
2. DLedger 应用场景 DLedger 其中一个应用就是在分布式消息系统中RocketMQ 4.5 版本发布后可以采用 RocketMQ on DLedger 方式进行部署。DLedger commitlog 代替了原来的 commitlog使得 commitlog 拥有了选举复制能力然后通过角色透传的方式raft 角色透传给外部 broker 角色leader 对应原来的 masterfollower 和 candidate 对应原来的 slave。
因此 RocketMQ 的 broker 拥有了自动故障转移的能力。在一组 broker 中 Master 挂了以后依靠 DLedger 自动选主能力会重新选出 leader然后通过角色透传变成新的 Master。 DLedger 还可以构建高可用的嵌入式 KV 存储。我们把对一些数据的操作记录到 DLedger 中然后根据数据量或者实际需求恢复到hashmap 或者 rocksdb 中从而构建一致的、高可用的 KV 存储系统应用到元信息管理等场景。
三、DLedger 的优化
1. 性能优化 Raft 协议复制过程可以分为四步先是发送消息给 leaderleader 除了本地存储之外会把消息复制给 follower然后等待follower 确认如果得到多数节点确认该消息就可以被提交并向客户端返回发送成功的确认。DLedger 中如何去优化这一复制过程
1异步线程模型
DLedger 采用一个异步线程模型异步线程模型可以减少等待。在一个系统中如果阻塞点越少每个线程处理请求时能减少等待就能更好的利用 CPU提高吞吐量和性能。 以 DLedger 处理 Append 请求的整个过程来讲述 DLedger 异步线程模型。图中粗箭头表示 RPC 请求实现箭头表示数据流虚线表示控制流。
首先客户端发送 Append 请求由 DLedger 的通信模块处理当前 DLedger 默认的通信模块是利用 Netty 实现的因此 Netty IO 线程会把请求交给业务线程池中的线程进行处理然后 IO 线程直接返回处理下一个请求。业务处理线程处理 Append 请求有三个步骤首先是把 Append 数据写入自己日志中也就是 pagecache 中。然后生成 Append CompletableFuture 放入一个 Pending Map 中由于该日志还没有得到多数的确认所以它是一个判定状态。第三步唤醒 EnrtyDispatcher 线程通知该线程去向follower 复制日志。三步完成以后业务线程就可以去处理下一个 Append 请求中间几乎没有任何等待。
另一方面复制线程 EntryDispatcher 会向 follower 复制日志每一个 follower 都对应一个 EntryDispatcher 线程该线程去记录自己对应 follower 的复制位点每次位点移动后都会去通知 QurumAckChecker 线程这个线程会根据复制位点的情况判断是否一条日志已经复制到多数节点上如果已被复制到了多数节点该日志就可以被提交并去完成对应的 Append CompletableFuture 通知通信模块向客户端返回响应。
2独立并发的复制过程 在 DLedger 中leader 向所有 follower 发送日志也是完全相互独立和并发的leader 为每个 follower 分配一个线程去复制日志并记录相应的复制位点然后再由一个单独的异步线程根据位点情况检测日志是否被复制到了多数节点上返回给客户端响应。
3日志并行复制 传统的线性复制是 leader 向 follower 复制日志follower 确认后下一个日志条目再复制也就是 leader 要等待 follower 对前一条日志确认后才能复制下一条日志。这样的复制方式保证了顺序性且不会出错但吞吐量很低时延也比较高因此DLedger设计并实现日志并行复制的方案不再需要等待前一个日志复制完成再复制下一个日志只需在 follower 中维护一个按照日志索引排序请求列表 follower 线程按照索引顺序串行处理这些复制请求。而对于并行复制后可能出现数据缺失问题可以通过少量数据重传解决。
2. 可靠性优化
1DLedger对网络分区的优化 如果出现上图的网络分区n2与集群中的其他节点发生了网络隔离按照 raft 论文实现n2会一直请求投票但得不到多数的投票term 一直增大。一旦网络恢复后n2就会去打断正在正常复制的n1和n3进行重新选举。为了解决这种情况DLedger 的实现改进了 raft 协议请求投票过程分成了多个阶段其中有两个重要阶段WAIT_TO_REVOTE和WAIT_TO_VOTE_NEXT。WAIT_TO_REVOTE是初始状态这个状态请求投票时不会增加 termWAIT_TO_VOTE_NEXT则会在下一轮请求投票开始前增加 term。对于图中n2情况当有效的投票数量没有达到多数量时。可以将节点状态设置WAIT_TO_REVOTEterm 就不会增加。通过这个方法提高了Dledger对网络分区的容忍性。
2DLedger 可靠性测试
DLedger 还有非常高的容错性。它可以容忍各种各样原因导致节点无法正常工作比如
● 进程异常崩溃 ● 机器节点异常崩溃机器断电操作系统崩溃 ● 慢节点出现 Full GCOOM 等 ● 网络故障各种各样的网络分区
为了验证 DLedger 对这些故障的容忍性除了本地对 DLedger 进行了各种各样的测试还利用分布式系统验证与故障注入框架 Jepsen 来检测 DLedger 存在的问题并验证系统的可靠性。 Jepsen 框架主要是在特定故障下验证系统是否满足一致性。Jepsen 验证系统由 6 个节点组成一个控制节点Control Node五个 DB 节点DB Node。控制节点可以通过 SSH 登录到 DB 节点通过控制节点的控制可以在 DB 节点完成分布式系统的下载部署组成一个待测试的集群。测试开始后控制节点会创建一组 Worker 进程每一个 Worker 都有自己的分布式系统客户端。Generator 产生每个客户端执行的操作客户端进程将操作应用于待测试的分布式系统。每个操作的开始和结束以及操作结果记录在历史记录中。同时一个特殊的 Client 进程 Nemesis 将故障引入系统。测试结束后 Checker 分析历史记录是否正确是否符合一致性。
根据 DLedger 定位它是一个基于 raft 协议的 commitlog 存储库是一个 append only 的日志系统采用 Jepsen 的 Set模型进行测试。Set 模型的测试流程分为两个阶段。第一阶段由不同的客户端并发地向待测试集群添加不同的数据中间会进行故障注入。第二阶段向待测试集群进行一次最终读取获得读取的结果集。最后验证每一个成功添加的元素都在最终结果集中并且最终的结果集也仅包含企图添加的元素。 上图是 DLedger 其中一次测试结果有30个客户端进程并发地向待测试的 DLedger 集群添加数据中间会引入随机对称网络分区故障引入的间隔时间默认是30s也就是30s正常运行30s故障引入再30s正常运行、30s故障引入一直循环。整个阶段一共持续600s。可以看到最后一共发送了16万个数据中间没有出现数据丢失lost-count0也没有出现不应该存在的数据uexpected-count0一致性测试通过。 上图展示了该次测试中客户端对DLedger集群每一次操作情况蓝色小框表示添加成功红色小框表示添加失败黄色小框表示不确定是否添加成功比如多数认证超时图中灰色部分表示故障引入的时间段。可以看出一些故障引入时间段造成集群短暂不可用一些故障时间段则没有这是合理的。因为是随机网络隔离所以需要看隔离的节点会不会造成集群重新选举。但即使造成集群重新选举一段时间后DLedger集群也会恢复可用性。
除了测试对称网络分区故障还测试了其他故障下 Dledger 表现情况包括随机杀死节点随机暂停一些节点的进程模拟慢节点的状况以及 bridge、partition-majorities-ring 等复杂的非对称网络分区。在这些故障下DLedger 都保证了一致性验证了 DLedger 有很好可靠性。
四、DLedger 未来发展
DLedger 接下来的计划包括:
● Leader 节点优先选择 ● RocketMQ on DLedger 的Jepsen 测试 ● 运行时成员变更 ● 增加观察者只参与复制不参与投票 ● 构建高可用的K/V存储 ● ……
DLedger 现在是在 OpenMessaging 下的一个项目欢迎社区的同学一起加入来构建高可用高性能的 commitlog 存储库。
原文链接 本文为云栖社区原创内容未经允许不得转载。