什麼是實例?
Paxos的命名法有點不直觀。
- 的實例是選擇一個值的算法。
- 甲輪指提議者的階段1 +階段2的單次嘗試的節點可以具有多個輪在實例的Paxos的。在所有節點上,每個實例的round id是全局唯一的。這有時稱爲提案編號。
- 節點可能承擔多個角色;最顯着的是提議者和接受者。在我的答案中,我會假設每個節點都承擔這兩個角色。
- 階段1也被稱爲準備階段。
- 在階段1a,一個投標發送一個準備!(roundId)消息發送到接受者
- 在階段1b,與任一無極與接受者的答覆!(roundId,值)或PrepareNack!()
- 階段2也被稱爲接受階段。
- 在階段2a,一個投標發送接受!(roundId,值)消息發送到接受者
- 在階段2b,與接受者與任一接受回覆!(...)或AcceptNack!()
假設羣集分爲3個區域,每個區域包含3個節點(總數= 9個節點)。如果區域之間的通信中斷,會發生什麼?任何領導者都無法達到法定人數(即5)。
Paxos要求您至少可以獲得一個法定人數(您的案例中有5個節點)。去你的解決方案的三個地區;這三個地區之間有兩個網絡分區是非常糟糕的消息。我還使用Paxos版本,可以將節點成員從一個實例更改爲下一個實例。這對於分區和節點故障很有用。
Paxos不會進入無限循環嗎?
由於多個節點可以跳躍式準備階段,所以Paxos的幼稚實現不能保證終止。有兩種方法可以解決這個問題。一種是在開始新的Prepare階段之前進行隨機退避。二是所有請求路由到指定的領導者,充當提議者
在階段1b(前導由的Paxos情況下選擇還請參見多的Paxos。):「如果該提議數N比任何以前的提案都大,那麼每個>> Acceptor都承諾不接受小於N的提議,並且將它最後接受的值發送給Proposer。
'接受的最後一個值'是什麼?提案人是否有任何以前的提案編號?
當節點收到Accept!(roundId,value)消息,它沒有承諾不接受該值(由於Prepare!(higherRoundId)消息),它存儲值和roundId(我將它們稱爲acceptedValue
和acceptedRoundId
)。由於隨後的Accept!(...)消息,它可能會寫入這些消息。
當節點從Proposer收到Prepare!(roundId)消息時,它存儲roundId,如promiseRoundId = max(roundId, promiseRoundId)
。然後它將Promise!(acceptedRoundId, acceptedValue)
發回給Proposer。注意:如果一個節點沒有收到Accept!(...)消息,它將以Promise!(null, null)
回覆。
在階段1a:其中一個包括與Prepare消息達成一致的值還是推遲到Accept!信息?或者它確實很重要?
有沒有必要發送它。我不。
在階段2a:'如果任何接受者已經接受了一個值,領導者必須選擇一個具有最大提案編號N'的值。
這裏有什麼價值?這是提案號碼嗎?我不相信,但這句話不清楚。
該值是算法達成共識的實際數據。我將對此進行更改
要啓動接受階段,Proposer必須根據Prepare階段的結果選擇要接受的值。如果任何接受者回答了Promise(roundId,value),則Proposer必須使用與最高roundId相關的值。否則,Proposer只收到Promise(null,null),並可能選擇任何值發送給接受者。
注意:此處的提議編號與roundId是相同的。
在階段2a:'否則,Proposer可以自由選擇任何值。這是什麼意思?什麼值?對於提案號碼?
這是您希望達成共識的價值。這通常是跨分佈式系統的狀態變化,可能是由客戶端請求觸發的。
Paxos似乎依賴於增加的N值(提案編號)的工作?它是否正確?
維基百科條目沒有討論節點在開始參與Paxos之前應該設置的初始值。這些是什麼?
回合IDS(又名建議數)應越來越大,並在所有節點必須是每個實例是唯一的。 Paxos論文假設你可以做到這一點,因爲它是微不足道的。下面是一個在所有節點上產生相同結果的方案:
- 假設有M個節點參與Paxos實例。
- 按照字典順序排列所有節點。 index [node]是此排序列表中節點的索引。
roundId = i*M + index[node]
其中i是第i個回合該節點正在啓動(即我每個節點每個paxos實例都是唯一的,並且是單調遞增的)。
或者僞代碼(這顯然是缺乏的幾個主要的優化):
define runPaxos(allNodesThisPaxosInstance, myValue) {
allNodesThisPaxosInstance.sort()
offset = allNodesThisPaxosInstance.indexOf(thisNode)
for (i = 0; true; i++) {
roundId = offset + i * allNodesThisPaxosInstance.size()
prepareResult = doPreparePhase(roundId)
if (!prepareResult.shouldContinue?)
return
if (prepareResult.hasAnyValue?)
chosenValue = prepareResult.valueWithHighestRoundId
else
chosenValue = myValue
acceptResult = doAcceptPhase(roundId, chosenValue)
if (!acceptResult.shouldContinue?)
return
}
}
我爲您創建了標籤。 – Anomie 2011-05-01 19:56:37
謝謝,我也更新了維基百科條目。 – JVerstry 2011-05-01 21:54:27
順便說一句,如果你感到無聊,你可以檢查[可能使用你的新標籤的其他問題](http://stackoverflow.com/search?q=paxos)。 – Anomie 2011-05-01 23:50:14