phxpaxos的checkpoint從哪一個server同步

1、狀態同步

在工程應用環境中,一個新啓動的節點須要可以從其它節點進行狀態同步,或者叫作實例的對齊(Learn)。該節說明了C的數據能夠從B學習,可是在一個具體的環境中,當一個節點須要學習時,它具體應該如何選擇,以哪個爲準,這裏並無後詳細說明清楚,這個就須要結合代碼來看一下。node

2、學習定時器

在實例類Instance啓動的時候,它首先啓動定時器,定時嘗試向同組中的全部機器學習:
int Instance :: Init()
{
……
m_oLearner.Reset_AskforLearn_Noop();機器學習

PLGImp("OK");函數

return 0;
}oop

void Learner :: AskforLearn_Noop(const bool bIsStart)
{
Reset_AskforLearn_Noop();學習

m_bIsIMLearning = false;ui

m_poCheckpointMgr->ExitCheckpointMode();spa

AskforLearn();

if (bIsStart)
{
AskforLearn();
}
}對象

3、定時器到來時執行的動做

向系統廣播 MsgType_PaxosLearner_AskforLearn 消息,全部收到該消息的節點經過MsgType_PaxosLearner_SendNowInstanceID協議返回本身本地最大的實例號。
void Learner :: AskforCheckpoint(const nodeid_t iSendNodeID)
{
PLGHead("START");get

int ret = m_poCheckpointMgr->PrepareForAskforCheckpoint(iSendNodeID);
if (ret != 0)
{
return;
}cmd

PaxosMsg oPaxosMsg;

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

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

SendMessage(iSendNodeID, oPaxosMsg);
}

leaner執行AskforCheckpoint函數準備學習,可是在PrepareForAskforCheckpoint函數中會判斷當前是否已經收到半數以上的節點回復,而且經過m_bInAskforCheckpointMode標誌位進入checkpointmode
int CheckpointMgr :: PrepareForAskforCheckpoint(const nodeid_t iSendNodeID)
{
if (m_setNeedAsk.find(iSendNodeID) == m_setNeedAsk.end())
{
m_setNeedAsk.insert(iSendNodeID);
}

if (m_llLastAskforCheckpointTime == 0)
{
m_llLastAskforCheckpointTime = Time::GetSteadyClockMS();
}

uint64_t llNowTime = Time::GetSteadyClockMS();
if (llNowTime > m_llLastAskforCheckpointTime + 60000)
{
PLGImp("no majority reply, just ask for checkpoint");
}
else
{

if ((int)m_setNeedAsk.size() < m_poConfig->GetMajorityCount())
{
PLGImp("Need more other tell us need to askforcheckpoint");
return -2;
}
}

m_llLastAskforCheckpointTime = 0;
m_bInAskforCheckpointMode = true;

return 0;
}

4、有其它節點的MsgType_PaxosLearner_SendNowInstanceID包如何處理


從代碼上看,當開始學習以後,就是一個專心致志的過程,那最開廣播的消息,其它節點回包也是知足PrepareForAskforCheckpoint函數的半數以上條件,那會不會它們都會被同步過來呢?

void Instance :: OnReceive(const std::string & sBuffer)
{
BP->GetInstanceBP()->OnReceive();
……

int iCmd = oHeader.cmdid();

if (iCmd == MsgCmd_PaxosMsg)
{
if (m_oCheckpointMgr.InAskforcheckpointMode())
{
PLGImp("in ask for checkpoint mode, ignord paxosmsg");
return;
}

……

OnReceivePaxosMsg(oPaxosMsg);
}
……
}
因爲發送學習checkpoint以後就經過m_bInAskforCheckpointMode進入了checkpoint模式,而MsgType_PaxosLearner_SendNowInstanceID回包是一個paxos類型的回包,因此要通過if (m_oCheckpointMgr.InAskforcheckpointMode())的過濾,而且當前處於checkpoint學習模式時,這個消息會被忽略。
const bool CheckpointMgr :: InAskforcheckpointMode() const
{
return m_bInAskforCheckpointMode;
}

5、總結

具體的學習對象是從第一個超過半數的節點學習。在CheckpointMgr :: PrepareForAskforCheckpoint函數中的m_setNeedAsk並無在學習以後清零,多是因爲checkpoint同步以後系統就會重啓,因此不須要清零吧。

相關文章
相關標籤/搜索