分布式共识算法 (一) 背景html
分布式共识算法 (四) BTF算法promise
Paxos,最先是Leslie Lamport 用Paxos岛的故事模型进行描述,而得以命名。这位大神原来是学数学的,最终变成了计算机科学家,在2013年得到图灵奖...附上美照:架构
Paxos问题是指分布式的系统中存在故障(crash fault),但不存在恶意(corrupt)节点的场景(即可能消息丢失/重复,但无错误消息)下的共识达成问题。并发
Paxos 协议是一个解决分布式系统中,多个节点之间就某个值(提案)达成一致(决议)的通讯协议。分布式
1990年Leslie Lamport在论文《The Part-time Parliament》中提出Paxos共识算法,在工程角度实现了一种最大保障分布式系统一致性的机制。Paxos算法被普遍应用在Chubby、ZooKeeper中。post
Paxos wiki:Paxos (computer science)
性能
Client:客户端,发起请求并等待返回。
Proposer(提案者):处理客户端请求,将客户端的请求发送到集群中,以便决定这个值是否能够被批准。
Acceptor(接受者):负责处理接收到的提议,他们的回复就是一次投票。会存储一些状态来决定是否接收一个值。
Learner(学习者):当有同一个value的协议被超过一半的Acceptor采纳并发送消息给Learner时,Learner采纳该协议值。
Leader:一个特殊的Proposer。学习
核心实现Paxos Instance主要包括两个阶段:
准备阶段(prepare phase)和提议阶段(accept phase)。细化为4个小阶段,wiki上是这样描述的:
简单来讲,Basic Paxos 是一个经典两阶段提交(2PC)
第一阶段:
第二阶段:
配上wiki流程图以下:
其中prepare阶段的做用,以下图所示:
1.S1首先发起accept(1,red),并在S1,S2和S3达成多数派,red在S1,S2,S3上持久化
2.随 后S5发起accept(5,blue),在S3,S4和S5达成多数派,blue在S3,S4和S5持久化
4.最后的结果是,S1和S2的值是red,而S4和S5的值是blue,s3存在异议,red覆盖了blue?
解决方案:
不少文章有误解说Muti-Paxos是一阶段提交,那是仅限于leader稳定时。刚选出来一个新的leader时,依然是二阶段提交以下图:
若是leader稳定,不须要prepare和promise步骤,以下图(图中Proposer就是一个Leader):
Multi Paxos中leader用于避免活锁(例如1个leader,4个Proposer,2个提议A,2个提议B不能达成一致,致使活锁),但leader的存在会带来其余问题,一是如何选举和保持惟一leader(虽然无leader或多leader不影响一致性,但影响决议进程progress),二是充当leader的节点会承担更多压力,如何均衡节点的负载。Mencius[1]提出节点轮流担任leader,以达到均衡负载的目的;租约(lease)能够帮助实现惟一leader,但leader故障状况下可致使服务短时间不可用。
Google Chubby是一个高可用分布式锁服务,被设计成一个须要访问中心化节点的分布式锁服务。本文只分析chubby服务端的实现。
Chubby服务端的基本架构大体分为三层
① 最底层是容错日志系统(Fault-Tolerant Log),经过Paxos算法可以保证集群全部机器上的日志彻底一致,同时具有较好的容错性。
② 日志层之上是Key-Value类型的容错数据库(Fault-Tolerant DB),其经过下层的日志来保证一致性和容错性。
③ 存储层之上的就是Chubby对外提供的分布式锁服务和小文件存储服务。
Paxos算法用于保证集群内各个副本节点的日志可以保持一致,Chubby事务日志(Transaction Log)中的每个Value对应Paxos算法中的一个Instance(对应Proposer),因为Chubby须要对外提供不断的服务,所以事务日志会无限增加,因而在整个Chubby运行过程当中,会存在多个Paxos Instance,同时,Chubby会为每一个Paxos Instance都按序分配一个全局惟一的Instance编号,并将其顺序写入到事务日志中去。
在Paxos中,每个Paxos Instance都须要进行一轮或多轮的Prepare->Promise->Propose->Accept这样完整的二阶段请求过程来完成对一个提议值的选定,为了保证正确性的前提下尽量地提升算法运行性能,可让多个Instance共用一套序号分配机制,并将Prepare->Promise合并为一个阶段。具体作法以下:
① 当某个副本节点经过选举成为Master后,就会使用新分配的编号N来广播一个Prepare消息,该Prepare消息会被全部未达成一致的Instance和目前还未开始的Instance共用。
② 当Acceptor接收到Prepare消息后,必须对多个Instance同时作出回应,这一般能够经过将反馈信息封装在一个数据包中来实现,假设最多容许K个Instance同时进行提议值的选定,那么:
-当前之多存在K个未达成一致的Instance,将这些未决的Instance各自最后接受的提议值封装进一个数据包,并做为Promise消息返回。
-同时,判断N是否大于当前Acceptor的highestPromisedNum值(当前已经接受的最大的提议编号值),若是大于,那么就标记这些未决Instance和全部将来的Instance的highestPromisedNum的值为N,这样,这些未决Instance和全部将来Instance都不能再接受任何编号小于N的提议。
③ Master对全部未决Instance和全部将来Instance分别执行Propose->Accept阶段的处理,若是Master可以一直稳定运行的话,那么在接下来的算法运行过程当中,就再也不须要进行Prepare->Promise处理了。可是,一旦Master发现Acceptor返回了一个Reject消息,说明集群中存在另外一个Master而且试图使用更大的提议编号发送了Prepare消息,此时,当前Master就须要从新分配新的提议编号并再次进行Prepare->Promise阶段的处理。
可见chubby就是一个典型的Muti-Paxos算法应用,在Master稳定运行的状况下,只须要使用同一个编号来依次执行每个Instance的Promise->Accept阶段处理。
Paxos算法的变种还有不少Cheap Paxos、Fast Paxos等等,本文介绍了使用最广的Muti-Paxos算法。但愿可以带给你们一点分布式一致性算法的入门灵感和思想。
====================
参考:
1.paxos的wiki:Paxos (computer science)
2.csdn博客:一步一步理解Paxos算法
3.书:《从Paxos到Zookeeper》
4.论文:《Time-Clocks-and-the-Ordering-of-Events-in-a-Distributed-System》
5.书:《区块链 原理、设计与应用》