コンシューマ進捗管理
Apache RocketMQはコンシューマのオフセットを使用して、コンシューマの進捗を管理します。このトピックでは、Apache RocketMQのコンシューマ進捗管理メカニズムについて説明します。
背景
Apache RocketMQでは、メッセージはコンシューマにサブスクライブされる前後に生成できます。では、コンシューマはメッセージのコンシューミングを開始する場所をどのように認識し、コンシューミングされたメッセージはどのようにマークされるのでしょうか? この課題を克服するために、Apache RocketMQはコンシューマ進捗管理メカニズムを開発しました。
Apache RocketMQのコンシューマ進捗管理メカニズムは、次の問題を解決します。
クライアントは起動後にメッセージのコンシューミングをどこから開始しますか?
コンシューミングされたメッセージは、複数回処理されないようにどのようにマークされますか?
サービスの例外が発生した場合、同じクライアントはメッセージを再度コンシューミングできますか?
動作メカニズム
メッセージオフセット
Apache RocketMQでは、メッセージは到着順にトピックにキューイングされ、一意のLong型座標が割り当てられます。これはメッセージのオフセットとも呼ばれます。これらの概念の個別定義の詳細については、トピックとメッセージキューを参照してください。
理論的には、メッセージキューは無限の数のメッセージを格納できます。したがって、オフセットの値の範囲は0からLong.MAX_VALUEまでです。トピック、キュー、オフセットに基づいてどのメッセージでも見つけることができます。次の図は、これら3つの概念の関係を示しています。
Apache RocketMQでは、キュー内の最も古いメッセージのオフセットは最小オフセット(MinOffset)と呼ばれ、最新のメッセージのオフセットは最大オフセット(MaxOffset)と呼ばれます。理論的にはメッセージキューは無限の数のメッセージを保持できますが、それらを格納する物理マシンには限られたスペースしかありません。したがって、Apache RocketMQはキューから最も古いメッセージを動的に削除し、キューのMinOffsetとMaxOffsetの値は常に増加します。
コンシューマオフセット
Apache RocketMQはパブリッシュ/サブスクライブパターンに従います。複数のコンシューマグループが同じキューにサブスクライブできます。このようなシナリオでは、コンシューマがメッセージをコンシューミングした後、そのメッセージを削除すると、他のコンシューマはそのメッセージをコンシューミングできなくなります。
これを防ぐために Apache RocketMQ はコンシューマーオフセットを使用して、異なるコンシューマーのメッセージ消費の進捗状況を管理します。Apache RocketMQ はコンシューマーが消費したメッセージをすぐに削除しません。代わりに、コンシューマーグループによって消費された最新のメッセージの記録を保持し、コンシューマーオフセットとも呼ばれます。
クライアントが再起動された場合、コンシューマーはサーバーに保存されたコンシューマーオフセットに基づいてメッセージの処理を続行できます。コンシューマーオフセットが期限切れして削除された場合、サーバーに保存されたキューの MinOffset 値がコンシューマーオフセットとして使用されます。
コンシューマーオフセットは Apache RocketMQ サーバーに保存して復元され、特定のコンシューマーとは関係ありません。そのため、Apache RocketMQ は異なるコンシューマー間でコンシューマーの進捗状況を復元できます。
次の図は、メッセージキュー内の最小オフセット、最大オフセット、コンシューマーオフセットの関係を示しています。
コンシューマーオフセットは常に最大オフセット以下です。
メッセージが同じ速度で生成され消費され、キューの中に消費されていないメッセージがない場合、コンシューマーオフセットは最大オフセットと同じです。
メッセージが生成されるよりも遅く消費される場合、消費されていないメッセージがキュー内に存在します。その結果、コンシューマーオフセットは最大オフセットより小さくなり、差は消費されていないメッセージの数になります。
通常、コンシューマーオフセットは最小オフセット以上になります。コンシューマーオフセットが最小オフセットより小さい場合、コンシューマーはメッセージを消費できません。この場合、サーバーは正しいコンシューマーオフセットをコンシューマーに復元します。
初期コンシューマーオフセット
初期コンシューマーオフセットは、コンシューマーグループが初めてメッセージキューを消費し始める際にサーバーに保存されるコンシューマーオフセットです。
コンシューマーが初めてキューからメッセージを取得するときに、Apache RocketMQ はキューの最大オフセットを使用して初期コンシューマーオフセットとします。つまり、コンシューマーはキュー内の最新のメッセージから消費を開始します。
コンシューマーオフセットをリセットする
初期または現在のコンシューマーオフセットがビジネスの状態と一致しない場合は、コンシューマーオフセットをリセットしてコンシューマーの進捗状況を調整できます。
シナリオ
正しくない初期コンシューマーオフセット: 初期コンシューマーオフセットはキューの最大オフセットで、つまりクライアントは最新のメッセージから消費を開始します。以前のメッセージを消費する必要がある場合は、コンシューマーオフセットを以前のメッセージのオフセットにリセットできます。
コンシューマーラグ: コンシューマーがメッセージの生成速度に追いつけない場合、大量のメッセージが蓄積される可能性があります。蓄積されたメッセージがミッションクリティカルでない場合は、コンシューマーオフセットをより大きな値に調整してこれらのメッセージをスキップし、ダウンストリームの負荷を軽減できます。
ビジネスのバックトラッキングと是正処理: ビジネス上のエラーにより間違って消費されたメッセージを再消費したい場合は、コンシューマーオフセットをより小さな値に設定できます。
コンシューマーオフセットリセット機能
Apache RocketMQ のコンシューマーオフセットリセット機能を使用すると、次のことができます。
メッセージキュー内の任意のオフセットにコンシューマーオフセットをリセットします。
コンシューマーオフセットを特定の時点にリセットします。サーバーはコンシューマーオフセットを、時間点に最も近いオフセットに調整します。
制限
コンシューマー・オフセットをリセットすると、コンシューマーは新しいオフセットからメッセージの消費を開始します。バックトラッキングのシナリオにおいて、コンシューマーは主にコールドデータである履歴のメッセージから開始します。コールドリードと呼ばれるこれは、システムに過度の負荷をかける可能性があります。この操作を進める前に、リスクと利点を評価してください。乱用や頻繁なリセットを防ぐため、この権限に厳格な制御ポリシーを実装することをお勧めします。
Apache RocketMQでは、可視メッセージに対してのみコンシューマー・オフセットをリセットできます。スケジュール中または再試行保留ステータスのメッセージのオフセットはリセットできません。詳しくは、遅延メッセージとメッセージの再消費の再試行をご覧ください。
バージョンの互換性
サーバは、Apache RocketMQの異なるバージョンでの初期コンシューマー・オフセットを、それぞれ異なる方法で定義します。
4.xと3.xバージョンでは、初期コンシューマー・オフセットはキューのメッセージ・ステータスに定義されます。
5.xバージョンでは、初期コンシューマー・オフセットはコンシューマーがメッセージの受信を開始した時点におけるキューの最大オフセットです。
そのため、より前のバージョンからアップグレードする場合は、クライアントを起動するときに初期コンシューマー・オフセットに注意する必要があります。
使用上の注意
リセット権限を厳しく制御する
コンシューマー・オフセットをリセットするとシステムにさらなる負荷がかかり、メッセージの読み書きに影響を与える可能性があります。そのため、この操作を実行する前にリスクと利点を評価することをお勧めします。