メインコンテンツにスキップ
バージョン:5.0

コンシューマーの負荷分散

コンシューマーグループ内のコンシューマーがApache RocketMQトピックからメッセージをプルする場合、負荷分散ポリシーを使用して、メッセージをコンシューマーにどのように割り当てるかを決定します。負荷分散ポリシーは、サービスの同時実行性とアプリケーションのスケーラビリティを向上させます。このトピックでは、Apache RocketMQがコンシューマーに提供する負荷分散ポリシーについて説明します。

背景情報

Apache RocketMQが提供する負荷分散ポリシーをよく理解すると、以下のシナリオに直面したときに適切な対策を講じるのに役立ちます。

  • 災害復旧:ローカルノードが失敗した場合のメッセージの再試行と切り替え方法を決定できます。

  • メッセージの順序付け:Apache RocketMQが厳密な先入れ先出しのメッセージ順序をどのように保証するかをより深く理解できます。

  • 水平パーティショニング:メッセージの割り当て方法に基づいて、トラフィックの移行と水平スケーリング操作を計画できます。

ブロードキャスト消費とクラスター消費

Apache RocketMQでは、複数のコンシューマーグループが同じメッセージをサブスクライブし、各コンシューマーグループが複数のコンシューマーを初期化できます。コンシューマーグループとコンシューマーは、次のシナリオでメッセージを消費するように構成できます。消費モード

  • コンシューマーグループ間のブロードキャスト消費:このシナリオは、上記の図の左側に示されています。各コンシューマーグループは、すべてのメッセージを消費する独自のコンシューマーを初期化します。メッセージは、1対多の関係でトピックから複数のサブスクライバーに配信されます。

    このモードは、通常、ゲートウェイプッシュや構成プッシュなどのシナリオで使用されます。

  • コンシューマーグループ内のクラスター消費:このシナリオは、上記の図の右側に示されています。各コンシューマーグループは複数のコンシューマーを初期化し、メッセージはグループ内のすべてのコンシューマーに送信されます。これは、グループ内で水平トラフィックのパーティショニングと負荷分散を実装する場合に役立ちます。

    このモードは、マイクロサービスのデカップリングに適しています。

コンシューマーの負荷分散ポリシーの概要

ブロードキャスト消費を使用するシナリオでは、各コンシューマーグループに1つのコンシューマーしか含まれていないため、負荷分散は必要ありません。

ただし、クラスター消費を使用するシナリオでは、各コンシューマーグループに複数のコンシューマーが含まれています。負荷分散ポリシーは、メッセージの割り当て方法を決定するのに役立ちます。

コンシューマーの種類に基づいて、負荷分散ポリシーは次の2つのタイプに分類できます。

メッセージベースの負荷分散

使用範囲

メッセージベースの負荷分散は、プッシュコンシューマーとシンプルコンシューマーの唯一のデフォルトポリシーです。

動作メカニズム

メッセージベースの負荷分散は、トピック内のメッセージをコンシューマーグループ内の複数のコンシューマーに均等に割り当てます。メッセージベースの負荷分散

上記の図に示すように、コンシューマーグループAは、A1、A2、およびA3の3つのコンシューマーで構成されています。これら3つのコンシューマーは、トピック内のQueue1のメッセージを消費します。

メッセージベースの負荷分散は、キュー内のメッセージが複数のコンシューマーによって同時に処理されることを保証します。ただし、メッセージはコンシューマーにランダムに送信されます。つまり、メッセージをコンシューマーにどのように割り当てるかを指定できません。

メッセージベースの負荷分散は、トピック内の単一メッセージの確認応答セマンティクスに基づいています。コンシューマーがメッセージを受信すると、ブローカーはメッセージをロックして、メッセージが消費されるかタイムアウトするまで他のコンシューマーから見えなくなるようにします。これにより、同じキューのメッセージが異なるコンシューマーによって複数回消費されるのを防ぎます。

順序付きメッセージのロードポリシー

