複製コマンド
すべてのロック状態変更は、以下のいずれかのコマンドとして複製され、 AppendEntriesのログエントリとして運ばれ、過半数の コミット後にすべてのノードで同じ順序で適用されます。
コマンド(リーダーが提案)
| コマンド | フィールド | 意味 |
|---|---|---|
Grant | key, lease_ms | キーを獲得。コマンドにトークンは含まれません — 各ノードのステートマシンが適用時に決定的に割り当てるため、すべてのノードが同じトークンを計算する |
Release | key | キーを解放 |
Expire | key, token | リーダー主導のlease失効。tokenが一致した場合のみ削除される — 遅延または重複した失効が、その間に新しく発行されたロックを削除することはない(冪等) |
適用結果(ステートマシン → リーダー)
| 結果 | 意味 |
|---|---|
Granted { token } | 獲得成功 — 発行されたフェンシングトークン |
GrantRejected | すでに保持されているキーにGrantが届いた(防御的なもので、通常のフローでは発生しない) |
Released | 解放済み |
NotFound | 解放対象のキーが存在しなかった |
Expired { existed } | 失効処理を実行 — 実際に削除されたかどうかをexistedが示す |
Noop | 何も起きなかった |
各ノードはleaseの残り時間を自身のローカル時計で追跡しますが、実際の削除は常に コミットされたExpireコマンドを通じてのみ行われます — そのため、ノード間の時計の ずれがロック状態を分裂させることは決してありません。クライアントが応答を受け取る前に 切断した場合、リーダーは発行直後に自らその分のReleaseを提案し、幽霊ロックを すぐに片付けます。
フロー — Expireの複製
リーダー
フォロワー1
フォロワー2
ローカル時計でlease失効を検知
AppendEntries · Expire (key, token)
AppendEntries · Expire (key, token)
OK
過半数コミット → 全ノードが同じ順序で適用
トークン不一致 → 無視 — 新しく発行されたロックを保護
合意形成RPC(Raft)
失効すらも、リーダーの提案 → 過半数コミットを経る、ただの別のコマンドに過ぎません。 tokenのチェックのおかげで、コミットが遅れている間に同じキーが再獲得されていても、 遅れて適用されたExpireが新しいロックを削除することはありません。
用語
- ステートマシン — コミットされたコマンドを順番に適用して現在の状態(ここでは ロックテーブル)を作り出す部分。すべてのノードが同じコマンドを同じ順序で適用するため、 常に同じ状態に収束します。
- コミット — 過半数のノードが記録した時点でコマンドが到達する「確定」状態。 コミットされたコマンドだけがステートマシンに適用されます。
- 冪等 — 同じコマンドを誤って2回適用しても結果が変わらない性質。