初见Raft

本文探讨了Raft和Paxos两种分布式一致性协议的异同。通过对比发现,尽管两者在理论上都能保证系统的正确性,但Raft通过引入term概念和限制日志流动方向等手段,在实践中更易于理解和实现。

这几天研究了一下Raft协议,继Paxos之后出来的第二个可以理论证明自己正确性的分布式一致性协议(可以这么说吧,没仔细了解过其它协议)。

其实看过paxos,初看Raft,感觉还是有很多熟悉的面孔,仔细看作者的描述,确实两者也有不少差别。

我觉得basic paxos好像也没有Ongaro说的那么难以理解吧,不过有一点是肯定的,paxos给出了理论,但是距离一个基本可用的工程实践确实还有很远的距离。

很多关键的细节,比如新leader当选后,节点之间的日志如何sync;再比如选leader,paxos只保证proposal number最大者胜出,但是这个proposal number和工程意义的联系在哪里,比如是不是拥有最新日志的参与者,其proposal number应该越高;等等问题。

找时间再把paxos复习一编,很多都忘了,当初也不一定理解的对。

Raft将日志限制到了leader到follower的单向流动,又对能够竞选上leader的candidate施加了限制条件,这简化了很多问题。

Raft引入了term的概念,这玩意太像中国历史了,类比起来很容易理解term和leader的行为。

看Raft的论文,如何保证一条已经commit的log永远不丢失,并不难理解;可能稍微困难一点的是如果一条日志没有被commit,它后面可能出现什么问题?这里面有很多corner case。

如果一条日志在commit之前,leader被推翻了。那么这条日志就是未决状态,可能会被新leader间接的commit,也可能被覆盖掉。

如果leader在commit这条日志上花了太长的时间,比如100ms,leader可能暂时和它的follower闪断了,包延迟,有这个可能。会不会有什么不良后果?

Raft一个比较核心的概念就是log的committed状态,log被写入文件,不一定代表它是committed的,这个是理解Raft的核心之一吧。

如果一条log被leader commit了,也就被apply到了leader的状态机,然后,它何时会被各follower apply到状态机中?

随便写点,比较乱。


### RAFT分布式一致性算法概述 RAFT是一种用于管理日志复制的一致性算法,其设计目标是提高可理解性和实际系统的可实现性[^4]。RAFT通过将问题分解为几个关键部分来简化复杂性,包括领导选举(leader election)、日志复制(log replication)和安全性(safety)。这种分解方法使得RAFT比Paxos更容易理解和实现。 在领导选举方面,RAFT使用心跳机制来维护领导者的状态,并通过选举超时机制来处理领导者失效的情况[^2]。当一个跟随者(follower)检测到心跳超时,它会发起选举并请求其他节点投票。如果一个节点获得多数票,则成为新的领导者。 日志复制是RAFT的核心功能之一。领导者负责接收客户端的请求并将这些请求作为日志条目追加到自己的日志中。然后,领导者将这些日志条目复制到所有跟随者的日志中,并在确认大多数节点已成功复制后应用这些日志条目[^4]。 为了确保一致性RAFT引入了一些规则来限制领导者的选择。例如,任何候选者在赢得选举之前必须包含最新的日志条目[^1]。此外,领导者在提交日志条目时必须确保该条目已被大多数节点复制。 以下是RAFT算法的一个简单伪代码示例: ```python class RaftNode: def __init__(self): self.currentTerm = 0 self.votedFor = None self.log = [] def request_vote(self, candidateId, term, lastLogIndex, lastLogTerm): if term < self.currentTerm: return False, self.currentTerm if self.votedFor is None or self.votedFor == candidateId: self.votedFor = candidateId return True, self.currentTerm return False, self.currentTerm def append_entries(self, leaderId, term, prevLogIndex, prevLogTerm, entries, leaderCommit): if term < self.currentTerm: return False, self.currentTerm if prevLogIndex >= len(self.log) or self.log[prevLogIndex].term != prevLogTerm: return False, self.currentTerm self.log = self.log[:prevLogIndex + 1] + entries return True, self.currentTerm ``` ### 性能优化与测试验证 除了算法本身的设计外,RAFT的实际实现还需要考虑性能优化和测试验证。例如,JRaft项目使用了Jepsen框架进行分布式验证和故障注入测试,模拟了多种复杂的网络环境和节点故障情况,以确保算法的正确性和鲁棒性[^3]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值