menuTicketing

動作原理


ロックの取得と返却

クライアントがキーを取得(A)すると、サーバーは次の3つのうちいずれかで応答します。

キー状態サーバー動作応答
未登録即座に登録(失効 = now + lease)、トークン発行A + token + key
登録済み + 失効済み更新(now + lease)、新しいトークンを発行A + token + key
登録済み + 有効(占有中)待機列に登録、応答を保留返却/失効時にAwait超過時にT
  • 返却はFIFOで公平に処理されます。 保有者が返却(R)すると、待機列の先頭に直接引き渡されます — 再競合なしに新しいトークンとともに即座に渡ります。
  • leaseは安全網です。 クライアントが停止したり返却を忘れたりしても、leaseの時間が経過すればサーバーが自動的に キーを回収して次の待機者に渡すことができます。そのため、通常の返却フローとは別に、常にleaseを 余裕を持たせつつ、停止時にも長く縛られすぎない値に設定するのがよいでしょう。
  • waitは取得待機の上限です。 0なら無限待機、それ以外はその時間(秒)内に受け取れなければサーバーが 諦めてT(タイムアウト)で応答します — 付与なしで終わるため、ロックが漏れることはありません。

フェンシングトークン

A応答に含まれるtokenそのgrantの単調増加するu64です。取得のたびに以前のどのトークンよりも大きい 値が発行されます。フェイルオーバーが発生しても、新しくアクティブになったノードはレプリケーションで受け取った最大トークンより大きい 値から続けます(承継) — そのため、クラスター全体を通してもトークンは増加し続けます。

保護対象のリソース(口座、ファイル、注文など)が「今持っているトークンが最後に見たトークンより大きいか」だけを検証すれば、 lease失効後に遅れて動き出したクライアントが、すでに無効化された低いトークンでアクセスしようとするのを拒否できます。 これにより、ロックサーバーが常に完全に一貫していなくても安全性を保つことができます。

クライアントの動作

公式クライアントは共通して次のように動作します(言語ごとの詳細なAPIはライブラリを参照)。

  • アドレスごとに永続接続を1つ維持し、バックグラウンドで管理します。アドレスを1つだけ与えた場合は内部的に 同じノードへ接続を2つ維持し、そのうち一方が一時的に切断してもサービスが途切れないようにします。
  • ラウンドロビンで接続を選びます。 切断されたノードは自動的に除外され、3秒間隔でバックグラウンドで 再接続を試みます。
  • リクエストはパイプライン化されます。 応答を待たずに次のリクエストを送ることができ、応答の順序がリクエストの順序と 異なっても構いません — クライアントはエコーされた(op, キー)の組み合わせでどのリクエストへの応答かを区別します。同じ (op, キー)の組み合わせのリクエストが複数ある場合は、送信した順序でマッチングされます。
  • 取得試行中に接続が切断されると次の接続へ自動的に切り替えます。登録された接続数だけ試行しても使える 接続がなければ、そこで初めてエラーとして通知します。
  • 返却は5秒間、200ms間隔で再試行します — 返却の瞬間にたまたま接続が切れていても、ロックがサーバーに 残り続けないように(最終的にはleaseが回収しますが、その前に他の待機者へより早く渡すためです)。

クラスター — 優先順位ベースの無停止

  • peersリストの順序が昇格の優先順位です(先頭が最優先)。生存しているノードのうち優先順位が最も高い 1台がアクティブ、残りはその状態をリアルタイムでレプリケーションを受け取るスタンバイになります。
  • クライアントのリクエストはアクティブのみが処理します。スタンバイに接続したクライアントはアクティブのアドレスへ案内(M)され、 そちらへ移動します。
  • アクティブの障害/再起動 → スタンバイが昇格して引き継ぎます。
  • graceful終了Ctrl+C)時には、アクティブが後継に先に昇格を渡し(ハンドオフ)た後にクライアントを リダイレクトすることで、アクティブ不在の期間を最小化します。
  • 自動デモーション: ネットワークパーティションなどにより2つのノードが同時にアクティブになった場合、優先順位が低い 方が相手を検知して自らスタンバイへ退きます(恒久的なスプリットブレインを防止)。

この昇格方式はクォーラム(過半数投票)ベースではありません。 そのため奇数/偶数台数は重要ではなく、1台でも 生存していればサービスが維持されます

サーバー台数無停止同時障害許容備考
1台最も高速。再起動時に短い瞬断が発生
2台1台無停止の最小構成。 ほとんどの場合これで十分
3台2台1台点検中でも冗長性を維持
4台以上N−1台伝播コストが増えるだけ — 推奨しない

整合性について知っておくべきこと

優先順位ベースの昇格は合意ではないため、ネットワークパーティションの瞬間には両方が一時的に同時にアクティブになる 可能性があり、非同期レプリケーションの特性上フェイルオーバーの瞬間に一部のgrantが失われる可能性があります。つまりフェイルオーバー/パーティション区間では 相互排他が100%保証されるわけではありません。 強い保証が必要な場合は、先に説明したフェンシングトークンを保護対象の リソースが検証するように実装してください — 古い(小さい)トークンを拒否すれば、ロックサーバーが完全に一貫していなくても 安全です。