共有サブスクライブ
共有サブスクライブは、複数のサブスクライバー間での負荷分散を実現するためのサブスクリプションモードです。クライアントは複数のサブスクリプショングループに分けられ、メッセージはすべてのサブスクリプショングループに転送されますが、各グループ内のクライアントには同時に1つのクライアントだけがメッセージを受信します。
EMQX Cloudでは、以下の形式でグループ名を指定した共有サブスクライブをサポートしています:$share/<group-name>/<topic-name>。
共有サブスクライブは、いくつかの配信戦略をサポートしています:
| 戦略 | 説明 |
|---|---|
| ランダム | グループ内のセッションをランダムに選択します。 |
| ラウンドロビン | セッションに順番にメッセージを分配します。 |
| ハッシュ | トピックまたはパブリッシャーのクライアントIDのハッシュに基づいてメッセージを割り当てます。 |
| スティッキー | 最初にランダムにセッションを選択し、サブスクライバーがオフラインになるか再接続するまで同じセッションを使い続けます。 |
| ローカル | パブリッシャーと同じノード上のセッションを優先し、存在しない場合はランダムに選択します。 |
EMQX Cloudでは、デフォルトでラウンドロビン戦略を使用しています。
なお、共有サブスクライブはクライアントの実際の負荷やアイドル状態に基づいてメッセージ配信を動的に調整するものではありません。クライアントの処理能力が低い場合や保留中のメッセージが多く蓄積された場合でも、EMQXは戦略に基づいてメッセージを配信し続け、キューの上限を超えるとメッセージが破棄される可能性があります。
したがって、共有サブスクライブの目的はメッセージ配信の負荷をより均等に分散し、処理の制御性を向上させることであり、メッセージの損失が絶対に起きないことを保証するものではありません。
EMQX Cloudにクライアントツールで接続して、このメッセージングサービスを試すことができます。このページでは共有サブスクライブの動作原理を紹介し、MQTTX Desktopを使ってクライアントをシミュレートし、共有サブスクライブ機能を試す方法を説明します。
グループ向け共有サブスクライブ
サブスクライバーのグループに対して共有サブスクライブを有効にするには、元のトピックにプレフィックス $share/<group-name> を追加します。グループ名は任意の文字列を指定できます。EMQX Cloudは異なるグループに同時にメッセージを転送し、同じグループに属するサブスクライバーは負荷分散された形でメッセージを受信します。
例えば、サブスクライバーs1、s2、s3がグループg1のメンバーであり、サブスクライバーs4、s5がグループg2のメンバーで、すべてのサブスクライバーが元のトピックt1をサブスクライブしている場合、共有サブスクライブのトピックはそれぞれ$share/g1/t1と$share/g2/t1となります。EMQXが元のトピックt1にメッセージmsg1をパブリッシュすると:
- EMQX Cloudは
msg1をグループg1とg2の両方に送信します。 s1、s2、s3のうち1つだけがmsg1を受信します。s4とs5のうち1つだけがmsg1を受信します。

共有サブスクライブとセッション
共有サブスクライブの概念とMQTTクライアントにおけるパーシステントセッションの利用は矛盾しており、両者を同時に使用することはできません。共有サブスクライブ機能を利用する場合、クライアント側でclean_sessionパラメータをtrueに設定し、クリーンセッションを有効にする必要があります。
パーシステントセッション(clean_session=false)は、サブスクライバーが再接続後にメッセージを失うことなくデータフローを即座に再開できるようにするための機能であり、信頼性の高いメッセージ配信を維持する上で重要です。clean_sessionをfalseに設定すると、クライアントがオフラインになってもセッションは維持され、デバイスはメッセージを受信し続けます。しかし、デバイスがオフラインの間は受信したメッセージを処理できず、セッション内にメッセージが蓄積される可能性があります。
共有サブスクライブが有効で、同じグループ内の別のデバイスがオフラインのデバイスのデータフローを引き継いだ場合、そのデバイスは蓄積されたメッセージを受け取ることはできません。なぜなら、それらのメッセージは元のデバイスのセッションに属しているためです。そのため、デバイスが長期間オフラインのままだと、パーシステントセッションのメッセージバッファが溢れ、メッセージの損失が発生します。この状況は負荷分散を妨げ、最終的にはメモリやストレージリソースの枯渇を招き、システムの安定性や全体的なパフォーマンスに悪影響を及ぼします。
パーシステントセッションの詳細については、MQTT Persistent Session and Clean Session Explainedをご参照ください。
MQTTXを使った共有サブスクライブのテスト
MQTTXを使ってクライアントのサブスクライブをシミュレートします。
- s1、s2はトピック
$share/g1/testをサブスクライブ - s3はトピック
testをサブスクライブ

MQTTXでクライアントP1を作成し、トピックtestに3つのメッセージを送信します。

s1がmsg1、msg2を受信し、s2がmsg3を受信、s3はすべてのメッセージを受信します。
