源码分析 RocketMQ DLedger(多副本) 之日志复制(传播)
温馨提示:源码分析RocketMQ DLedger 多副本系列连载中:
1、RocketMQ 多副本前置篇:初探raft协议
2、源码分析 RocketMQ DLedger 多副本之 Leader 选主
3、源码分析 RocketMQ DLedger 多副本存储实现
4、源码分析 RocketMQ DLedger(多副本) 之日志追加流程
本文紧接着 源码分析 RocketMQ DLedger(多副本) 之日志追加流程 ,继续 Leader 处理客户端 append 的请求流程中最至关重要的一环:日志复制。
DLedger 多副本的日志转发由 DLedgerEntryPusher 实现,接下来将对其进行详细介绍。
目录温馨提示:由于本篇幅较长,为了更好的理解其实现,大家可以带着如下疑问来通读本篇文章:
1、raft 协议中有一个非常重要的概念:已提交日志序号,该如何实现。
2、客户端向 DLedger 集群发送一条日志,必须得到集群中大多数节点的认可才能被认为写入成功。
3、raft 协议中追加、提交两个动作如何实现。
- 1、DLedgerEntryPusher
- 1.1 核心类图
- 1.2 构造方法
- 1.3 startup
- 2、EntryDispatcher 详解
- 2.1 核心类图
- 2.2 Push 请求类型
- 2.3 doWork 方法详解
- 2.3.1 checkAndFreshState 详解
- 2.3.2 append 请求详解
- 2.3.2.1 doCommit 发送提交请求
- 2.3.2.2 doCheckAppendResponse 检查并追加请求
- 2.3.2.3 doAppendInner 追加请求
- 2.3.3 compare 请求详解
- 2.3.3.1 doTruncate 详解
- 3、EntryHandler 详解
- 3.1 核心类图
- 3.2 handlePush
- 3.3 doWork 方法详解
- 3.3.1 handleDoCommit
- 3.3.2 handleDoCompare
- 3.3.3 handleDoTruncate
- 3.3.4 handleDoAppend
- 3.3.5 checkAbnormalFuture
- 4、QuorumAckChecker
- 4.1 类图
- 4.2 doWork 详解
日志复制(日志转发)由 DLedgerEntryPusher 实现,具体类图如下:
主要由如下4个类构成:
- DLedgerEntryPusher
DLedger 日志转发与处理核心类,该内会启动如下3个对象,其分别对应一个线程。 - EntryHandler
日志接收处理线程,当节点为从节点时激活。 - QuorumAckChecker
日志追加ACK投票处理线程,当前节点为主节点时激活。 - EntryDispatcher
日志转发线程,当前节点为主节点时追加。
接下来我们将详细介绍上述4个类,从而揭晓日志复制的核心实现原理。
1、DLedgerEntryPusher
1.1 核心类图
DLedger 多副本日志推送的核心实现类,里面会创建 EntryDispatcher、QuorumAckChecker、EntryHandler 三个核心线程。其核心属性如下:
- DLedgerConfig dLedgerConfig
多副本相关配置。 - DLedgerStore dLedgerStore
存储实现类。 - MemberState memberState
节点状态机。 - DLedgerRpcService dLedgerRpcService
RPC 服务实现类,用于集群内的其他节点进行网络通讯。 - Map
> peerWaterMarksByTerm
每个节点基于投票轮次的当前水位线标记。键值为投票轮次,值为 ConcurrentMap/, Long/** 节点对应的日志序号/>。 - Map