PhxPaxos源码分析之(4)Learner篇

本文深入解析PhxPaxos中的Learner学习过程,涉及TCP的三次握手和ACK机制的模拟。通过初始化、协商和数据传输三个阶段,详细阐述如何在数据差距未超过阈值时进行数据追加。该机制为理解分布式一致性提供了参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更多 blog 见: https://joeylichang.github.io/

本篇文章介绍一下PhxPaxos-Learn的过程,Learn主要的功能是追数据,追数据分为两部分,如果数据差距过大进行批量追加即ckpt(下片文章介绍),本篇文章主要介绍差距没有超过设定的闸值时,追条数据追加的过程。

PhxPaxos在追数据的过程模拟了TCP的三次握手和ACK机制,下面看一下简单的示意图:

有了上面主要流程的示意图,下面看一下时序图:

接下来分三个阶段进行介绍:

  • 初始化阶段

Reset_AskforLearn_Noop主要是保证周期性的调用AskforLearn,AskforLearn向其他节点发送PaxosLearner_AskforLearn消息,进行起一次握手,没设么重要内容,下面直接看握手过程

  • 协商阶段(三次握手)

第一次握手:

void Learner :: AskforLearn()
{
    BP->GetLearnerBP()->AskforLearn();

    PLGHead("START");

    PaxosMsg oPaxosMsg;

    oPaxosMsg.set_instanceid(GetInstanceID());
    oPaxosMsg.set_nodeid(m_poConfig->GetMyNodeID());
    oPaxosMsg.set_msgtype(MsgType_PaxosLearner_AskforLearn);

    if (m_poConfig->IsIMFollower())
    {
        //this is not proposal nodeid, just use this val to bring followto nodeid info.
        oPaxosMsg.set_proposalnodeid(m_poConfig->GetFollowToNodeID());
    }

    PLGHead("END InstanceID %lu MyNodeID %lu", oPaxosMsg.instanceid(), oPaxosMsg.nodeid());

    // 这里有一点不是很理解,为什么tmp节点用udp,其他节点用tcp
    // 可能是不想tmp节点的数据,与其他工作节点的数据一起通过一个线程发送,加快性能?
    BroadcastMessage(oPaxosMsg, BroadcastMessage_Type_RunSelf_None, Message_SendType_TCP);
    BroadcastMessageToTempNode(oPaxosMsg, Message_SendType_UDP);
}

第一次握手只是向其他节点发起了MsgType_PaxosLearner_AskforLearn请求。

第二次握手:

下面看一下,其他节点对MsgType_PaxosLearner_AskforLearn消息的处理:

void Learner :: OnAskforLearn(const PaxosMsg & oPaxosMsg)
{
    BP->GetLearnerBP()->OnAskforLearn();
    
    PLGHead("START Msg.InstanceID %lu Now.InstanceID %lu Msg.from_nodeid %lu MinChosenInstanceID %lu", 
            oPaxosMsg.instanceid(), GetInstanceID(), oPaxosMsg.nodeid(),
            m_poCheckpointMgr->GetMinChosenInstanceID());
    
    // 更新当前节点视角下的paxos-group信息
    SetSeenInstanceID(oPaxosMsg.instanceid(), oPaxosMsg.nodeid());

    // 注意:在learn请求中proposalnodeid 不为0表示,发送请求的节点是fllower
    if (oPaxosMsg.proposalnodeid() == m_poConfig->GetMyNodeID())
    {
        //Found a node follow me.
        PLImp("Found a node %lu follow me.", oPaxosMsg.nodeid());
        m_poConfig->AddFollowerNode(oPaxosMsg.nodeid());
    }
    
    // 表示对端节点数据比当前节点新
    if (oPaxosMsg.instanceid() >= GetInstanceID())
    {
        return;
    }

    // 节点数据落后过多,走ckpt逻辑(下篇文章介绍)
    if (oPaxosMsg.instanceid() >= m_poCheckpointMgr->GetMinChosenInstanceID())
    {
        if (!m_oLearnerSender.Prepare(oPaxosMsg.instanceid(), oPaxosMsg.nodeid()))
        {
            BP->GetLearnerBP()->OnAskforLearnGetLockFail();

            PLGErr("LearnerSender working for others.");

            if (oPaxosMsg.instanceid() == (GetInstanceID() - 1))
            {
                PLGImp("InstanceID only difference one, just send this
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值