分散システムにおけるTimeouts、Retries、Idempotencyの扱い方
(infoq.com)Sam Newmanは、分散システムで必ず理解すべき3つの中核概念として Timeouts(タイムアウト)、Retries(リトライ)、Idempotency(冪等性) を強調した。
PaxosやRaftのような複雑な分散アルゴリズムよりも、まずはこれらの基本概念を正確に扱うことが重要だと述べた。
分散システムの3つの基本前提
- 情報は即座には伝わらない。
- 相手のシステムが応答しないことがある。
- リソースは有限である。
この3つが、分散システムにおけるあらゆる複雑さを生み出す根本原因である。
Timeouts(タイムアウト)
リクエストが一定時間内に完了しない場合は、中断させる必要がある。
リソースを長時間占有すると、システムの過負荷やユーザーの不便につながる可能性がある。
Newmanは、「タイムアウトとは、単一のリクエストの成功よりもシステム全体の健全性を優先することだ」と説明した。
重要ポイント
- 平均実行時間とユーザーの期待値を把握する
- 設定値はコード修正なしで柔軟に変更できる必要がある
Retries(リトライ)
過度なリトライは、システムに対する 自傷的なDoS攻撃 になりうる。
リトライは必要だが、クライアント・サーバー側での制限とネットワークジッター(jitter) をあわせて考慮しなければならない。
Newmanは、ジッターの追加は有効だが、指数バックオフはかえってシステムの負担になる場合がある と警告した。
Idempotency(冪等性)
リクエストを何度送っても結果は同じでなければならない。
これは主にサーバー側の責任であり、リトライを安全に行うための前提条件 である。
実際のシナリオ
- リクエストがサーバーに到達しなかった場合: 何も起きない
- サーバーが処理したが応答が途切れた場合: 変更は行われたがクライアントには分からない → 冪等性が必要
実装方法
- リクエストIDの使用: クライアントが重複したリクエストであることを判別できるよう識別子を付与する
- Fingerprint方式: リクエスト本文のハッシュ値などを基準に重複を判定する(時間情報は避ける)
結論
「同じ行動を繰り返しながら違う結果を期待するのは狂気だ」という言葉を引用して話を始めたが、
Newmanは、分散システムでは リトライがむしろ合理的 でありうると述べた。
ただし、リトライは必ず安全に行われなければならず、そのためにはタイムアウトと冪等性をあわせて設計する必要がある と強調した。
1件のコメント
サーキットブレーカー〜