Message Distribution With Partitioned Queues

The event broker distributes messages to partitioned queues based on a key (the partition key) carried in the message. Client applications set this key at publish time. The event broker creates a hash of the partition key and uses that hash value to determine which partition a particular set of messages is sent to. All messages with the same key are handled by the same partition. Related events and their publishing sequences are maintained within a partition.

The diagram below shows messages being published to a partitioned queue. The different colors of the messages represent their partition key value. Each partition key value is mapped to one partition. However, a partition might be mapped to more than one partition key value.

Similarly, each partition is mapped to one consumer flow, but a flow might be mapped to multiple partitions.

A diagram illustrating the concepts discussed in the surrounding text.

Multiple consumers connect to the queue, with each consumer assigned to a different set of partitions. Only a single consumer is allowed to be assigned to and consume from any given partition; however, a single consumer might service multiple partitions. Because message sequence is not guaranteed between partitions, the consumer in this case can receive messages out of sequence (with respect to their publish sequence). Message sequence is guaranteed within a partition.

For the list of messaging APIs that support partitioned queues, see Feature Support in PubSub+ Messaging APIs.

Publishing to a Partitioned Queue

Producing applications set the partition key for the messages they publish. If a message is attracted to a partitioned queue, the hash of this key determines which partition the message is placed in. Depending on the subscription set and other configuration on the event broker, messages with a partition key could also be fanned out to other queues.

If a producing application sets a partition key, that key should have a sufficiently large range to produce an even distribution of hashed values that map to partitions.

If no partition key is provided in a message, that message is randomly assigned a partition.

The diagram below illustrates a sequence of messages arriving in the event broker, and then being fanned out to some queues, one of which is partitioned. In the partitioned queue, the key-to-partition mapping determines which messages go to which partitions.

A diagram illustrating the concepts discussed in the surrounding text.

Setting the Partition Key

SMF clients specify the partition key by setting the QUEUE_PARTITION_KEY user property of published messages. The mechanism for setting this property varies between APIs.

JMS clients set the JMSXGroupID property directly to provide the partition key.

For details and examples that show how SMF and JMS clients set the partition key, see Partition Key.

AMQP and MQTT clients can publish to (but not consume from) partitioned queues. For details, see Partitioned Queue Feature Interactions.

Consuming from a Partitioned Queue

From the perspective of the consuming application, receiving messages from a partitioned queue is no different than receiving messages from any other queue. The details of the individual partitions are handled transparently by the event broker and the PubSub+ Messaging APIs. Although the consumer has access to the key provided in the message by the publisher, it has no knowledge of which partition a message was delivered from, and has no means to request messages from any particular partition.

The event broker maps one or more partitions to each consumer flow. This partition-to-flow mapping is shown in the diagram below. A consuming application binds to the parent queue, providing its required properties, message receive callbacks, and so on. It has a single flow, but is delivered messages from one or more of the partitions of that queue.

A diagram illustrating the concepts discussed in the surrounding text.

Adding or removing consumers can cause Partition Rebalancing. Partition rebalancing is triggered when:

  • A new consumer binds to a partitioned queue that has fewer consumers than partitions. If there are already excess consumers, a new consumer bind does not trigger rebalancing.

  • An active consumer unbinds from a partitioned queue. That consumer's partitions are re-assigned to one or more of the other bound consumers after the rebalance timer expires.

Partition rebalancing often includes Partition Handoff as well, where the event broker moves partitions between consumer flows.

If there are more consumers than there are partitions, excess consumers will not take on any messaging load. However, excess consumers can play a standby role—if an active consumer fails, the flow of one of the excess consumers then becomes active and starts receiving messages.

Partition Status

A partition can have one of the following statuses:

  • Unassigned—The partition is not assigned to a consumer flow.
  • Ready—The partition is operating normally, delivering messages to the flow.
  • Paused—The partition is assigned to a flow, but is paused. New messages are not being sent to the flow.
  • Unbound—The partition is assigned to a flow, but that flow is not bound.

Outcomes of Consumer Loss

When a consuming client binds to a partitioned queue, the event broker returns the set of assigned partitions to the client in the bind response. Similarly, the API sends the mapping information back to the event broker in subsequent bind requests to try to re-establish the same partition mappings the flow had prior to disconnecting.

If a consumer that is assigned to a partition disconnects unexpectedly (for example, due to a temporary connectivity issue or an application crash), there are several possible outcomes:

  • The consumer application API reconnects before the rebalance timer (rebalance delay) expires.

    In this case, the API of the consumer application provides the set of mapped partitions (which it still knows), along with the queue name, in the new bind request. The event broker maps the new flow to the same partitions and starts delivering messages to the consumer immediately. In this case, there is no disruption to the flow of messages and the partition-to-flow mapping remains unchanged. The consumer gets the same partitions it had before being disconnected.

  • The consumer application restarts and reconnects before the rebalance timer expires.

    If the consumer restarts, the API cannot provide its previously mapped partition set (it has been lost due to the restart) in the bind request. The rebalance timer subsequently expires, and the event broker treats the consumer like a new client with no partition-mapping history. The event broker performs partition rebalancing, and assigns arbitrary partitions to the reconnected consumer.

  • The consumer application restarts and reconnects after the rebalance timer expires.

    When the rebalance timer expires, partitions are remapped among the consumer applications that are still connected. When the disconnected application reconnects, a second rebalancing is triggered, which now includes the newly connected flow. The second rebalancing is triggered even if the application sends its previous partition mapping (the previous mapping is ignored).

  • The consumer application never returns.

    A consumer application could remain disconnected due to a hardware failure or permanent crash. In this case, when rebalance timer expires, the partitions are remapped between the applications that are still connected.

For information about how applications can respond to partition handoffs, see Partition Handoff.