Appearance
第4章:共识与 Raft
共识的要求
共识要求正确节点不会决定不同值,决定值符合有效性规则,并在规定条件下最终决定。日志复制可通过连续确定日志位置等方式建立一系列共同决定。
FLP 说明在完全异步、确定性、允许一个进程崩溃的模型中,不能保证所有允许执行都终止。它没有说共识永远做不到,也没有排除随机化或部分同步条件下的活性。
任期与选举
Raft 用递增任期标识领导时期,节点在一个任期最多投一票。候选人获得多数票才能成为领导者。多数集合相交,配合每任期一票,保证同一任期不会有两个都获得多数的领导者。
候选人的日志还必须足够新:比较最后日志项的任期,再比较索引。若只按节点 ID 或心跳先后选主,新领导者可能缺少已提交记录。
投票与必要日志状态必须按协议持久化,否则重启后“忘记已投票”会破坏证明前提。
日志匹配与修复
领导者发送 AppendEntries,包含前一项的索引与任期。跟随者先验证前缀匹配,再接受新项;冲突的未提交后缀可以被覆盖。
“复制更多日志”不等于随意拼接两个日志。索引相同但任期不同的项代表冲突历史,需要按协议选择一个合法前缀延伸。
提交条件
领导者通过多数复制直接推进提交索引时,Raft 要求所计数的日志项属于当前任期;它之前的项随此前缀一起提交。不能将某个旧任期项当前恰好位于多数副本,就独立当作安全提交证据。
这一限制与投票新旧比较、日志前缀匹配共同保证已提交项不会在后续领导者中丢失。省掉其中一条规则,不能只凭多数交集继续声称安全。
读取与快照
领导者本地读取也要确认自己仍有权提供线性一致读,并确保应用到适当提交位置。可用 quorum 确认等 ReadIndex 类机制,或在明确时间假设下使用租约;旧领导者直接读本地状态可能过期。
快照压缩已应用日志,但必须保留快照所到达的索引、任期及成员配置等必要元数据。成员变更同样需要保证旧新配置之间正确交接多数关系。
练习
- 证明同一任期两个多数领导者与“每节点一票”矛盾。
- 日志最新的节点为什么不一定是节点编号最大的节点?
- 区分日志已接收、已持久化、已提交、已应用四个状态。