インスタンスとは何ですか?
Paxosの命名法は少し直感的ではありません。
- インスタンスは、 1つの値を選択するためのアルゴリズムです。
- ラウンドとは、提案者がフェーズ1+フェーズ2を1回試行することを指します。ノードはPaxosのインスタンスで複数のラウンドを持つことができます。ラウンドIDは、すべてのノードでインスタンスごとにグローバルに一意です。これは、提案番号と呼ばれることもあります。
- ノードはいくつかの役割を担う場合があります。最も顕著なのは提案者と承認者です。私の答えでは、各ノードが両方の役割を担うと仮定します。
- フェーズ1は、準備フェーズとも呼ばれます。
- フェーズ1aでは、提案者は準備!(roundId)メッセージをアクセプターに送信します
- フェーズ1bでは、アクセプターはPromise!(roundId、value)またはPrepareNack!()のいずれかで応答します。
- フェーズ2は、承認フェーズとも呼ばれます。
- フェーズ2aでは、提案者はAccept!(roundId、value)メッセージをAcceptorsに送信します
- フェーズ2bでは、アクセプターはAccepted!(...)またはAcceptNack!()のいずれかで応答します。
クラスターが3つの領域に分割され、それぞれに3つのノードが含まれていると仮定します(合計= 9ノード)。リージョン間の通信が切断された場合はどうなりますか?リーダーがクォーラム(5)に到達する方法はありません。
Paxosでは、少なくともクォーラム(この場合は5ノード)を取得できる必要があります。3つの地域のソリューションを使用してください。3つのリージョン間に2つのネットワークパーティションがあることは非常に悪いニュースです。また、あるインスタンスから次のインスタンスにノードメンバーシップを変更できるバージョンのPaxosを使用しています。これは、パーティションとノードの障害に役立ちます。
Paxosは無限ループに入りませんか?
Paxosのナイーブな実装は、複数のノードが準備フェーズを飛び越える可能性があるため、終了することが保証されていません。これを回避するには2つの方法があります。1つは、新しい準備フェーズを開始する前にランダムなバックオフを行うことです。2つ目は、提案者として機能する指定されたリーダーにすべてのリクエストをルーティングすることです(リーダーはPaxosインスタンスによって選択されます。Multi-paxosも参照してください)
フェーズ1b:'プロポーザル番号Nが以前のプロポーザルよりも大きい場合、各>>アクセプターはN未満のプロポーザルを受け入れないことを約束し、>>このインスタンスに対して最後に受け入れた値をプロポーザーに送信します'。
「それが受け入れた最後の値」とは何ですか?提案者からの以前の提案番号ですか?
ノードが提案者からAccept!(roundId、value)メッセージを受信し、(Prepare!(higherRoundId)メッセージのために)値を受け入れないことを約束していない場合、ノードは値とroundIdを格納します(acceptedValue
それらを呼び出してacceptedRoundId
)。後続のAccept!(...)メッセージが原因で、これらが上書きされる可能性があります。
ノードがプロポーザーからPrepare!(roundId)メッセージを受信すると、ノードはroundIdをとして格納しpromiseRoundId = max(roundId, promiseRoundId)
ます。次にPromise!(acceptedRoundId, acceptedValue)
、提案者に送り返します。注意:ノードがAccept!(...)メッセージを受信していない場合、ノードは。で応答しPromise!(null, null)
ます。
フェーズ1aの場合:準備メッセージに同意するための値が含まれていますか、それともこれは承認に延期されていますか?メッセージ?それとも重要ですか?
送信する必要はありません。私はしません。
フェーズ2a:'アクセプターのいずれかがすでに値を受け入れている場合、リーダーは最大提案番号Nの値を選択する必要があります'。
ここでの価値は何ですか?提案番号ですか?私は信じていませんが、このフレーズは不明確です。
値は、アルゴリズムがコンセンサスに達している実際のデータです。これを言い換えます
承認フェーズを開始するには、提案者は準備フェーズの結果に応じて承認する値を選択する必要があります。アクセプターがPromise(roundId、value)で応答した場合、プロポーザーは最も高いroundIdに関連付けられた値を使用する必要があります。それ以外の場合、プロポーザーはPromise(null、null)のみを受信し、アクセプターに送信する任意の値を選択できます。
注意:ここでの提案番号はroundIdと同じです。
フェーズ2a:'それ以外の場合、提案者は任意の値を自由に選択できます'。これは何を意味するのでしょうか?何の価値?提案番号は?
これは、コンセンサスを得たい値です。これは通常、分散システム全体の状態変化であり、おそらくクライアント要求によってトリガーされます。
Paxosは、N(提案番号)の値の増加に依存して機能しているようですか?これは正しいです?
ウィキペディアのエントリでは、Paxosへの参加を開始する前にノードが設定する必要のある初期値については説明していません。これは何?
ラウンドID(別名プロポーザル番号)は増加している必要があり、すべてのノードでインスタンスごとに一意である必要があります。Paxosの論文では、達成するのは簡単なので、これを実行できると想定しています。すべてのノードで同じ結果を生成する1つのスキームを次に示します。
- Paxosのインスタンスに参加しているMノードがあるとします。
- すべてのノードを辞書式に並べ替えます。index [node]は、このソートされたリスト内のノードのインデックスです。
roundId = i*M + index[node]
ここで、iはこのノードが開始する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
}
}