インフライトとメッセージキュー
はじめに
メッセージのスループットを向上させ、ネットワークの変動による影響を軽減するために、EMQXは複数の未アック済みのQoS 1およびQoS 2メッセージを同時にインフライト状態で保持できます。送信済みで未確認のメッセージは、アックが完了するまでインフライトウィンドウに格納されます。
インフライトウィンドウの最大数(max_inflightを参照)に達した場合、新たに到着したメッセージは即座に転送されず、一時的にメッセージキューに格納されます。
配信が再開されると、トピック優先度が無効の場合はEMQXがFIFO順にメッセージをデキューします。トピック優先度が有効な場合は、EMQXがトピック優先度に従ってメッセージをスケジューリングし、各優先度内ではFIFO順を保持します。配信されたQoS 1およびQoS 2メッセージはインフライトウィンドウに追加されますが、配信されたQoS 0メッセージはインフライトウィンドウに入りません。
QoS 0メッセージは通常インフライトウィンドウをバイパスして即座に転送されます。インメモリセッションの場合、接続の送信キューが混雑するとEMQXは後続のQoS 0メッセージをメッセージキューに格納します。インフライトウィンドウが満杯でかつmqueue_store_qos0が有効な場合も、EMQXはQoS 0メッセージをキューに格納し、通常のキュースケジューリングに従わせます。接続が回復するかインフライトウィンドウに空きができると、EMQXはキューに格納されたメッセージの配信を再開します。
トピック優先度ごとのメッセージキューが長さ制限に達すると、EMQXはまずその優先度の最も古いQoS 0メッセージを削除します。該当優先度にQoS 0メッセージが存在しない場合は、その優先度の最も古い残りのメッセージを削除します。トピック優先度が無効の場合は、すべてのメッセージが同じ優先度を共有します。このポリシーにより、QoS 0のバースト時にもQoS 1およびQoS 2メッセージの進行が確保されます。したがって、適切なメッセージキューの長さ制限を設定することが重要です。詳細はmax_mqueue_lenを参照してください。
メッセージキューは、サブスクライバーがオフラインであってもセッションが維持されている間に到着したメッセージも格納します。サブスクライバーが再接続すると、EMQXはこれらのメッセージを配信します。オフライン時のQoS 0メッセージの保存を除外するには、mqueue_store_qos0をfalseに設定してください。
なお、インフライトウィンドウとメッセージキューはグローバルではなく、EMQXは各クライアント接続ごとに別々のインフライトウィンドウとメッセージキューを割り当てます。
インフライトウィンドウとReceive Maximum
MQTT v5プロトコルはCONNECTパケットにReceive Maximum属性を追加し、その公式説明は以下の通りです。
クライアントは、この値を使用して、同時に処理することを望むQoS 1およびQoS 2のパブリッシュメッセージの最大数を制限します。サーバーが送信しようとするQoS 0のパブリッシュメッセージを制限する仕組みはありません。
つまり、サーバーはアックを待つ間に異なるメッセージ識別子を持つPUBLISHパケットをクライアントに連続して送信できますが、未アック済みメッセージ数がReceive Maximumの制限に達するとそれ以上送信しません。
このことから、Receive Maximumは実質的にEMQXのインフライトウィンドウ機構と同じであることがわかります。ただし、EMQXはMQTT v5.0プロトコルがリリースされる前からこの機能をMQTTクライアントに提供していました。現在、MQTT v5.0プロトコルを使用するクライアントはReceive Maximumの仕様に従ってインフライトウィンドウの最大長を設定し、以前のバージョンのクライアントは設定に従って設定されます。
ただし、EMQXはCONNECTパケットで要求されたReceive Maximum値を必ずしも許可しません。代わりに、CONNACKパケットで許可されるReceive Maximumはmqtt.max_inflight設定によって上限が制限されます。
設定項目
| 設定項目 | 型 | オプション値 | デフォルト値 | 説明 |
|---|---|---|---|---|
| mqtt.max_inflight | integer | (0, 65536) | 32 | インフライトウィンドウの長さ制限。0は制限なしを意味します。 |
| mqtt.max_mqueue_len | integer | [0, ∞) | 1000 | メッセージキューの長さ制限。0は制限なしを意味します。 |
| mqtt.mqueue_store_qos0 | enum | true, false | true | クライアントがオフライン、インメモリ接続の送信キューが混雑、またはインフライトウィンドウが満杯の場合に、QoS 0メッセージをメッセージキューに保存するかどうかを指定します。 |