在 RocketMQ 构建高可靠、强一致性消息系统的架构中,DLedgerServer 扮演着举足轻重的角色,而 MemberState 作为 DLedgerServer 内部用于描述节点状态的核心类,更是整个分布式日志模块稳定运行的关键。深入理解 MemberState 的设计理念、功能特性和工作原理,有助于我们揭开 RocketMQ 高可用背后的技术奥秘。本文将从多个维度对 DLedgerServer 中的 MemberState 进行详细介绍与剖析。
一、MemberState 的基础概念与重要性
MemberState 是 DLedgerServer 用于记录和管理节点状态的核心数据结构,它贯穿于 DLedger 协议的选举、日志同步、故障恢复等各个环节。在基于 Raft 协议的 DLedger 集群中,每个节点都有自己的 MemberState 实例,该实例保存着节点在集群中的角色、选举周期、日志同步进度等关键信息。这些信息的准确维护和及时更新,是保证集群正常运行、实现高可用和数据一致性的基础。无论是节点的选举过程,还是消息的复制与提交,MemberState 都在其中发挥着承上启下的作用,协调着节点之间的协作与交互。
二、MemberState 的核心属性
//deleger 框架的核心配置信息public final DLedgerConfig dLedgerConfig;//一个可重入的锁private final ReentrantLock defaultLock = new ReentrantLock();//server成员的分组信息,一组是有多个Serverprivate final String group;//Server成员自己的idprivate final String selfId;//一组Server里面其他Server的节点信息private final String peers;//server节点当前的角色信息 默认角色是CANDIDATE(候选人)//一开始都是这个CANDIDATE角色 还没有开始选举 等选举完成//就会有LEADER或者FOLLOWER 这两种角色了private volatile Role role = CANDIDATE;//当前server节点所属的分组中learder节点的idprivate volatile String leaderId;//当前term条目private volatile long currTerm = 0;//当前投票给谁当leaderprivate volatile String currVoteFor;//leader结尾的索引 默认是-1private volatile long ledgerEndIndex = -1;//leader结尾的 默认是-1private volatile long ledgerEndTerm = -1;//Server分组中已知道的最大的条目 默认也是-1private long knownMaxTermInGroup = -1;//当前server分组里其他peer节点的信息private Map<String, String> peerMap = new HashMap<>();//当前server分组里peer节点是否存活的映射数据信息private Map<String, Boolean> peersLiveTable = new ConcurrentHashMap<>();//传输者的概念private volatile String transferee;//当前用于获取leader节点的terms条目 默认是-1private volatile long termToTakeLeadership = -1;
核心属性
-
role:该属性用于标识节点在集群中的角色,常见的取值包括Leader、Follower和Candidate。Leader角色的节点负责接收客户端的写请求,并将日志复制到其他Follower节点;Follower节点处于被动状态,接收并存储Leader节点同步过来的日志,响应Leader的心跳和投票请求;Candidate角色则在选举过程中出现,节点在发起选举时会转变为Candidate,尝试获取集群中其他节点的投票以成为新的Leader。例如,在一个新启动的 DLedger 集群中,所有节点初始角色均为Follower,随着选举流程的推进,部分节点会转变为Candidate,最终选举出一个Leader节点
-
currTerm:表示当前的选举周期。在 Raft 协议中,term是一个重要的概念,它用于标识不同的选举阶段,每个term内只会有一个Leader。当节点发起选举时,会将自己的term值加 1,并向其他节点发送投票请求。其他节点在处理投票请求时,会优先考虑term值更高的节点。例如,在一次选举过程中,如果有两个Candidate节点同时发起投票请求,拥有更高term值的节点将更有可能获得其他节点的投票。
-
currVoteFor:记录当前节点在本次选举周期中投票给了哪个节点。该属性确保了每个节点在一个term内只能投一票,并且在选举过程中可以追踪投票的流向。当节点接收到投票请求时,会根据自身的term和voteFor属性来决定是否投票给请求节点。如果请求节点的term大于当前节点的term,且当前节点尚未投票(voteFor为null),则当前节点会将票投给请求节点,并更新voteFor属性。
三、MemberState 的状态转换逻辑
3.1 从 Follower 到 Candidate 的转换
当Follower节点在一定时间内(选举超时时间)没有收到Leader节点的心跳消息时,它会认为Leader可能已经宕机,此时Follower节点会触发选举流程,将自身的MemberState中的role属性从Follower转变为Candidate,同时将term值加 1,并向集群中的其他节点发送投票请求。在发送投票请求时,会携带自身的term、ledgerEndIndex和ledgerEndTerm等信息,以便其他节点进行投票决策。例如,节点 A 作为Follower,在选举超时后,将自己的role设置为Candidate,term从当前的 3 变为 4,并向节点 B、C、D 发送投票请求,请求内容包括 “我是节点 A,term为 4,ledgerEndIndex为 50,ledgerEndTerm为 3,请求投票”。
3.2 从 Candidate 到 Leader 或 Follower 的转换
-
成为 Leader:当Candidate节点在一个选举周期内获得超过半数节点的投票时,它将赢得选举,成为Leader节点。此时,Candidate节点会更新自身MemberState的role为Leader,并开始向其他Follower节点发送心跳消息和日志复制请求。例如,在一个包含 5 个节点的集群中,节点 A 作为Candidate,收到了节点 B、C 的投票,加上自身的一票,共获得 3 票(超过半数),则节点 A 成功当选为Leader,将role设置为Leader,并向节点 B、C、D 发送心跳消息以维持领导地位。
-
重新成为 Follower:如果Candidate节点在选举过程中发现其他节点的term值比自己更高,或者在等待投票的过程中收到了Leader节点的心跳消息,它会意识到已经有其他节点成为了Leader,此时Candidate节点会将自身的role重新设置为Follower,并更新term为更高的term值,以与新的Leader保持一致。例如,节点 A 作为Candidate正在等待投票,此时收到了节点 B(term为 5)发送的心跳消息,而节点 A 的term为 4,那么节点 A 会将自己的role改为Follower,term更新为 5,继续作为Follower接收Leader节点 B 的消息。
3.3 从 Leader 到 Follower 的转换
当Leader节点出现故障,如网络中断、宕机等情况,导致无法正常向Follower节点发送心跳消息和日志复制请求时,Follower节点会在选举超时后发起新一轮选举。如果在新一轮选举中,其他节点当选为新的Leader,原Leader节点在恢复正常后,会发现集群中已经有了新的Leader(通过收到新Leader的心跳消息或投票请求得知),此时原Leader节点会将自身的role从Leader转换为Follower,并更新term和其他相关属性,以适应新的集群状态。
四、MemberState 与 DLedgerServer 其他组件的协同工作
MemberState 与 DLedgerServer 的选举组件、远程通信组件、日志存储组件等密切协作,共同保障 DLedger 集群的正常运行。在选举过程中,选举组件依赖MemberState的属性来判断节点的选举资格和投票决策;远程通信组件在发送和接收消息时,会携带MemberState的相关信息,如节点角色、term等,以便其他节点进行处理;日志存储组件在写入和读取日志时,会与MemberState中的lastLogIndex和lastLogTerm进行交互,确保日志的一致性和完整性。例如,在日志复制过程中,Leader节点的远程通信组件会将MemberState中的ledgerEndIndex和ledgerEndTerm等信息封装到日志复制请求中,发送给Follower节点;Follower节点接收到请求后,会根据自身MemberState的相关属性进行校验,然后将日志写入日志存储组件,并更新自身MemberState的ledgerEndIndex和ledgerEndTerm。
MemberState 作为 RocketMQ 中 DLedgerServer 的核心状态管理类,通过对节点角色、选举周期、日志同步等关键信息的精准维护和高效管理,在集群的选举、日志同步、故障恢复等各个环节中发挥着不可或缺的作用。深入理解 MemberState 的设计和工作原理,不仅有助于我们掌握 RocketMQ 高可用和强一致性的实现机制,还能为在实际应用中优化和调试 DLedger 集群提供有力的支持。随着分布式系统技术的不断发展,相信 MemberState 的设计理念和实现方式也将不断演进和完善,为构建更加可靠、高效的消息系统奠定坚实的基础。