版权声明:本文为博主原创文章,未经博主容许不得转载。算法
手动码字不易,请你们尊重劳动成果,谢谢promise
如下摘自Paxos Made Simple论文:分布式
Phase 1. 学习
(a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors..net
(b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded, then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered proposal (if any) that it has accepted.code
Phase 2. blog
(a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n with a value v, where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals.get
(b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n.requests
Paxos算法的目的是为了在消息可能重复或丢失的状况下,在分布式系统中肯定一个值的最终取值。
Paxos算法中有两个关键的角色组:proposer
和acceptor
,其中acceptor
组决定了整个分布式环境的一致性。先介绍下proposer
和acceptor
的职责:
proposer为提案提出者,负责产生该值的可能性取值,并提交给acceptor进行决策。
proposer本地不持久化存储数据。
acceptor为决策者,负责批准或者拒绝一个proposer对该值的修改请求。
acceptor会在本地存储:
一、当前已收到的最大提案编号:PN,在未收到任何消息前,该值为空
二、当前最后一个批准的值的数据:Value,在未批准任何提案前,该值为空
首先来看下Paxos算法:
算法前提:全部proposer提出的提案编号不能重复。
第一阶段(预提案):
(a)proposer先选择一个提案编号N(咱们假设全部proposer都从0开始),而且将该编号的预提交请求Prepare(N)
发送给acceptor集合中的大多数服务(通常发送给所有acceptor集合)。
(b)若是一个acceptor接收到了一个提案编号为N的预提案请求Prepare(N)
,则比较其存储的最大提案编号PN
与N
的关系:
一、若是
PN
为空,则先令PN = N,Value = null
,而且赞成proposer的该预提案请求,发送当前acceptor的最大提案编号PN(等于N)和最后一个批准的数据Value(为空):PrepareResponse(PN, null)
二、若是PN < N
,则先令PN = N,Value = null
,而且赞成proposer的该预提案请求,发送当前acceptor的最大提案编号PN(等于N)和最后一个批准的数据Value(可能为空):PrepareResponse(PN, Value)
三、不然,拒绝该proposer的该预提案请求,发送当前acceptor的最大提案编号PN(大于N)和最后一个批准的数据Value(可能为空):PrepareResponse(PN, Value)
第二阶段(提案):
(a)当proposer的预提案Prepare(N)
被acceptor集合中的大多数赞成时(PN=N),则作出如下提案:
一、若是全部接收到的
PrepareResponse(PN, Value)
中Value
所有为空(acceptor还未批准任何提案),则本身制定一个该值的取值Vn,并向acceptor集合发送提案:Proposal(N, Vn)
二、若是接收到的PrepareResponse(PN, Value)
集合中存在不为空的Value
,则选取Value
不为空的PrepareResponse(PN, ValueNotNull)
集合中PN
最大的值(PNmax, ValueNotNull)
,并将其做为提案发送给acceptor集合:Proposal(PNmax, ValueNotNull)
(b)若是一个acceptor接收到一个提案编号为N的提案Proposal(N, Vn)
则:
一、若是
PN
为空或者PN < N
,则先令PN = N,Value = Vn
,而且经过该条提案,返回:ProposalResponse(PN, Value)
二、若是PN == N
而且Value
为空(还没有批准提案号为PN的任何提案),则先令Value = Vn
,而且经过该条提案,返回:ProposalResponse(PN, Value)
三、若是PN > N
则拒绝该提案,返回:ProposalResponse(PN, Value)
以上为Paxos算法的一种解释方式,可是仅仅经过这两轮提交可能没法肯定该值和取值:
一、只有acceptor集合中的大多数中的Value值都等于一个值时才能认定该值被肯定
二、经过一次提交可能因为信息丢失致使不一样的acceptor批准了不一样值的提案的状况
所以为了肯定该值的取值,可能须要多轮提案,下一轮提案的触发点的一种可能状况就是:
在proposer向acceptor提交预提案以后启动随机定时器,若是在超时前其预提案没有被大多数acceptor批准,则选取返回消息中最大的PN,在定时器超时后用
PN + 1
做为新的预提案号进行下一轮的二阶段提交。
paxos算法使用了集合中大多数这个保证来肯定一个值是否能够被最终肯定。好比N个节点集合的大多数为N / 2 + 1
。好比有5个节点则取值为3,6个节点则取值为4,7个节点也取值为4。
为何要使用集合中大多数这个概念呢,由于从集合全集中任取两个集合中大多数
集合,那么这两个集合一定至少存在一个公共元素。这个元素就是整个paxos算法的关键要素。
如下证实思路非严格证实,只阐明思路
咱们先假设一个值Value已经被一个acceptor集合的大多数批准了,咱们试图思考下这个值是否还会被改变:
若是一个proposer要决定一个提案,必须先进行两阶段提交。首先进行预提案,只有提案编号大于acceptor中保存的提案编号的预提案才能被经过,所以proposer首先选取了一个足够大的提案编号进行预提案,acceptor会返回其接受的提案编号和当前已批准的值,因为算法规定proposer进行第二阶段提交前必须得到acceptor集合中的大多数赞成,所以这个大多数acceptor集合中一定至少有一个acceptor已经批准了上述Value值,所以该提案必须使用这个提案编号最大的ValueX进行提案。
下面只须要证实这个提案编号最大的ValueX == Value
便可保证值永远不会改变。
首先假设当前Value值被在提案号为N时被大都数acceptor批准了,所以在第N+1个提案时,其从大都数acceptor获取预提案反馈时一定会接收到值为Value的提案,而且其提案编号时最大的。所以第N+1个提案的Value值也必须为Value。以此类推,以后全部的提案都不会改变该Value值的取值。
以上思路说明了一旦一个值被大多数acceptor批准,则以后的提案不会再改变这个值
(提案号仍是会单调增长)。
咱们说明了若是遵循paxos算法,一个值被选定了,则这个值永远不会被改变,那是否存在这个值永远不会被选定的状况呢?
proposerA使用提案编号1进行预提案得到了大多数acceptor的经过,以后proposerB使用提案编号2进行预提案得到了大多数acceptor的经过,proposerA使用提案编号1进行提案则会被拒绝,以后又使用提案编号3进行预提案,proposerB使用提案编号2进行提交被拒绝,使用提案编号4进行预提案。。。。。。
以上这种状况下,paxos算法出现了活锁,所以通常在实际应用中,会首先使用paxos算法选举出一个leader,而后由该leader做为proposer来进行提案的二阶段提交,这样就消除了产生上述活锁的状况。而且由于paxos算法只能肯定一个值的最终取值,每每不适用于实际应用中。经过首先选举leader的方式能够很好地控制实现一系列值的最终取值,也能保证全部proposer提出的提案编号不能重复这个前提条件。
参考资料: 一、Paxos Made Simple 二、《从Paxos到Zookeeper分布式一致性原理与实践》