サブスクリプションフィルター
EMQX 6.2で導入されたサブスクリプションフィルター機能は、MQTT 5.0のパブリッシュ/サブスクライブモデルを拡張し、サブスクリプションレベルでのコンテンツベースのフィルタリングを可能にします。これにより、クライアントはトピックフィルターと追加のフィルター式の両方にマッチするメッセージのみを受信でき、不必要なメッセージ配信やネットワークのオーバーヘッドを削減できます。
本ページでは、EMQXにおけるサブスクリプションフィルターの設計意図、主要概念、フィルター式の構文、動作セマンティクス、実際のユースケースを包括的に解説します。
サブスクリプションフィルターとは?
サブスクリプションフィルターとは、MQTTサブスクリプションに付加できる任意のフィルター条件です。パブリッシュされたメッセージがサブスクリプションのトピックフィルターにマッチした場合、EMQXはメッセージのMQTT 5.0 User Propertiesに対してフィルター式を評価し、両方の条件を満たすメッセージのみをサブスクライバーに転送します。
標準のMQTTルーティングでは、トピックにマッチしたすべてのメッセージがサブスクライバーに転送されます。
Publisher --> Topic -- (Filter) --> Subscription --> Subscriberサブスクリプションフィルターはメッセージルーティング経路に第2のフィルター層を導入します。
Publisher --> Topic -- (Filter) --> Subscription -- (Filter) --> Subscriberこの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を使ったフィルター動作のエンドツーエンド検証をステップバイステップで解説します。