処理が失敗したとき、そのまま送り直すと失敗した相手にみんなで一斉に押し寄せます。復旧しかけた相手を、また倒します。
待ち時間の決め方を4通り測りました。ばらつきを足すだけで、送り直しの山が301回から43回になります。しかも終わるのは速くなりました。
待ち時間の決め方を4通り走らせました。ばらつきを足した場合だけ、山が一桁変わります。
リトライ設計で待ち時間の決め方を変えると何が起きるのかを、実際に走らせて測りました。1000件を同時に送り、1回あたり30%の割合で失敗する状況です。
数えたのは送り直しが同じ100ミリ秒のうちに何回集中したかです。初回の1000件は数えていません。
const WAYS = [ ['すぐ送り直す', () => 0], ['固定で1秒待つ', () => 1000], ['倍々に増やす', (n) => 1000 * 2 ** (n - 1)], ['倍々+ばらつき', (n, r) => Math.floor(1000 * 2 ** (n - 1) * r())], ];
やり方 成功 送った回数 最後に成功するまで 送り直しが集中した最大数 すぐ送り直す 996件 1440回 0.0秒 440回 固定で1秒待つ 996件 1440回 4.0秒 301回 倍々に増やす 996件 1440回 15.0秒 301回 倍々+ばらつき 999件 1428回 12.8秒 43回
右端の列を見てください。ばらつきを足した場合だけ43回です。他は301回から440回でした。
3行目に注目してください。待ち時間を倍々に増やしても、山は301回のままです。
全員が同じ規則で待つので、また同じ瞬間に集まります。AWSも、待つだけでは呼び出しの塊が残り、誰も競合しない時間帯を作っただけになると書いています。
意外だったのは時間です。ばらつきを足したほうが15.0秒から12.8秒に短くなりました。
送った回数も1440回から1428回に減っています。成功件数は996件から999件に増えました。譲っている項目がありません。
待つだけでは301回。ばらつきを足すと43回。
The solution isn't to remove backoff. It's to add jitter.原文AWS Architecture Blog「Exponential Backoff And Jitter」 この内容の有効期限2027-02-18
送り直すかどうか、何回まで、どれだけ待つかを決めます。決めていないと、既定の動きがそのまま出ます。
リトライ設計は、処理が失敗したときにどう送り直すかを決めることです。
1番目を飛ばすと無駄が積み上がります。送り直しても通らない失敗の扱いはデッドレターキューの記事で扱っています。
相手が一時的に処理しきれなくなっているとき、すぐ送り直すと止めを刺します。復旧のための余裕がなくなります。
AWSも、呼び出す側を遅くすることが助けになる場合があり、その古典的なやり方が上限付きの指数的な待ちだとしています。待つのは相手のためです。
前の節で使ったのは、計算した待ち時間に0から1の値を掛けるやり方です。待ち時間は0から上限までのどこかになります。
平均すると待ち時間は半分になります。それでいて山は7分の1になりました。待ち時間を伸ばすより、ばらつかせるほうが効きます。
失敗するかどうかは種を固定した乱数で決めています。相手の状態は再現していません。実際には送り直しが集中すると失敗率そのものが上がるので、ばらつきの効果はこの計測より大きく出ます。ここで見せているのは、集中の度合いがどれだけ変わるかという部分です。
Slowing clients down may help, and the classic way to slow clients down is capped exponential backoff.原文AWS Architecture Blog「Exponential Backoff And Jitter」 この内容の有効期限2027-02-18
待ち時間を伸ばせば安全だと考えることです。全員が同じ規則で待つ限り、集中は残ります。
リトライ設計でいちばん多い勘違いは、待ち時間さえ伸ばせば相手に優しいという考え方です。
前の節の実測では、待ち時間を倍々に増やしても山は301回のままでした。すぐ送り直す場合の440回から、思ったほど減っていません。
理由は単純です。1秒待った全員が、1秒後に同時に戻ってきます。空いた時間帯ができただけで、山はそのままです。
送り直しの回数に上限がないと、通らない処理が永久に送り直されます。この計測は5回で打ち切っています。
上限に達したものをどうするかも決めてください。捨てるのか、別の置き場に移すのか。決めていないと、静かに消えます。
山が起きていることは、成功率を見ていても分かりません。前の節でも成功件数は996件と999件で、ほとんど差がありませんでした。
見るべきは時刻ごとの送信数です。記録していなければ、相手側から苦情が来るまで気づけません。
成功率では見えない。時刻ごとに数える。
there are still clusters of calls. Instead of reducing the number of clients competing in every round, we've just introduced times when no client is competing.原文AWS Architecture Blog「Exponential Backoff And Jitter」 この内容の有効期限2027-02-18
同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。
出品の仕組みを見る