结合phxpaxos简单看下paxos

1、paxos的基本假设

关于paxos最为简洁的描述在这里,做者的大体思路是根据结论来找到条件来知足这个条件,而这个限制是逐步收紧,而且在各个参与者之间逐步进行职责转移和派发。node

P2a. If a proposal with value v is chosen, then every higher-numbered proposal accepted by any acceptor has value v.
其中最为关键的就是从一个抽象的限制P2b到一个能够实际具体操做P2c的转换,在此次限制(职责)转换的过程当中,首先把P2a是到P2b的限制比较简单天然,可是它是第一次把限制从acceptor转移到了proposer:由于若是全部的更高提议被提议时都是chosen值,那么接受者确定接受的也都是chosen值。web

P2b. If a proposal with value v is chosen, then every higher-numbered proposal issued by any proposer has value v.
把限制转移到提议者以后,这个限制仍是一个比较抽象的限制,或者说不是一个能够具体操做的限制,由于要求提议者须要知道chosen值,而这个chosen值如何肯定则并无具体操做流程。此时就是须要把限制具体细化到能够操做的级别。这个时候须要从P2b到P2c的细化:
假设第m次提议的v值被肯定,也就意味着存在一个多数派C,这个多数派accept了这个值,此时的C是固定的acceptor集合。考察这个集合C,因为提议值大于m的提议都是已经chosen的v值,因此它们在以后一直都是肯定值v。
对于一个提议者,它若是选择任意一个acceptor多数派集合S,这个S集合和C之间确定有至少一个相同元素,而且这个元素已经接受了提议值v,而且提议号在m到n-1之间。
P2c. For any v and n, if a proposal with value v and number n is issued,
then there is a set S consisting of a majority of acceptors such that
either (a) no acceptor in S has accepted any proposal numbered less
than n, or (b) v is the value of the highest-numbered proposal among
all proposals numbered less than n accepted by the acceptors in S.
对于这个多数派集合,那么提议号小于m的被chosen值(若是存在的话)是未被接受的,而大于等于m的提议号的值都是相同的chosen值v。因此取这个集合中全部已经接受的提议中提议号最大的一个,它必定是chosen值。promise

而P2b这个命题把限制从acceptor转移到了proposer,当acceptor的一个值被接受以后,proposer提议的每一个值都应该是v。这里第一次把皮球从acceptor踢到了proposer。
因为P2c是对提议者做了限制,当一个提议被chosen以后,全部提议的值都是以前的提议值。这个知足P2c便可知足P2b的理解仍是比较简单的:由于肯定以后,全部的提议值都是该值,而接受者只会接收提议值,因此接收值必定是v。
可是对于提议者来讲,如何当一个值被chosen以后,它的提议值必定是这个肯定值呢?这里首先要证实,当第m次提议的v值被肯定以后,咱们要证实如何保证以后每次提议n>m的提议值都有值v。
根据假设,若是m次提议的v被chosen,则说明有一个多数acceptor集合,这个集合中的全部元素接受值都是以v,这个多数集合是肯定为C(这个集合是致使v被接受的acceptor集合)。如今固定考察这个集合C中的每一个acceptor:因为以后的每次大于m的提议都具备相同的值v,因此它们收到m……n-1次提议都有相同的v值。在第n次提议前时,集合中这些元素接受是提议多是m……n-1次的任意次提议,而且这些提议有相同的值v。
对于任意一个包含了多数派的集合S来讲,它必定包含有一个C中的至少一个元素。这样对于任意一个多数派集合S,对于n提议的v值,其中任意一个元素都没有接受过编号小于n的提议,或者v是全部小于提议n的提议中最大值的。
当有这个集合的状况下,可能集合中不包含任何已经接受的提议,
For any v and n, if a proposal with value v and number n is issued,
then there is a set S consisting of a majority of acceptors such that
either (a) no acceptor in S has accepted any proposal numbered less
than n, or (b) v is the value of the highest-numbered proposal among
all proposals numbered less than n accepted by the acceptors in S.less

2、phxpaxos中prepare阶段对于多数派的处理函数

