拜占庭将军问题是分布式领域最复杂、最严格的容错模型 。但在日常工作中使用的分布式系统面对的问题不会那么复杂,更多的是计算机故障挂掉了,或者网络通信问题而没法传递信息,这种情况不考虑计算机之间互相发送恶意信息,极大简化了系统对容错的要求,最主要的是达到一致性 。所以将拜占庭将军问题根据常见的工作上的问题进行简化:假设将军中没有叛军,信使的信息可靠但有可能被暗杀的情况下,将军们如何达成一致性决定?
对于这个简化后的问题,有许多解决方案,第一个被证明的共识算法是 Paxos,由拜占庭将军问题的作者 Leslie Lamport 在1990年提出,最初以论文难懂而出名,后来这哥们在2001重新发了一篇简单版的论文 Paxos Made Simple,然而还是挺难懂的 。
因为 Paxos 难懂,难实现,所以斯坦福大学的教授在2014年发表了新的分布式协议 Raft 。与 Paxos 相比,Raft 有着基本相同运行效率,但是更容易理解,也更容易被用在系统开发上 。
针对简化版拜占庭将军问题,Raft 解决方案类比我们还是用拜占庭将军的例子来帮助理解 Raft 。
假设将军中没有叛军,信使的信息可靠但有可能被暗杀的情况下,将军们如何达成一致性决定?Raft 的解决方案大概可以理解成 先在所有将军中选出一个大将军,所有的决定由大将军来做 。选举环节:比如说现在一共有3个将军 A, B, C,每个将军都有一个随机时间的倒计时器,倒计时一结束,这个将军就会把自己当成大将军候选人,然后派信使去问其他几个将军,能不能选我为总将军?假设现在将军A倒计时结束了,他派信使传递选举投票的信息给将军B和C,如果将军B和C还没把自己当成候选人(倒计时还没有结束),并且没有把选举票投给其他,他们把票投给将军A,信使在回到将军A时,将军A知道自己收到了足够的票数,成为了大将军 。在这之后,是否要进攻就由大将军决定,然后派信使去通知另外两个将军,如果在一段时间后还没有收到回复(可能信使被暗杀),那就再重派一个信使,直到收到回复 。
故事先讲到这里,希望不做技术方面的朋友可以大概能理解 Raft 的原理,下面从比较技术的角度讲讲 Raft 的原理 。
1. Raft 节点状态从拜占庭将军的故事映射到分布式系统上,每个将军相当于一个分布式网络节点,每个节点有三种状态:Follower,Candidate,Leader,状态之间是互相转换的,可以参考下图,具体的后面说 。
文章插图
【共识算法Raft为什么这么流行,及原理解析】每个节点上都有一个倒计时器 (Election Timeout),时间随机在 150ms 到 300ms 之间 。有几种情况会重设 Timeout:
- 收到选举的请求
- 收到 Leader 的 Heartbeat (后面会讲到)
- 选主 Leader Election
- 复制日志 Log Replication
文章插图
假设现在有如图5个节点,5个节点一开始的状态都是 Follower 。
文章插图
在一个节点倒计时结束 (Timeout) 后,这个节点的状态变成 Candidate 开始选举,它给其他几个节点发送选举请求 (RequestVote)
文章插图
其他四个节点都返回成功,这个节点的状态由 Candidate 变成了 Leader,并在每个一小段时间后,就给所有的 Follower 发送一个 Heartbeat 以保持所有节点的状态,Follower 收到 Leader 的 Heartbeat 后重设 Timeout 。
这是最简单的选主情况,只要有超过一半的节点投支持票了,Candidate 才会被选举为 Leader,5个节点的情况下,3个节点 (包括 Candidate 本身) 投了支持就行 。
2.2 Leader 出故障情况下的选主
文章插图
一开始已经有一个 Leader,所有节点正常运行 。
文章插图
Leader 出故障挂掉了,其他四个 Follower 将进行重新选主 。
文章插图
推荐阅读
- 数据科学家需要知道的5种图算法
- 算法浅谈——人人皆知却很多人写不对的二分法
- 负载均衡的5种算法,你了解几种?
- 中国茶叶行业T20峰会达成十点共识
- 谷歌近期排名不稳定,算法更新正在发生
- 分布式寻址算法
- 计算机基本原理—语言与算法
- 清晰明了的JavaScript版动态规划
- 愿茶为国饮成为国民共识讲座周日开讲
- 算法专题-手动实现循环队列