インフライトおよびメッセージキュー
はじめに
メッセージのスループットを向上させ、ネットワークの変動による影響を軽減するために、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は次回サブスクライバーがオンラインになった際にこれらのメッセージを送信します。mqueue_store_qos0オプションは、サブスクライバーがオフラインの間、インメモリ接続の送信キューが混雑している間、またはインフライトウィンドウが満杯の間にEMQXがQoS 0メッセージをメッセージキューに格納するかどうかを制御します。このオプションが無効の場合、サブスクライバーがオフラインまたは送信キューが混雑している間に到着したQoS 0メッセージは破棄されます。インフライトウィンドウが満杯の場合のみ、EMQXはQoS 0メッセージを即座に配信し続けます。
なお、インフライトウィンドウとメッセージキューはグローバルではなく、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の仕様に従ってインフライトウィンドウの最大長を設定し、以前のバージョンのMQTTプロトコルを使用するクライアントは設定に基づいて設定されます。
ただし、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 | クライアントがオフライン、インメモリ接続の送信キューが混雑、またはインフライトウィンドウが満杯の際に、EMQXがQoS 0メッセージをメッセージキューに格納するかどうかを指定します。 |