基于 raft 协议的 RocketMQ DLedger 多副本日志复制设计原理

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 上一篇 源码分析 RocketMQ DLedger(多副本) 之日志复制(传播) ,可能有不少读者朋友们觉得源码阅读较为枯燥,看的有点云里雾里,本篇将首先梳理一下 RocketMQ DLedger 多副本关于日志复制的三个核心流程图,然后再思考一下在异常情况下如何保证数据一致性。

上一篇 源码分析 RocketMQ DLedger(多副本) 之日志复制(传播) ,可能有不少读者朋友们觉得源码阅读较为枯燥,看的有点云里雾里,本篇将首先梳理一下 RocketMQ DLedger 多副本关于日志复制的三个核心流程图,然后再思考一下在异常情况下如何保证数据一致性。

1、RocketMQ DLedger 多副本日志复制流程图

1.1 RocketMQ DLedger 日志转发(append) 请求流程图

在这里插入图片描述

1.2 RocketMQ DLedger 日志仲裁流程图

在这里插入图片描述

1.3 RocketMQ DLedger 从节点日志复制流程图

在这里插入图片描述

2、RocketMQ DLedger 多副本日志复制实现要点

在这里插入图片描述
上图是一个简易的日志复制的模型:图中客户端向 DLedger 集群发起一个写请求,集群中的 Leader 节点来处理写请求,首先数据先存入 Leader 节点,然后需要广播给它的所有从节点,从节点接收到 Leader 节点的数据推送对数据进行存储,然后向主节点汇报存储的结果,Leader 节点会对该日志的存储结果进行仲裁,如果超过集群数量的一半都成功存储了该数据,主节点则向客户端返回写入成功,否则向客户端写入写入失败。

接下来我们来探讨日志复制的核心设计要点。

2.1 日志编号

为了方便对日志进行管理与辨别,raft 协议为一条一条的消息进行编号,每一条消息达到主节点时会生成一个全局唯一的递增号,这样可以根据日志序号来快速的判断数据在主从复制过程中数据是否一致,在 DLedger 的实现中对应 DLedgerMemoryStore 中的 ledgerBeginIndex、ledgerEndIndex,分别表示当前节点最小的日志序号与最大的日志序号,下一条日志的序号为 ledgerEndIndex + 1 。

与日志序号还与一个概念绑定的比较紧密,即当前的投票轮次。

2.2 追加与提交机制

请思考如下问题,Leader 节点收到客户端的数据写入请求后,通过解析请求,提取数据部分,构建日志对象,并生成日志序号,用 seq 表示,然后存储到 Leader 节点中,然后将日志广播(推送)到其从节点,由于这个过程中存在网络时延,如果此时客户端向主节点查询 seq 的日志,由于日志已经存储在 Leader 节点中了,如果直接返回给客户端显然是有问题的,那该如何来避免这种情况的发生呢?

为了解决上述问题,DLedger 的实现(应该也是 raft 协议的一部分)引入了已提交指针(committedIndex)。即当主节点收到客户端请求时,首先先将数据存储,但此时数据是未提交的,此过程可以称之为追加,此时客户端无法访问,只有当集群内超过半数的节点都将日志追加完成后,才会更新 committedIndex 指针,得以是数据能否客户端访问。

一条日志要能被提交的充分必要条件是日志得到了集群内超过半数节点成功追加,才能被认为已提交。

2.3 日志一致性如何保证

从上文得知,一个拥有3个节点的 DLedger 集群,只要主节点和其中一个从节点成功追加日志,则认为已提交,客户端即可通过主节点访问。由于部分数据存在延迟,在 DLedger 的实现中,读写请求都将由 Leader 节点来负责。那落后的从节点如何再次跟上集群的步骤呢?

要重新跟上主节点的日志记录,首先要知道的是如何判断从节点已丢失数据呢?

DLedger 的实现思路是,DLedger 会按照日志序号向从节点源源不断的转发日志,从节点接收后将这些待追加的数据放入一个待写队列中。关键中的关键:从节点并不是从挂起队列中处理一个一个的追加请求,而是首先查阅从节点当前已追加的最大日志序号,用 ledgerEndIndex 表示,然后尝试追加 (ledgerEndIndex + 1)的日志,用该序号从代写队列中查找,如果该队列不为空,并且没有 (ledgerEndIndex + 1)的日志条目,说明从节点未接收到这条日志,发生了数据缺失。然后从节点在响应主节点 append 的请求时会告知数据不一致,然后主节点的日志转发线程其状态会变更为COMPARE,将向该从节点发送COMPARE命令,用来比较主从节点的数据差异,根据比较的差异重新从主节点同步数据或删除从节点上多余的数据,最终达到一致。于此同时,主节点也会对PUSH超时推送的消息发起重推,尽最大可能帮助从节点及时更新到主节点的数据。

