メッセージ送信再試行およびスロットリングポリシー
このトピックでは、Apache RocketMQのメッセージ送信再試行メカニズムとスロットリングメカニズムについて説明します。
背景
メッセージ送信再試行
Apache RocketMQの送信再試行メカニズムは、以下の質問に答えます。
一部のノードに障害が発生した場合、メッセージを送信できますか?
再試行リクエストは呼び出しスレッドをブロックしますか?
送信再試行の欠点は何ですか?
スロットリング
Apache RocketMQのスロットリングメカニズムは、以下の質問に答えます。
どのような状況でスロットリングがトリガーされますか?
スロットリングがトリガーされた場合、クライアントの動作はどうなりますか?
スロットリングのトリガーを回避するにはどうすればよいですか?また、予期しないスロットリングが発生した場合はどうすればよいですか?
メッセージ送信再試行
送信再試行の概要
Apache RocketMQのプロデューサークライアントがブローカーを呼び出してメッセージを送信すると、ネットワーク障害やサービス例外などの理由で呼び出しが失敗する可能性があります。メッセージの信頼性を確保するために、Apache RocketMQは、リクエストが成功するまで失敗したリクエストを再試行するロジックをクライアントSDKに組み込んでいます。
メッセージ送信再試行は、同期送信モードと非同期送信モードの両方でサポートされています。
トリガー条件
送信再試行は、次のいずれかの条件によってトリガーされます。
クライアントからの呼び出しが失敗するか、リクエストがタイムアウトする。
ネットワーク例外により、接続障害またはリクエストタイムアウトが発生する。
ブローカーノードがシャットダウンまたは再起動されているため、接続が閉じられる。
ブローカーの実行速度が遅いため、リクエストがタイムアウトする。
ブローカーがエラーコードを返す。
ロジックエラー:実行ロジックが正しくないために発生したエラー。
スロットリング:過剰なトラフィックによってトリガーされるスロットリング。
トランザクションメッセージの場合、透過的な再試行のみが実行されます。ネットワーク例外またはタイムアウトのシナリオでは、再試行は実行されません。
再試行プロセス
プロデューサーがメッセージを初期化するときに、プロデューサーで最大再試行回数を指定できます。上記のトリガー条件のいずれかが発生すると、プロデューサークライアントは、メッセージが送信されるか、最大再試行回数に達するまで、メッセージの送信を再試行します。最後の再試行でも障害が解決しない場合は、呼び出しエラーが返されます。
同期送信:再試行が成功するか、最後の再試行が失敗するまで、呼び出しスレッドはブロックされます。最後の再試行が失敗した場合、システムはエラーコードと例外を返します。
非同期送信:呼び出しスレッドはブロックされません。呼び出し結果は、例外イベントまたは成功イベントとして返されます。
再試行間隔
再試行がスロットリングによってトリガーされた場合を除き、メッセージは障害発生後すぐに再試行されます。
再試行がスロットリングによってトリガーされた場合、メッセージは指数バックオフプロトコルで指定された間隔で再試行されます。指数バックオフアルゴリズムは、次のパラメーターを使用して再試行動作を制御します。
INITIAL_BACKOFF:最初の障害と最初の再試行の間隔を指定します。デフォルト値:1秒。
MULTIPLIER:再試行が失敗するたびに間隔に乗算する係数を指定します。デフォルト値:1.6。
JITTER:間隔をランダム化する係数を指定します。デフォルト値:0.2。
MAX_BACKOFF:間隔の上限を指定します。デフォルト値:120秒。
MIN_CONNECT_TIMEOUT:最小間隔を指定します。デフォルト値:20秒。
次のアルゴリズムをお勧めします。
ConnectWithBackoff()
current_backoff = INITIAL_BACKOFF
current_deadline = now() + INITIAL_BACKOFF
while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT))!= SUCCESS)
SleepUntil(current_deadline)
current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF)
current_deadline = now() + current_backoff + UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)
詳細については、connection-backoff.mdを参照してください。
制限
リンクブロッキングの評価:再試行メカニズムから、プロデューサーは再試行プロセスで最大再試行回数のみを設定できることがわかります。システム例外がSDKの組み込み再試行ロジックをトリガーした場合、ブローカーは最終的な再試行結果を待機する必要があり、送信リクエストリンクはブロックされます。したがって、再試行によってリンクがブロックされないように、各呼び出しのタイムアウト期間と最大再試行回数を評価する必要があります。
最終的な例外の処理:Apache RocketMQクライアントの組み込み送信再試行メカニズムは、失敗したメッセージが正常に送信されることを保証するものではありません。最後の再試行でも失敗した場合は、呼び出し元は例外をキャッチし、冗長性保護を提供して、メッセージ送信結果の不整合を防ぐ必要があります。
重複メッセージ:Apache RocketMQプロデューサークライアントがメッセージを再送信する場合、クライアントはブローカーで推定失敗したメッセージの処理結果を知りません。その結果、ブローカーに重複メッセージが存在する可能性があります。ビジネスロジックがこのような状況を適切に処理できることを確認してください。
スロットリング
スロットリングの概要
システム容量の使用率がしきい値を超えると、Apache RocketMQブローカーはリクエストを拒否し、基盤となるリソースに過負荷がかからないようにエラーを返します。
トリガー条件
Apache RocketMQのスロットリングメカニズムは、次のいずれかの条件によってトリガーされます。
高ストレージ圧力:コンシューマーの進捗管理の動作メカニズムセクションで説明されているように、コンシューマーグループはキューの最大オフセットからメッセージの消費を開始します。コンシューマーグループが以前の時点から消費する必要がある場合、キューのストレージ圧力が急増し、スロットリングがトリガーされます。これは、新しいビジネスのロールアウトなどのバックトラックシナリオで発生します。
ブローカーに未消費のメッセージが多すぎる:コンシューマーがメッセージの送信速度と同じ速度で消費できない場合、リクエストがキューに蓄積されます。蓄積されるメッセージの数がしきい値を超えると、ダウンストリームシステムの負荷を軽減するためにスロットリングがトリガーされます。
動作
スロットリングがトリガーされると、プロデューサークライアントは次のエラーメッセージと例外を受信します。
reply-code:530
reply-text:TOO_MANY_REQUESTS
これらを受信すると、クライアントは指数バックオフプロトコルに従ってメッセージを再試行します。詳細については、メッセージ送信再試行を参照してください。
推奨事項
推奨事項
スロットリングのトリガーを回避する方法:監視可能なメトリックを使用してシステム容量を監視し、それに応じて基盤となるリソースをスケーリングします。
スロットリングを処理する方法:スロットリングがトリガーされ、クライアントの組み込み再試行プロセスが失敗した場合は、呼び出しを一時的に別のシステムに切り替えることができます。