WelCome You 待つことの設計 — リトライ・バックオフ・サーキットブレーカー – LatentWorkflow 本文へスキップ
非同期と遅延

待つことの設計 — リトライ・バックオフ・サーキットブレーカー

LatentWorkflow 編集部 4分で読めます 2026.04.14
待つことの設計 — リトライ・バックオフ・サーキットブレーカー

要点

  • 一時的な失敗に対する再試行は有効だが、無秩序な再試行はかえって障害を悪化させる。
  • 指数バックオフとジッター(ばらつき)は、再試行が同時に殺到する事態を避ける定石である。
  • Michael Nygardの『Release It!』が広めたサーキットブレーカーは、壊れた相手への呼び出しを一時的に遮断する。
  • これらは「速く直す」道具ではなく、「悪化を防ぐ」ための割り切りの道具である。

——通信が失敗したら、もう一回試せばいいんですよね。何が難しいんですか。

一回試し直すだけなら簡単です。問題は、失敗しているのが自分だけじゃないときに起きる。ある依存先が一時的に重くなって、みんなが一斉に失敗する。そこで全員が同時に再試行したら、何が起きると思いますか。

——あ……ただでさえ重い相手に、さらに一斉に殺到する。

そのとおりです。良かれと思った再試行が、回復しかけた相手にとどめを刺す。これを「再試行の嵐」と呼びます。再試行は薬にも毒にもなる。

ばらつきを混ぜる

——どうすれば毒にならずに済むんですか。

まず、すぐに再試行しないこと。失敗するたびに待ち時間を倍々に伸ばす「指数バックオフ」を使います。1秒待って駄目なら2秒、次は4秒、というように。相手に回復の余地を与えるわけです。

——でも、全員が同じルールで倍にしていったら、結局また同時に再試行しませんか。

鋭い。だから、そこに「ジッター」——わざとばらつきを加えます。AWSのBuilders’ LibraryでMarc Brookerが論じているのは、まさにこの点です。待ち時間に乱数で揺らぎを入れ、再試行の時刻を散らす。全員が綺麗に揃って殺到する事態を、意図的に崩す。整然と並ぶことが、この場面では害になる。

呼び出しを止める判断

——それでも相手が完全に落ちていたら、再試行しても無駄ですよね。

ええ。落ちている相手に投げ続けるのは、待ち時間を浪費するだけでなく、自分のスレッドや接続を食いつぶして、自分まで巻き込まれる。ここで登場するのがサーキットブレーカーです。Michael Nygardが『Release It!』で広めた考え方で、電気のブレーカーが由来です。

——どういう動きをするんですか。

一定の割合で失敗が続いたら、ブレーカーを「開く」。つまり、しばらくその相手への呼び出しを即座に失敗させて、実際には投げない。相手に回復の時間を与えつつ、自分も無駄な待ちから解放される。そして時々、試しに一回だけ通してみて、回復していれば元に戻す。キューによる緩衝とも組み合わさって、過負荷の連鎖を断ち切ります。

悪化を防ぐという発想

——なんだか、どれも「直す」というより「これ以上ひどくしない」道具ですね。

本質を突いています。バックオフもジッターもサーキットブレーカーも、故障そのものを直すわけではない。一時的な失敗が、システム全体を巻き込む大障害へ広がるのを防ぐ。被害の封じ込めが目的です。テールレイテンシの議論と同じで、ここでも完璧な解はなく、悪化の速度を緩める割り切りがある。

——派手な解決策じゃないんですね。

派手ではありません。でも、障害は必ず起きるという前提に立つと、起きたあとにどう振る舞うかの設計こそが、運用の成熟度を分ける。失敗を避けることはできない。だが、失敗が連鎖する速さは、設計で遅くできる。背景で静かに働くこれらの仕組みは、いわばシステムの自制心です。うまく効いているとき、利用者は障害があったことにすら気づかない。気づかせないことが、いちばんの成果なんです。

出典

  1. Michael Nygard『Release It!』(サーキットブレーカーパターン)
  2. Marc Brooker「Timeouts, retries, and backoff with jitter」(Amazon Builders’ Library)

更新のお知らせ

見えない処理の記録を、月数回お届けします