当前位置: 首页 > 工具软件 > PhxPaxos > 使用案例 >

PhxPaxos之Master功能的使用

凤修筠
2023-12-01

PhxPaxos是腾讯公司微信后台团队自主研发的一套基于Paxos协议的多机状态拷贝类库。它以库函数的方式嵌入到开发者的代码当中, 使得一些单机状态服务可以扩展到多机器,从而获得强一致性的多副本以及自动容灾的特性。
该库的源代码请参考: https://github.com/Tencent/phxpaxos
本文不会对PhxPaxos库的具体实现进行详细的讲解,只是简单地介绍了该库中的master功能的使用。目前的计划是先学习该库基本的功能的使用,然后在慢慢研读源码。
在分布式系统中,经常会有这样的应用需求:多个节点中,在任意的时刻,只能存在一个master节点进行相应的操作,从而保证状态的一致性。目前也有各种的方案来实现该需求,比如说使用ZooKeeper来搭建分布式锁,或者使用分布式一致性算法(比如paxos,raft)来实现。PhxPaxos库的核心就是基于Paxos算法来实现的,然后在加上租约的机制从而实现master的选举功能。
要使用PhxPaxos库的话,首先要对源码进行编译,关于编译的流程可以参考github上面的说明。
下面是描述怎么在自己的代码中使用该库的master功能:

  1. 首先要先创建一个master的选举模块,代码如下:
class PhxElection
{
public:
    PhxElection(const phxpaxos::NodeInfo & oMyNode, const phxpaxos::NodeInfoList & vecNodeList);
    ~PhxElection();

    int RunPaxos();
    const phxpaxos::NodeInfo GetMaster();
    const bool IsIMMaster();

private:
    phxpaxos::NodeInfo m_oMyNode;
    phxpaxos::NodeInfoList m_vecNodeList;
    phxpaxos::Node * m_poPaxosNode;
};

其中,RunPaxos是运行paxos协议的函数,也就是实现选举master功能的函数,GetMaster接口是用来获取对应的master节点的,IsIMMaster是用来判断本节点是否master节点的。
2. 实现RunPaxos

int PhxElection :: RunPaxos()
{
    Options oOptions;

    int ret = MakeLogStoragePath(oOptions.sLogStoragePath);
    if (ret != 0)
    {   
        return ret;
    }   

    oOptions.iGroupCount = 1;  // 因为只是使用master功能,所以只需要一个实例

    oOptions.oMyNode = m_oMyNode;
    oOptions.vecNodeInfoList = m_vecNodeList;  // 节点列表,就是当前节点的信息,不少于3个,并且必须为基数个

    //open inside master state machine
    GroupSMInfo oSMInfo;
    oSMInfo.iGroupIdx = 0;
    oSMInfo.bIsUseMaster = true;   //  这里必须为true,说明是使用master功能

    oOptions.vecGroupSMInfoList.push_back(oSMInfo);

    ret = Node::RunNode(oOptions, m_poPaxosNode);
    if (ret != 0)
    {   
        printf("run paxos fail, ret %d\n", ret);
        return ret;
    }   

    //you can change master lease in real-time.
    m_poPaxosNode->SetMasterLease(0, 3000);  // 租约有效期,过期后需要重新选举

    printf("run paxos ok\n");
    return 0;
}

执行RunPaxos后,系统会起一个后台的线程用于执行master的选举,以及master的续租等功能(就是不断地续租,不断地运行paxos协议)

  1. GetMaster和IsIMMaster接口的实现
const phxpaxos::NodeInfo PhxElection :: GetMaster()
{
    //only one group, so groupidx is 0.
    return m_poPaxosNode->GetMaster(0);
}

const bool PhxElection :: IsIMMaster()
{
    return m_poPaxosNode->IsIMMaster(0);
}

根据上述的方式,就可以很简单的在项目中使用PhxPaxos库的master功能,实际项目中如果原本没有ZooKeeper服务也推荐直接使用该库的功能,避免重复造轮子。
后续会对PhxPaxos库中的master的具体实现原理进行讲解,然后再分析实际项目运用过程中会存在的哪些问题,比如系统的热启、冷启过程中master切换的问题的解决方案。

 类似资料: