Raft作为两大分布式一致性协议之一(另一个就是大名鼎鼎的Paxos),本身是为了解决Paxos学习成本过高,工程实现过于困难的问题。在论文中也是遵循这个原则,因此阅读下来还是比较轻松的,而且也有丰富的图表可以帮助思考。

不过在实现上还是会有很多坑,再次感受到了分布式编程的困难之处,尤其是调试,也再次印证了printf是最好的调试工具~(事实上只能看日志来调试)

下面简单过一下Raft比较有意思的点。

选举安全

在同一term最多选举出一个leader。

首先所有节点都是follower,term=0,term相当于一个阶段。

follower等待一个随机的超时时间,超时以后该节点成为candidate,term+1,向其余节点发起投票请求。

其余节点发现投票请求中的term>=currentTerm,并且在currentTerm没有投过票,并且投票请求的日志记录至少与自己的日志记录一样新,就授权这次投票请求。

当某个candidate获得majority的授权以后,成为leader,并且向其余follower发送心跳。

如果某个term没有leader产生,那么在选举超时以后,会再发起选举。

Leader的日志完整性

只要在某个term一条日志被commit,那么这条日志将会出现在所有更高term的leader中。

假设存在一个比term T大且最小的term U,term U的leader不包含term T已经commit的日志。

因为要成为leader,必须获得majority follower的投票;同样地,一个日志要被commit,也必须被majority follower接收。所以至少存在一个follower,既接收了term T的leader的日志,也投票给了term U的leader。

如果term U的leader不包含之前commit的日志,那么这个follower是不会投票给他的。因此会矛盾。

论文里面是用反证法证明的。