順序付きメッセージでは、メッセージの順序は、メッセージグループ内の複数のメッセージのシーケンスを指します。これらのメッセージは、ブローカーに保存された順序とまったく同じ順序で処理する必要があります。したがって、メッセージベースの負荷分散では、メッセージグループ内のメッセージがサーバーに保存された順序と同じ順序で消費されるようにする必要があります。異なるコンシューマーが同じグループ内のメッセージを処理する場合、システムはメッセージ順序に厳密に従ってメッセージをロックし、メッセージが順番に消費されるようにします。順序付きメッセージのロードポリシー

上記の図では、Queue1のメッセージグループG1に4つの順序付きメッセージがあります。それらの保存順序は、M1からM4で表されます。消費中、メッセージM1とM2がコンシューマーA1によって処理されている場合、M1とM2の消費ステータスが送信されていない場合、コンシューマーA2はメッセージM3とM4を並行して消費できません。コンシューマーは、先行メッセージの消費ステータスが送信された場合にのみ、メッセージを消費できます。

特徴

キューベースの負荷分散と比較して、メッセージベースの負荷分散には次の特徴があります。

  • よりバランスの取れた消費割り当て。従来のキューベースの負荷分散では、キューの数とコンシューマーの数のバランスが適切ではない場合があります。これにより、一部のコンシューマーがアイドル状態になり、一部のコンシューマーが過負荷になるシステムになります。これに対し、メッセージベースの負荷分散では、キューとコンシューマーの数を管理する必要がなく、コンシューマー間で均等な負荷分散が保証されます。
  • ネットワーク容量の違いに対して寛容。オンラインの本番環境では、実際のネットワーク条件やネットワークハードウェアの仕様の不一致により、コンシューマーの処理能力が異なる場合があります。メッセージがキューに基づいて割り当てられている場合、一部のコンシューマーがメッセージを累積し、他のコンシューマーがアイドル状態になるケースが発生する可能性があります。対照的に、メッセージベースの負荷分散は、コンシューマー間でよりバランスの取れた負荷分散を実現するために、必要に応じてメッセージを割り当てます。
  • キュー割り当てのO\&Mが容易。従来のキューベースの負荷分散が使用されるシナリオでは、アイドル状態のコンシューマーが発生しないように、キューの数がコンシューマーの数以上であることを確認する必要があります。この問題は、メッセージベースの負荷分散では発生しません。

シナリオ

キュー内のメッセージはコンシューマーに個別に割り当てられるため、メッセージベースの負荷分散は、ほとんどのオンラインイベント処理シナリオに適しています。これらのシナリオでは、コンシューマーはメッセージの一括集計ではなく、基本的な処理能力のみを必要とします。ストリーム処理や、メッセージの集計とバッチ処理が必要な集計コンピューティングなどのシナリオでは、キューベースの負荷分散の方が適しています。

コンシューマーは、メッセージベースの負荷分散のために追加の構成を実行する必要はありません。デフォルトでは、このポリシーはプッシュコンシューマーとシンプルコンシューマーに対して有効になっています。

        SimpleConsumer simpleConsumer = null;
// Consumption example 1: When push consumers consume normal messages, they need only to process messages on a message listener and do not need to consider load balancing.
MessageListener messageListener = new MessageListener() {
@Override
public ConsumeResult consume(MessageView messageView) {
System.out.println(messageView);
// Return the status based on the consumption result.
return ConsumeResult.SUCCESS;
}
};
// Consumption example 2: When simple consumers consume normal messages, they obtain and submit messages. The consumers obtain messages based on the subscribed topic and do not need to consider load balancing.
List<MessageView> messageViewList = null;
try {
messageViewList = simpleConsumer.receive(10, Duration.ofSeconds(30));
messageViewList.forEach(messageView -> {
System.out.println(messageView);
// After consumption is complete, consumers must invoke ACK to submit the consumption result.
try {
simpleConsumer.ack(messageView);
} catch (ClientException e) {
e.printStackTrace();
}
});
} catch (ClientException e) {
// If the pull fails due to system traffic throttling or other reasons, consumers must re-initiate the request to obtain the message.
e.printStackTrace();
}

