zoukankan      html  css  js  c++  java
  • 结合phxpaxos简单看下paxos

    一、paxos的基本假设

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

    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值。

    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值。

    而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.

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

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

    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());
    }

    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);
    }
    ……
    }

    而这个具体的增加,其中会判断提议值是否更大,它始终记录提议值最大的被接受提议值。是否是多数派则通过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());

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

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

    三、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);
    }
    ……
    }

  • 相关阅读:
    【转载】C/C++中extern关键字详解
    【转载】extern "C"的用法解析(原博主就是抄百度百科的,不如另外一篇好)
    lua Date和Time
    MySQL-Linux安装
    Hive-0.13安装
    MR案例:单表关联查询
    MR案例:小文件处理方案
    MR案例:链式ChainMapper
    MR案例:定制Partitioner
    MR案例:多文件输出MultipleOutputs
  • 原文地址:https://www.cnblogs.com/tsecer/p/10572314.html
Copyright © 2011-2022 走看看