Thursday, April 16, 2015

Internet of Things MQTT Quality of Service Levels


Next week Red Hat is hosting a Virtual Event,
Building Data-driven Solutions for the Internet of Things.  I am presenting a session on Connect to the IoT with a lightweight protocol: MQTT so I wanted to do some articles on MQTT Basics this week.  Also,  you can visit the Red Hat IoT pages for more insight on IoT.

Message Queue Telemetry Transport (MQTT) is a Client Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and designed so as to be easy to implement. These characteristics make it ideal for use in many situations, including constrained environments such as for communication in Machine to Machine (M2M) and Internet of Things (IoT) contexts where a small code footprint is required and/or network bandwidth is at a premium.   The protocol runs over TCP/IP, or over other network protocols that provide ordered, lossless, bi-directional connections.

MQTT supports three quality of service levels as seen in the diagram above:
  1. Delivered at most once (Fire and forget) which means no confirmation
  2. Delivered at least once, which means confirmation required
  3. Delivered exactly once, which means a 4 step handshake is done
The QoS defines how hard the broker/client will work or attempt to ensure that a message is received. Messages can be sent at any QoS level, and clients may attempt to subscribe to topics at any QoS level, which means that the client chooses the maximum QoS level they will receive. 

For example, if a message is published at QoS 2 and a client is subscribed with QoS 0, the message will be delivered to that client with QoS 0. If a second client is also subscribed to the same topic, but with QoS 2, then it will receive the same message but with QoS 2.

Another example could be if a client is subscribed with QoS 2 and a message is published on QoS 0, the client will receive it on QoS 0. Higher levels of QoS are more reliable, but involve higher latency and have higher bandwidth requirements.

More detail on each QoS is below.  The MQTT Control Packet table is at the bottom of the article describes the control packets from each QoS flow.

Quality of Service Level 0
The message is delivered at most once, or it is not delivered at all which means the delivery across the network is not acknowledged.  The message is NOT stored.   The message might be lost if the client is disconnected, or if the server fails.  This is is the fastest mode of transfer.   The MQTT protocol does not require servers to forward publications at QoS=0 to a client.   If the client is disconnected at the time the server receives the publication, the publication might be discarded, depending on the server. The telemetry (MQXR) service does not discard messages sent with QoS=0. They are stored as nonpersistent messages, and are only discarded if the queue manager stops.   

In the QoS 0 delivery protocol, the Sender:  MUST send a PUBLISH packet with QoS=0, DUP=0

In the QoS 0 delivery protocol, the Receiver:  Accepts ownership of the message when it receives the PUBLISH packet.

Quality of Service Level 1
The message is always delivered at least once.   If the sender does not receive an acknowledgment, the message is sent again with the DUP flag set until an acknowledgment is received.   As a result receiver can be sent the same message multiple times, and might process it multiple times.   The message must be stored locally at the sender and the receiver until it is processed.  The message is deleted from the receiver after it has processed the message. If the receiver is a broker, the message is published to its subscribers. If the receiver is a client, the message is delivered to the subscriber application. After the message is deleted, the receiver sends an acknowledgment to the sender.
The message is deleted from the sender after it has received an acknowledgment from the receiver. 

This level could be used, for example, with ambient sensor data where it does not matter if an individual reading is lost as the next one will be published soon after.

In the QoS 1 delivery protocol, the Sender:
-MUST assign an unused Packet Identifier each time it has a new Application Message to publish.
-MUST send a PUBLISH Packet containing this Packet Identifier with QoS=1, DUP=0.
-MUST treat the PUBLISH Packet as “unacknowledged” until it has received the corresponding PUBACK packet from the receiver.

The Packet Identifier becomes available for reuse once the Sender has received the PUBACK Packet.  Note that a Sender is permitted to send further PUBLISH Packets with different Packet Identifiers while it is waiting to receive acknowledgements.

In the QoS 1 delivery protocol, the Receiver:
-MUST respond with a PUBACK Packet containing the Packet Identifier from the incoming PUBLISH Packet, having accepted ownership of the Application Message
-After it has sent a PUBACK Packet the Receiver MUST treat any incoming PUBLISH packet that contains the same Packet Identifier as being a new publication, irrespective of the setting of its DUP flag.

Quality of Service Level 2
The message is always delivered exactly once.   The message must be stored locally at the sender and the receiver until it is processed.   QoS=2 is the safest, but slowest mode of transfer.   It takes at least two pairs of transmissions between the sender and receiver before the message is deleted from the sender.  The message can be processed at the receiver after the first transmission.   In the first pair of transmissions, the sender transmits the message and gets acknowledgment from the receiver that it has stored the message.   If the sender does not receive an acknowledgment, the message is sent again with the DUP flag set until an acknowledgment is received.   In the second pair of transmissions, the sender tells the receiver that it can complete processing the message, PUBREL.   If the sender does not receive an acknowledgment of the PUBREL message, the PUBREL message is sent again until an acknowledgment is received. The sender deletes the message it saved when it receives the acknowledgment to the PUBREL message.   The receiver can process the message in the first or second phases, provided that it does not reprocess the message. If the receiver is a broker, it publishes the message to subscribers.   If the receiver is a client, it delivers the message to the subscriber application.   The receiver sends a completion message back to the sender that it has finished processing the message.  

This level could be used, for example, with billing systems where duplicate or lost messages could lead to incorrect charges being applied.

In the QoS 2 delivery protocol, the Sender:
-MUST assign an unused Packet Identifier when it has a new Application Message to publish.
-MUST send a PUBLISH packet containing this Packet Identifier with QoS=2, DUP=0.
-MUST treat the PUBLISH packet as “unacknowledged” until it has received the corresponding PUBREC packet from the receiver.
-MUST send a PUBREL packet when it receives a PUBREC packet from the receiver. This PUBREL packet MUST contain the same Packet Identifier as the original PUBLISH packet.
-MUST treat the PUBREL packet as “unacknowledged” until it has received the corresponding PUBCOMP packet from the receiver.
-MUST NOT re-send the PUBLISH once it has sent the corresponding PUBREL packet.

The Packet Identifier becomes available for reuse once the Sender has received the PUBCOMP Packet.  Note that a Sender is permitted to send further PUBLISH Packets with different Packet Identifiers while it is waiting to receive acknowledgements.

In the QoS 2 delivery protocol, the Receiver:
-MUST respond with a PUBREC containing the Packet Identifier from the incoming PUBLISH Packet, having accepted ownership of the Application Message.
-Until it has received the corresponding PUBREL packet, the Receiver MUST acknowledge any subsequent PUBLISH packet with the same Packet Identifier by sending a PUBREC. It MUST NOT cause duplicate messages to be delivered to any onward recipients in this case.
-MUST respond to a PUBREL packet by sending a PUBCOMP packet containing the same Packet Identifier as the PUBREL.
-After it has sent a PUBCOMP, the receiver MUST treat any subsequent PUBLISH packet that contains that Packet Identifier as being a new publication.

MQTT Control Packet Descriptions
References:
OASIS Documents:
-http://docs.oasis-open.org/mqtt/mqtt/v3.1.1
-https://www.oasis-open.org/standards#mqttv3.1.1
Some info pulled from BB Smartworx and IBM Developer Works