概述
本文将简要概括全序广播与共识,清楚的理解这两个概念,将有助于理解raft、paxos等共识算法。
全序广播的要点是:消息按照相同的顺序发送到所有节点,有且只有一次。 仔细想想,这相当于进行多轮的共识过程:在每一轮,节点提出他们接下来要发送的消息,然后决定下一个消息的全局顺序。
主从复制与共识
主从复制是single master replication,master接收信息并广播给从节点,可以对标为一种fixed-sequencer的total order broadcast的实现方式(即[1]中的section4.1 fixed sequencer)。
但当主节点出故障时,我们需要重新选主。选主就涉及到共识,通过选举的方式将某个从节点提升为新的主节点。 同时还需要考虑脑裂,我们需要共识算法来选出一位主节点。 但如果共识算法是全序广播的话,又需要主节点,陷入奇怪循环。 如何解决呢?
Epoch and Quorum
目前讨论的共识协议在内部使用了某种形式的主节点,虽然主节点不是固定的。 相反,他们都采用了一种弱化的保证:协议定义一个世代编号(epoch number,对应raft中的term、paxos中ballot number) .
- 如果当前主节点失效,那么开始新的一轮选举, 选举赋予一个单调递增的epoch号。如果两个不同主节点对应于不同epoch号码,则具有更高epoch号码的主节点将获胜
- 在主节点作出任何决定之前,必须首先检查是否存在比它更高的epoch号码,否则就会产生冲突的决定
- 节点不能依靠自己所掌握的信息来决策。比如出现分区,老的主节点在分区的小集群上,新的主节点在多数集群上产生,这时候老的主节点其实已经失效。
- 这里面实际有两轮不同的投票:首先是投票决定谁是主节点,然后是对主节点的提议进行投票。
- 在raft的读取中,这是 read index.
投票过程与两阶段提交2PC
- 2PC的协调者并不是依赖选举产生
- 容错共识算法只需要收到多数节点的投票结果即可通过决议,而2PC则要求每个参与者都必须做出“是”才能最终通过。
共识算法与全序广播
全序关系广播的要点是:所有节点按照相同顺序接收消息,有且只有一次。 如果仔细想想,这其实相当于进行了多轮的共识过程。在每一轮中,节点提出他们接下来想要发送的消息,然后决定要以全序的方式接收的下一个消息。
所以,全序关系广播相当于持续的多轮共识(每一轮共识的决定对应于一条消息的接收):
- 由于共识的一致性属性(agreement property),所有节点以相同顺序接收相同消息
- 由于诚实性,消息不能重复
- 由于合法性,消息不会被破坏,也不会凭空捏造
- 由于可终止性,消息不会丢失。
对标到raft协议中的日志复制
raft协议中的日志复制是否可以对标全序广播
我们看一下全序广播:
- 尽最大努力可靠的广播,通过重发丢失的消息
- 基于可靠广播,保证接收顺序
total order broadcast protocol 要满足下面四个属性:
- validity (正确性):如果一个正确的进程广播了一条消息,那么其他所有正确的进程都接收到这条消息
- uniform agreement: 如果一个进程接收到消息m,那么所有正确的进程都接收到消息m
- uniform integrity: 一个进程最多接收一次消息m
- uniform total order: 如果进程p和q都接收到消息m和m’,当且仅当q接收消息m早于m’时,进程p接收消息m早于m’
综上所述, raft的日志保证是满足上述属性的。
- 尽最大努力可靠的广播:如果失败,则一直发送 附加条目rpc
- 基于可靠广播,保证接收顺序:接收到一条信息,leader会广播,然后作出决定 是否可以提交。
raft的实现中:
- leader 处理不一致是 通过强制跟随者直接复制自己的日志来解决的。 leader从来不会覆盖或者删除自己的日志。
- 安全性保证:当出现分区(或leader崩溃)时,只有拥有最新已提交记录的候选者才能成为leader。
特别注意:
在<数据密集型应用系统设计>中 将delivery翻译为发送,这实际是错误的。 在分布式-广播中介绍了,广播协议中 broadcast/deliver 对应的是发送和接收。 全序广播实际是指接收者要保持全序,与发送者的顺序无关。
参考:
- <数据密集型应用系统设计> chap9 一致性与共识
- 寻找一种易于理解的一致性算法