更多问题,`欢迎大家留言与我一起探讨。如果觉得文章对自己有些用处的话,麻烦帮忙点个赞,谢谢。

推荐阅读:RocketMQ 日志复制系列文章:
1、源码分析 RocketMQ DLedger 多副本存储实现
2、源码分析 RocketMQ DLedger(多副本) 之日志追加流程
3、源码分析 RocketMQ DLedger(多副本) 之日志复制(传播)


原文发布时间为:2019-10-02
本文作者:丁威,《RocketMQ技术内幕》作者。
本文来自中间件兴趣圈,了解相关信息可以关注中间件兴趣圈

相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
2月前
|
数据采集 传感器 监控
Modbus 与 MQTT 协议兼容:MyEMS 的泛在能源数据采集技术实现
MyEMS深度融合Modbus与MQTT协议,破解能源数据采集中协议碎片化、网络异构、数据孤岛等难题。通过Modbus接入95%以上工业设备,实现现场数据精准“拉取”;依托MQTT构建高效物联网传输通道,支持多源数据主动“推送”与云端集成。边缘侧采集规整,中心侧汇聚分析,形成统一、可靠、低延迟的数据流。该架构兼具高兼容性、强扩展性与低运维成本,广泛应用于工业园区、商业楼宇及集团型企业,支撑实时监控、AI分析与跨系统融合,打造泛在互联的能源数据底座,助力企业实现全面智慧能源管理。
230 6
|
9月前
|
数据可视化 关系型数据库 MySQL
嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议数据可视化
通过本文的介绍,我们详细讲解了如何结合嵌入式C++、STM32、MySQL、GPS、InfluxDB和MQTT协议,实现数据的采集、传输、存储和可视化。这种架构在物联网项目中非常常见,可以有效地处理和展示实时数据。希望本文能帮助您更好地理解和应用这些技术,构建高效、可靠的数据处理和可视化系统。
508 82
|
5月前
|
监控 安全 Java
Java 开发中基于 Spring Boot 3.2 框架集成 MQTT 5.0 协议实现消息推送与订阅功能的技术方案解析
本文介绍基于Spring Boot 3.2集成MQTT 5.0的消息推送与订阅技术方案,涵盖核心技术栈选型(Spring Boot、Eclipse Paho、HiveMQ)、项目搭建与配置、消息发布与订阅服务实现,以及在智能家居控制系统中的应用实例。同时,详细探讨了安全增强(TLS/SSL)、性能优化(异步处理与背压控制)、测试监控及生产环境部署方案,为构建高可用、高性能的消息通信系统提供全面指导。附资源下载链接:[https://pan.quark.cn/s/14fcf913bae6](https://pan.quark.cn/s/14fcf913bae6)。
861 0
|
8月前
|
存储 监控 Java
G1原理—7.G1的GC日志分析解读
本文进行了TLAB的GC日志解读、YGC的GC日志解读、模拟YGC(单次GC及多次GC的不同场景)、打开实验选项查看YGC的详情日志信息、Mixed GC日志信息之初始标记过程、Mixed GC日志信息之混合回收过程。
|
10月前
|
SQL 关系型数据库 MySQL
MySQL事务日志-Undo Log工作原理分析
事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。
495 7
MySQL事务日志-Undo Log工作原理分析
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
2268 14
MySQL事务日志-Redo Log工作原理分析
|
11月前
|
数据采集 传感器 监控
多协议网关BL110钡铼6路RS485转MQTT协议云网关
BL110钡铼6路RS485转MQTT协议云网关是一款高性能、易配置的工业级设备,适用于各种需要远程监控和数据采集的物联网应用场景。通过将传统RS485设备的数据转换为MQTT协议并上传至云平台,实现了设备的远程管理和智能控制,极大地提升了系统的管理效率和响应速度。
362 2
|
SQL 存储 关系型数据库
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
老架构师尼恩在其读者交流群中分享了关于 MySQL 中 redo log、undo log 和 binlog 的面试题及其答案。这些问题涵盖了事务的 ACID 特性、日志的一致性问题、SQL 语句的执行流程等。尼恩详细解释了这些日志的作用、所在架构层级、日志形式、缓存机制以及写文件方式等内容。他还提供了多个面试题的详细解答,帮助读者系统化地掌握这些知识点,提升面试表现。此外,尼恩还推荐了《尼恩Java面试宝典PDF》和其他技术圣经系列PDF,帮助读者进一步巩固知识,实现“offer自由”。
美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
|
网络协议 物联网 网络性能优化
物联网协议比较 MQTT CoAP RESTful/HTTP XMPP
【10月更文挑战第18天】本文介绍了物联网领域中四种主要的通信协议:MQTT、CoAP、RESTful/HTTP和XMPP,分别从其特点、应用场景及优缺点进行了详细对比,并提供了简单的示例代码。适合开发者根据具体需求选择合适的协议。
417 5
|
存储 缓存 关系型数据库
redo log 原理解析
redo log 原理解析
184 0
redo log 原理解析

热门文章

最新文章