phxpaxos的Proposer和Acceptor的流程

本文深入探讨了phxpaxos中Proposer和Acceptor的运作机制。通过详细阐述它们的交互流程,揭示了Paxos算法在分布式一致性中的应用。内容包括Proposer如何发起提案,Acceptor如何接收并选择提案,以及在冲突和一致性的解决策略。
摘要由CSDN通过智能技术生成
    在paxos算法中,主要包含了三个角色,proposer、accepter和learner。learner在paxos算法的论文中提及不是很详细,但是在phxpaxos实现是最为复杂的,之后独立一篇文章分析。
    在微信的文档中,通过推导,一步一步得出simple-paxos正式算法的流程,推导的过程可以反复看看原先的文档( Paxos理论介绍(1): 朴素Paxos算法理论推导与证明),理解透了收益非浅。
    这里主要分析phxpaxos的proposer和Acceptor代码实现算法的过程。
    先看看算法的主要过程,给出的一页PPT如下:

    在phxpaxos的代码中,整理出主要流程如下图,


    在图中,左边是propoer的流程,右边是accepter的流程。其实就是最简单的方式实现了文档中paxos算法的流程。这里按照代码的主要流程来进行一步步分析。
    首先,Propose的处理:

int Proposer :: NewValue(const std::string & sValue)
{
    BP->GetProposerBP()->NewProposal(sValue);

    if (m_oProposerState.GetValue().size() == 0)
    {
        m_oProposerState.SetValue(sValue);
    }

    m_iLastPrepareTimeoutMs = START_PREPARE_TIMEOUTMS;
    m_iLastAcceptTimeoutMs = START_ACCEPT_TIMEOUTMS;

    if (m_bCanSkipPrepare && !m_bWasRejectBySomeone)
    {
        //本节点之前已经执行过Prepare阶段,并且Prepare阶段或者Accept阶段没有被人拒绝过。。
        BP->GetProposerBP()->NewProposalSkipPrepare();
        PLGHead("skip prepare, directly start accept");
        Accept();
    }
    else
    {
        //这里被人拒绝过就增加proposalID,否则,沿用之前的proposalID
        //if not reject by someone, no need to increase ballot
        Prepare(m_bWasRejectBySomeone);
    }

    return 0;
}

    Propose的代码就是一些初始化并调用Prepare,这里有一个Multi-paxos的处理,就是有选择性的跳过Prepare,当前的proposer已经进行过了提交,并且在Prepare阶段或者Accept阶段没有被拒绝过,则跳过prepare阶段,具体的推导过程可以见( Paxos理论介绍(2): Multi-Paxos与Leader)。

接着进入Prepare,代码如下:

void Proposer :: Prepare(const bool bNeedNewBallot)
{
    PLGHead("START Now.InstanceID %lu MyNodeID %lu State.ProposalID %lu State.ValueLen %zu",
            GetInstanceID(), m_poConfig->GetMyNodeID(), m_oProposerState.GetProposalID(),
            m_oProposerState.GetValue().size());

    BP->GetProposerBP()->Prepare();
    m_oTimeStat.Point();

    //重置proposer的状态,退出Accept状态,进入Prepare状态
    ExitAccept();
    m_bIsPreparing = true;
    m_bCanSkipPrepare = false;
    m_bWasRejectBySomeone = false;

    //是否需要重新分配ballot,被人拒绝过就需要重新分配
    m_oProposerState.ResetHighestOtherPreAcceptBallot();
    if (bNeedNewBallot)
    {
        m_oProposerState.NewPrepare();
    }

    PaxosMsg oPaxosMsg;
    oPaxosMsg.set_msgtype(MsgType_PaxosPrepare);
    oPaxosMsg.set_instanceid(GetInstanceID());
    oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID());
    oPaxosMsg.set_proposalid(m_oProposerState.GetProposalID());

    m_oMsgCounter.StartNewRound();

    //设置Prepare超时定时器
    AddPrepareTimer();

    PLGHead("END OK");

    //发送Prepare消息。BroadcastMessage默认采用UDP方式发送,自己先执行,再发送给其他的节点
    BroadcastMessage(oPaxosMsg);
}

    Prepare主要判断是否需要重新分配ballot,并且增加一个Prepare定时器,超时重新进行Prepare。这里有一行代码:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值