为何prepare请求要过半返回才算成功?
- 可终止性:一旦有过半节点的为同一个状态,则集群的状态确定,以后无法改变;
- 获取Accept请求锁:集群任何时刻,Accept只能接受一个版本号,即最近成功请求prepare的版本号;
为何要使用最新的版本号?
- Paxos的约定:分歧状态下选取最新的提案广播
- Acceptor的目的就是获取集群最新状态
- Paxos选举是一个过程,从集群的多种状态最终衍变到唯一状态,后者认同前者
Paxos选举的原子性?
- Prepare、Accept通过序号锁定一次选举:
- 串行执行:P1————>o|P2————>o|A1- - - - ->o|A2————>o
Paxos选举的生命周期
- 如果出现大于自己之前收到的序号,说明选举仍然在继续
- 历史终究是历史,历史不能改变,能改变的只有未来
Paxos选举过程的中关键节点
- 空
- 非空未过半
- 非空过半
- 相同状态未过半
- 相同状态过半————结束
Paxos、ZAB、Raft三者关系
- 个人认为Paxos与ZAB、Raft没有什么关系,因为ZAB、Raft是有Leader的角色,提案广播是基于顺序的,过程中某一提案是否最终提交可以依赖于下一次广播;而Paxos理论上任何节点都可以发起提案,而每一次选举是独立的。
- 如果硬要说有什么相似之处,那么ZAB选Leader的过程与Paxos是非常相近的,区别就在于约定不同,Paxos的前提是选取最新提案而不关心提案的值,而ZAB选择提案是根据提案的值来确定,因此Paxos需要一个版本号,而ZAB不需要,有人会说ZAB也有版本号的东东,其实在Paxos的世界里那个不是提案的版本号,是提案的值。
- Raft选Learder的做法似乎与Paxos和ZAB都不同,选Leader不关心版本号,也不关心提案的值,每个Raft节点都会发起选举请求,为了避免冲突,每个节点sleep一个随机值,谁先获取过半数响应谁就是Leader;这么选Leader后log的index不一样怎么办?很简单,选完Leader后由Leader进行同步,这有点意思。不过Raft在多节点集群以及较差网络环境下进行Leader选举似乎会比较困难了。
ZAB、Raft协议的可终止性实现
- Paxos基于读写串行操作,终止性保证容易理解。对于ZAB和Raft,虽然Leader选举算法不同,但是关于可终止性实现上有相似之处。每个节点刚自认为被选为Leader之后,会给它投票的过半集合发同步请求,如果同样收到了过半集合的Ack,,则Leader取得了其他节点的认可真正成为了Leader,选举结束了。
那些事儿
- 相同状态未过半时的集群状态
- 最大提交原则:冲突状态时某次提案获得Accept响应的节点越多,本次提案的值越有可能成为过半数节点的值,即集群最终值。