在prepare的回包中,经过
m_oMsgCounter.AddPromiseOrAccept(oPaxosMsg.nodeid());
m_oProposerState.AddPreAcceptValue(oBallot, oPaxosMsg.value());
更新可能已经被接受的值
phxpaxos-master\src\algorithm\proposer.cpp
void Proposer :: OnPrepareReply(const PaxosMsg & oPaxosMsg)
{
……
m_oMsgCounter.AddReceive(oPaxosMsg.nodeid());spa

if (oPaxosMsg.rejectbypromiseid() == 0)
{
BallotNumber oBallot(oPaxosMsg.preacceptid(), oPaxosMsg.preacceptnodeid());
PLGDebug("[Promise] PreAcceptedID %lu PreAcceptedNodeID %lu ValueSize %zu",
oPaxosMsg.preacceptid(), oPaxosMsg.preacceptnodeid(), oPaxosMsg.value().size());
m_oMsgCounter.AddPromiseOrAccept(oPaxosMsg.nodeid());
m_oProposerState.AddPreAcceptValue(oBallot, oPaxosMsg.value());
}
else
{
PLGDebug("[Reject] RejectByPromiseID %lu", oPaxosMsg.rejectbypromiseid());
m_oMsgCounter.AddReject(oPaxosMsg.nodeid());
m_bWasRejectBySomeone = true;
m_oProposerState.SetOtherProposalID(oPaxosMsg.rejectbypromiseid());
}.net

if (m_oMsgCounter.IsPassedOnThisRound())
{
int iUseTimeMs = m_oTimeStat.Point();
BP->GetProposerBP()->PreparePass(iUseTimeMs);
PLGImp("[Pass] start accept, usetime %dms", iUseTimeMs);
m_bCanSkipPrepare = true;
Accept();
}
else if (m_oMsgCounter.IsRejectedOnThisRound()
|| m_oMsgCounter.IsAllReceiveOnThisRound())
{
BP->GetProposerBP()->PrepareNotPass();
PLGImp("[Not Pass] wait 30ms and restart prepare");
AddPrepareTimer(OtherUtils::FastRand() % 30 + 10);
}
……
}rest

而这个具体的增长,其中会判断提议值是否更大,它始终记录提议值最大的被接受提议值。是不是多数派则经过IsPassedOnThisRound函数肯定
void ProposerState :: AddPreAcceptValue(
const BallotNumber & oOtherPreAcceptBallot,
const std::string & sOtherPreAcceptValue)
{
PLGDebug("OtherPreAcceptID %lu OtherPreAcceptNodeID %lu HighestOtherPreAcceptID %lu "
"HighestOtherPreAcceptNodeID %lu OtherPreAcceptValue %zu",
oOtherPreAcceptBallot.m_llProposalID, oOtherPreAcceptBallot.m_llNodeID,
m_oHighestOtherPreAcceptBallot.m_llProposalID, m_oHighestOtherPreAcceptBallot.m_llNodeID,
sOtherPreAcceptValue.size());ip

if (oOtherPreAcceptBallot.isnull())
{
return;
}

if (oOtherPreAcceptBallot > m_oHighestOtherPreAcceptBallot)
{
m_oHighestOtherPreAcceptBallot = oOtherPreAcceptBallot;
m_sValue = sOtherPreAcceptValue;
}
}get

3、phxpaxos中对于值被chosen的处理

这个地方比较奇怪的是值是否被chosen是在proposer逻辑中完成的,而learner的功能相对比较少,它并无进行确认数量的计数。void Proposer :: OnAcceptReply(const PaxosMsg & oPaxosMsg){…… if (m_oMsgCounter.IsPassedOnThisRound()) { int iUseTimeMs = m_oTimeStat.Point(); BP->GetProposerBP()->AcceptPass(iUseTimeMs); PLGImp("[Pass] Start send learn, usetime %dms", iUseTimeMs); ExitAccept(); m_poLearner->ProposerSendSuccess(GetInstanceID(), m_oProposerState.GetProposalID()); } else if (m_oMsgCounter.IsRejectedOnThisRound() || m_oMsgCounter.IsAllReceiveOnThisRound()) { BP->GetProposerBP()->AcceptNotPass(); PLGImp("[Not pass] wait 30ms and Restart prepare"); AddAcceptTimer(OtherUtils::FastRand() % 30 + 10); }……}

相关文章
相关标签/搜索