キューベースの負荷分散

使用範囲

PullConsumer、DefaultPushConsumer、DefaultPullConsumer、DefaultLitePullConsumerなど、ブローカーバージョン4.xおよび3.xのコンシューマーの場合、キューベースの負荷分散のみを使用できます。

動作メカニズム

キューベースの負荷分散ポリシーでは、同じコンシューマーグループ内のコンシューマーは、割り当てられたキュー内のメッセージを消費します。各キューは1つのコンシューマーによって消費されます。队列级负载均衡原理

上記の図に示すように、トピック内の3つのキュー(Queue1、Queue2、およびQueue3)は、コンシューマーグループ内の2つのコンシューマーに割り当てられます。各キューは1つのコンシューマーにのみ割り当てることができるため、コンシューマーA2には2つのキューが割り当てられます。キューの数がコンシューマーの数よりも少ない場合、一部のコンシューマーにはキューが割り当てられません。

キューベースの負荷分散は、キューの数やコンシューマーの数などの操作データに基づいてメッセージを割り当てます。各キューは、特定のコンシューマーにバインドされます。次に、各コンシューマーは、メッセージを取得するという消費セマンティクスに従ってメッセージを処理します。>オフセットの送信>オフセットの永続化。コンシューマーがメッセージを取得するとき、消費ステータスはキューに返されません。したがって、複数のコンシューマーによるメッセージの繰り返し消費を回避するために、各キューは1つのコンシューマーのみが消費できます。

キューベースの負荷分散は、キューが1つのコンシューマーのみによって処理されることを保証します。ただし、このポリシーの実装は、コンシューマーとブローカー間の情報ネゴシエーションメカニズムに依存します。

Apache RocketMQは、キュー内のメッセージが1つのコンシューマーのみによって処理されることを保証しません。したがって、コンシューマーの数とキューの数が変化すると、キューの割り当てに一時的な不整合が発生する可能性があり、少数のメッセージが複数回処理される可能性があります。

特徴

メッセージベースのロードバランシングと比較して、キューベースのロードバランシングは粒度が大きく、柔軟性に欠けます。しかし、キューベースのロードバランシングはストリーム処理のシナリオに最適です。キュー内のメッセージが1つのコンシューマーによって処理されることを保証します。したがって、キューベースのロードバランシングは、集約されたメッセージやバッチ処理されるメッセージを処理したいシナリオに適しています。

シナリオ

キューベースのロードバランシングは、集約されたメッセージやバッチ処理されるメッセージを処理したいシナリオに適用できます。これらは、ストリームコンピューティングやデータ集約アプリケーションで一般的なシナリオです。

コンシューマーは、キューベースのロードバランシングのために追加の設定を行う必要はありません。デフォルトでは、このポリシーはブローカーバージョン4.xおよび3.xのプルコンシューマーに対して有効になっています。

サンプルコードの詳細については、Apache RocketMQのコードライブラリを参照してください。

バージョン互換性

メッセージベースのロードバランシングポリシーは、Apache RocketMQのブローカーバージョン5.0から利用可能です。ブローカーバージョン4.xおよび3.xでは、キューベースのロードバランシングポリシーのみが利用可能です。

メッセージベースとキューベースの両方のロードバランシングポリシーは、Apache RocketMQのブローカーバージョン5.xで利用可能です。どちらのポリシーが有効になるかは、クライアントのバージョンとコンシューマーのタイプに依存します。

使用上の注意

消費ロジックに対してメッセージの冪等性を実装してください。

メッセージベースとキューベースの両方のロードバランシングポリシーは、コンシューマーの追加、コンシューマーの削除、ブローカーのスケーリングなどのシナリオで一時的なリバランスをトリガーします。これにより、一時的な負荷の不整合が発生し、少数のメッセージが複数回消費される可能性があります。したがって、メッセージ消費の冪等性を保証するために、重複排除を実行する必要があります。