サブスクリプションフィルター
EMQX 6.2で導入されたサブスクリプションフィルター機能は、MQTT 5.0のパブリッシュ/サブスクライブモデルを拡張し、サブスクリプションレベルでのコンテンツベースのフィルタリングを可能にします。これにより、クライアントはトピックフィルターと追加のフィルター式の両方に一致するメッセージのサブセットのみを受信でき、不必要なメッセージ配信やネットワークのオーバーヘッドを削減できます。
本ページでは、EMQXにおけるサブスクリプションフィルターの設計動機、主要概念、フィルター式の構文、動作セマンティクス、実際のユースケースを含めて包括的に解説します。
サブスクリプションフィルターとは?
サブスクリプションフィルターは、MQTTサブスクリプションに付加できるオプションのフィルター条件です。パブリッシュされたメッセージがサブスクリプションのトピックフィルターに一致した場合、EMQXはメッセージのMQTT 5.0のUser Propertiesに対してフィルター式を評価し、両方の条件を満たすメッセージのみをサブスクライバーに転送します。
標準のMQTTルーティングでは、トピックに一致したすべてのメッセージがサブスクライバーに転送されます。
パブリッシャー --> トピック -- (フィルター) --> サブスクリプション --> サブスクライバーサブスクリプションフィルターは、メッセージルーティング経路に第2のフィルタリングレベルを導入します。
パブリッシャー --> トピック -- (フィルター) --> サブスクリプション -- (フィルター) --> サブスクライバーこの2段階のフィルタリング機構により、トピックベースとコンテンツベースの両方のフィルタリングが可能となり、クライアントは受信したいメッセージを正確に指定できます。
なぜサブスクリプションフィルターを使うのか?
標準のMQTT 5.0サブスクリプションはトピックの一致のみでメッセージをルーティングします。マッチしたトピックにパブリッシュされたすべてのメッセージが、内容に関係なくすべてのサブスクライバーに配信されます。これは以下のようなシナリオで制約となることがあります。
- サブスクライバーが特定の地域、デバイスグループ、カテゴリのメッセージのみを受信したい場合
- 高頻度のトピックに混在するデータを異なるコンシューマーが独立して分割して処理したい場合
- すべてのメッセージをクライアントに配信するとネットワーク負荷や処理負荷が不必要に増大する場合
サブスクリプションフィルターは、サブスクリプション時に正確でコンテンツ認識型の配信ルールを宣言できるようにし、パブリッシャーやトピック構造、データ次元ごとの別トピックの変更を必要としません。
主要概念
トピックフィルター:サブスクリプションの標準MQTTトピックフィルター部分(
?より前の部分)。どのメッセージがルーティング段階に入るかを決定します。フィルター式:コンテンツベースのフィルター条件(
?より後の部分)。トピックフィルターを通過した各メッセージのMQTT 5.0 User Propertiesに対して評価されます。User Properties:MQTT 5.0メッセージに付加されるキー・バリュー形式のメタデータ。パブリッシャーは
locationやdevice_type、regionなどの追加コンテキストを提供し、サブスクライバーはこれを基にフィルタリングできます。2段階配信:トピックフィルターの評価に続き、フィルター式の評価を行い、両方を満たしたメッセージのみをサブスクライバーに配信する仕組み。
非フィルターサブスクリプション:
?区切りがないサブスクリプション。標準のMQTTサブスクリプションとして扱われ、トピックに一致するすべてのメッセージが配信されます。
サブスクリプションフィルターの動作
サブスクリプションフィルターはMQTT 5.0のUser Propertiesをフィルタリング対象とします。クライアントがメッセージをパブリッシュする際、User Propertiesヘッダーにキー・バリューのペアを含めることができます。EMQXは各フィルター式をこれらのキー・バリューに対して評価し、式に一致した場合のみメッセージを配信します。
サブスクリプションフィルターはデフォルトで無効です。有効化方法についてはサブスクリプションフィルターの使い始めをご参照ください。
フィルター構文
サブスクリプションフィルターは、トピックフィルターの後に?区切りで付加します。
<topic-filter>?<filter-expression>| コンポーネント | 説明 |
|---|---|
<topic-filter> | 標準のMQTTトピックフィルター(例:sensor/+/temperatureやhome/#) |
? | トピックフィルターとフィルター式を区切るデリミタ |
<filter-expression> | メッセージのUser Propertiesに対して評価されるキー・バリューのフィルター条件 |
フィルター式の形式
フィルター式は等価比較や大小比較演算子をサポートします。複数条件は&(論理AND)で結合します。
key1=value1&key2>value2| 要素 | 説明 |
|---|---|
key | パブリッシュされたメッセージのUser Propertyキー名 |
= | 等価比較(キーの値が指定文字列と完全一致する必要あり) |
> | 数値比較(キーの値が指定数値より大きい必要あり) |
>= | 数値比較(キーの値が指定数値以上である必要あり) |
< | 数値比較(キーの値が指定数値より小さい必要あり) |
<= | 数値比較(キーの値が指定数値以下である必要あり) |
& | 複数条件の結合。すべての条件が真の場合にメッセージを配信 |
フィルター式は大文字・小文字を区別します。指定されたキーがメッセージのUser Propertiesに存在しない場合、そのメッセージはフィルターアウトされます。
TIP
サブスクリプションフィルターはMQTT 5.0クライアントのみ適用されます。MQTT 3.1.1クライアントが?を含むトピック文字列でサブスクライブした場合、文字列全体がリテラルトピックフィルターとして扱われます。
動作セマンティクス
- EMQXは、トピックフィルターが一致し、かつフィルター式が真と評価された場合にのみメッセージをサブスクライバーに配信します。
- フィルター式が参照するキーがメッセージのUser Propertiesに存在しない場合、そのメッセージは当該サブスクライバーに配信されません。
- 各サブスクリプションのフィルター式は独立して評価されます。あるサブスクライバーにメッセージが配信されるかどうかは、同じトピックの他のサブスクライバーへの配信に影響しません。
?区切りのないサブスクリプションは標準のMQTTサブスクリプションと同様に動作します。- フィルター式の評価はサーバー側で行われ、クライアント側でのフィルタリングロジックは不要です。
フィルター式の例
以下は一般的なサブスクリプションパターンの例です。
| サブスクリプション文字列 | 意味 |
|---|---|
sensor/+/temperature?location=roomA | User Propertiesにlocation=roomAを含む温度メッセージを受信 |
sensor/+/temperature?value>25 | value User Propertyが25より大きい温度メッセージを受信 |
sensor/+/temperature?location=roomA&unit=celsius | location=roomAかつunit=celsiusの両方を満たす温度メッセージを受信 |
home/lights/# | 標準サブスクリプション。マッチするトピックのすべてのメッセージを受信 |
パブリッシャー側
パブリッシャーはUser Propertiesとして以下を付加し、sensor/1/temperatureにメッセージを送信します。
{
"location": "roomA",
"unit": "celsius"
}サブスクライバー側
| サブスクリプション | 配信されるか | 理由 |
|---|---|---|
sensor/+/temperature?location=roomA | はい | location=roomAが一致 |
sensor/+/temperature?location=roomB | いいえ | locationの値が一致しない |
sensor/+/temperature?location=roomA&unit=celsius | はい | 両条件が一致 |
sensor/+/temperature?location=roomA&unit=fahrenheit | いいえ | unitの値が一致しない |
sensor/+/temperature | はい | フィルター式なしの標準サブスクリプション |
認可に関する考慮事項
認可が有効な場合、EMQXは設定されたルールに基づきサブスクリプショントピックを検証します。認可に使用されるトピックはベーストピックフィルター(?区切りの前の部分)です。フィルター式は認可評価前に除去されます。
例えば、sensor/+/temperature?location=roomAにサブスクライブするクライアントは、sensor/+/temperatureに対して認可されている必要があります。サブスクリプションフィルターを用いる場合は、ベーストピックパターンに対応した認可ルールを設定してください。
関連機能リファレンス
サブスクリプションフィルターはEMQXの他のメッセージング機能を補完します。
- 共有サブスクリプション:サブスクライバーグループ間でメッセージを分散しロードバランシングを実現。コンテンツベースのフィルタリングはサポートしません。
- 保持メッセージ:トピックごとに最後のメッセージを保存し、新規サブスクライバーに配信。保持メッセージの配信はサブスクリプションフィルターの式に影響されません。
- トピック書き換え:ルーティング前にトピック文字列を書き換え。トピック書き換えルールはサブスクリプションフィルター評価前に適用されます。
- ワイルドカードサブスクリプション:
+や#ワイルドカードで複数トピックにマッチ。ワイルドカードトピックフィルターはサブスクリプションフィルターと組み合わせ可能です。 - メッセージキュー:永続ストレージと設定可能なディスパッチ戦略を備えた耐久性のある非同期メッセージキューを提供します。
次のステップ
サブスクリプションフィルターの概念を理解したら、実際の利用方法を学びましょう。
- サブスクリプションフィルターの使い始め:機能の有効化方法とMQTTX CLIを使ったフィルター動作のエンドツーエンド検証をステップバイステップで解説します。