分布式中的共识
在分布式中存在两个概念:“共识” 和 “一致性”
- 共识(Consensus):指所有节点就某项操作(如选主、原子事务提交、日志复制、分布式锁管理等)达成一致的实现过程
- 一致性(Consistency):描述多个节点的数据是否保持一致,关注数据最终达到稳定状态的结果
在分布式系统中,节点故障是不可避免的,但部分节点故障不应该影响系统整体状态。通过增加节点数量,依据 过半原则,只要多数节点(至少 N/2 + 1 )达成一致,其状态即可代表整个系统。这种依赖多数节点实现容错的机制称为 Quorum
机制。实际上该机制是在确保在分布式下无需过多的冗余节点即可达成效果一致的节点故障容忍
- 3 节点集群:Quorum 为 ⌈3/2⌉+1=2,允许 1 个节点故障
- 4 节点集群:Quorum 为 ⌈4/2⌉+1=3,允许 1 个节点故障
- 5 节点集群:Quorum 为 ⌈5/2⌉+1=3,允许 2 个节点故障
- 6 节点集群:Quorum 为 ⌈6/2⌉+1=3,允许 2 个节点故障
集群节点个数为 N 个时能容忍 N-1/2 个节点故障,我们可以发现奇数和偶数个节点的容灾能力是一致的
基于 Quorum 的机制,通过 “少数服从多数” 协商机制达成一致的决策,从而对外表现为一致的运行结果。这一过程被称为节点间的“协商共识”。
- 主节点选举:在主从复制数据库中,所有节点需要就“谁是 Leader”达成一致。如果由于网络问题导致节点间无法通信,很容易引发争议。若争议未解决,可能会出现多个节点“同时认为自己是主节点”的情况,这就是分布式系统中最棘手的问题:分区脑裂
- 原子事务提交:对于支持跨节点或跨分区事务的数据库,可能会发生部分节点事务成功、部分节点事务失败的情况。为维护事务的原子性(即 ACID 特性),所有节点必须就事务的 最终结果达成一致
- 分布式锁管理:当多个请求尝试访问共享资源时,共识机制可确保所有节点一致认定“谁成功获取了锁”。即使发生网络故障或节点异常,也能避免锁争议,从而防止并发冲突或数据不一致
- 日志复制:日志复制指将主节点的操作日志同步到从节点。在这一过程中,所有节点必须确保日志条目的顺序一致,即 日志条目必须以相同顺序写入
Raft
Raft 算法出现之前,绝大多数共识系统都是基于 Paxos 算法或者受其影响。同时 Paxos 算法也成为教学领域里讲解共识问题时的范例。不幸的是,对于大部分人来说 Paxos 算法太过于难理解了,并难以实现。而 Raft 算法则是一种更为简单方便易于理解的分布式算法,主要解决了分布式中的一致性问题。
Raft 中的名词
角色
Raft协议一共包含如下几类角色:
- Leader(领袖):领袖由群众投票选举得出,每次选举只能选出一名领袖
- Candidate(候选人):当没有领袖时,某些群众可以成为候选人然后去竞争领袖的位置
- Follower(群众):同步 Leader 的数据,具有投票能力,且具备成为候选者的潜质
- Learner(学习者):同步 Leader 的数据,不具备投票能力,具有成为群众的潜质
有些 raft 的实现库中会提供 Learner 角色, 通常我们可以将其看成集群中的后备角色
选举
在进行选举过程中,还有几个核心的概念:
- Leader Election(领导人选举):简称选举,从候选人中选出领袖
- Candidate (候选人):群众的选举超时后会升任为候选人,具备选举资格
- Term(任期):它其实是个单独递增的连续数字,每一次任期就会重新发起一次领导人选举
- Election Timeout(选举超时):就是一个超时时间,当群众超时未收到领袖的心跳时,会重新进行选举
raft 实现库中可能出现的组件
组件名 | 作用与说明 |
---|---|
Raft Node / Raft Core | Raft 协议的核心逻辑单元。每个节点负责:处理消息(选举、日志复制)、维持状态(term、role、log 等),对外提供接口 |
LogStore(日志存储) | 存储 Raft 日志条目(Log Entries),也就是 raft 集群通信日志和客户端请求(如写操作)记录。支持追加、读取、截断等操作 |
StateMachine(状态机) | 应用已提交日志 ,维护最终的业务状态。比如存储 key-value 数据、账户余额等。每个节点都要执行相同顺序的日志条目以保持一致状态 |
RaftLog / Log | 实际维护的日志列表,存放所有 待提交/已提交日志项 ,是 Raft 核心的数据结构之一 |
Snapshot(快照) | 用于压缩旧日志,提高效率。Snapshot 是 StateMachine 某一时刻的完整快照 ,用来帮助落后节点快速追上集群状态 |
Storage / PersistentStorage | 统一封装持久化组件(LogStore + Snapshot + Term 状态等),提供接口支持崩溃恢复 |
Network / Transport | 实现 Raft 节点之间的通信,负责发送 RPC(如 AppendEntries、RequestVote)支持网络错误处理和超时重试。 |
Timer / ElectionTimer / HeartbeatTimer | 定时器组件,用于触发选举超时(选新 Leader)或发送心跳(维持 Leader 身份) |
Membership / Cluster Config | 管理集群节点成员列表,如添加节点、删除节点等。变更过程也要通过日志达成一致 |
Metrics / Monitoring | 提供 Raft 内部状态信息,如当前 Leader 是谁、日志复制延迟、提交索引等,便于监控和调试 |
Client Interface | 接收客户端请求,通常只由 Leader 处理写入请求,并反馈提交结果给客户端 |