tencent cloud

Subscription Mode
Last updated:2025-12-24 15:03:03
Subscription Mode
Last updated: 2025-12-24 15:03:03
To meet the needs of different scenarios, Pulsar supports four subscription modes: Exclusive, Shared, Failover, and Key_Shared.

Subscription modes



Exclusive Mode

Exclusive mode (default mode): A subscription can only be associated with one consumer, and only this consumer can receive all messages in the topic. If the consumer encounters a fault, consumption stops.
In Exclusive mode, only one consumer in a subscription can consume messages in the topic. If multiple consumers subscribe to the topic, an error is reported. This mode is suitable for globally sequential consumption scenarios.

Exclusive mode diagram


// Construct a consumer.
Consumer<byte[]> consumer = pulsarClient.newConsumer()
// Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page.
.topic("persistent://pulsar-xxx/sdk_java/topic1")
// You need to create a subscription on the topic details page in the console. Specify the subscription name here.
.subscriptionName("sub_topic1")
// Declare the consumption mode to be the Exclusive mode.
.subscriptionType(SubscriptionType.Exclusive)
.subscribe();
If multiple consumers are started, an error message will be received, as shown in the following figure:



Shared Mode

Messages are distributed to different consumers through the round-robin scheduling mechanism (customizable), and each message is distributed only to one consumer. When a consumer disconnects, all messages that were sent to the consumer but have not been acknowledged are rescheduled and distributed to other active consumers.

Shared mode diagram


// Construct a consumer.
Consumer<byte[]> consumer = pulsarClient.newConsumer()
// Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page.
.topic("persistent://pulsar-xxx/sdk_java/topic1")
// You need to create a subscription on the topic details page in the console. Specify the subscription name here.
.subscriptionName("sub_topic1")
// Declare the consumption mode to be the Shared mode.
.subscriptionType(SubscriptionType.Shared)
.subscribe();
The following figure shows multiple consumers in Shared mode.



Failover Mode

When multiple consumers exist in this mode, they are ordered lexicographically, and the first consumer is initialized as the sole receiver of messages. If the first consumer disconnects, all messages (both unacknowledged and new ones) are distributed to the next consumer in the queue.

Failover mode diagram


// Construct a consumer.
Consumer<byte[]> consumer = pulsarClient.newConsumer()
// Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page.
.topic("persistent://pulsar-xxx/sdk_java/topic1")
// You need to create a subscription on the topic details page in the console. Specify the subscription name here.
.subscriptionName("sub_topic1")
// Declare the consumption mode to be the Failover mode.
.subscriptionType(SubscriptionType.Failover)
.subscribe();
The following figure shows multiple consumers in Failover mode.



Key_Shared Mode

When multiple consumers exist in this mode, messages are distributed based on their keys. Messages with the same key are distributed to the same consumer.

Key_Shared mode diagram


Note:
The Key_Shared mode has usage limits. Its engineering implementation is complex, and there are continuous improvements and optimizations to features of the Key_Shared mode in the Apache Pulsar iterations. Its overall stability is weaker compared to the three subscription modes: Exclusive, Failover, and Shared. Preferentially select the preceding three modes if they can meet business requirements.
In pro clusters, messages with the same key can be delivered sequentially. In virtual clusters, the message delivery sequence cannot be guaranteed.

Usage Suggestions for the Key_Shared Mode

When to Use the Key_Shared Mode

Select the Shared mode for general production/consumption scenarios.
To distribute messages with the same key to the same consumer, you cannot use the Shared mode. You have two options:
Select the Key_Shared mode.
Use a multi-partition topic and the Failover mode.

Scenarios to Use the Key_Shared Mode

A lot of message keys exist, and messages of each key are evenly distributed.
Consumption is fast without a message backlog.
If either of the preceding two conditions is not met in the production process, it is recommended that a multi-partition topic and the Failover mode be used.

Sample Code

Sample Subscription in Key_Shared Mode

By default, the batch feature is enabled for TDMQ for Apache Pulsar during message production, and batch messages are parsed on the consumer side. Therefore, a batch of messages is treated as one entry on the broker side. Since messages with different keys may be packaged into the same batch, the Key_Shared mode becomes ineffective in this case because it achieves sequential subscription based on the message key. There are two ways to avoid this when you create a producer:
1. Disable the batch feature.
// Construct a producer.
Producer<byte[]> producer pulsarClient.newProducer()
.topic(topic)
.enableBatching(false)
.create();
// Set the key when messages are sent.
MessageId msgId = producer.newMessage()
// The message content.
.value(value.getBytes(StandardCharsets.UTF_8))
// Set the key here. Messages with the same key are distributed only to the same consumer.
.key("youKey1")
.send();
2. Use the key_based batch type.
// Construct a producer.
Producer<byte[]> producer = pulsarClient.newProducer()
.topic(topic)
.enableBatching(true)
.batcherBuilder(BatcherBuilder.KEY_BASED)
.create();
// Set the key when messages are sent.
MessageId msgId = producer.newMessage()
// The message content.
.value(value.getBytes(StandardCharsets.UTF_8))
// Set the key here. Messages with the same key are distributed only to the same consumer.
.key("youKey1")
.send();
Sample code for message consumption:
// Construct a consumer. Consumer<byte[]> consumer = pulsarClient.newConsumer() // Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page. .topic("persistent://pulsar-xxx/sdk_java/topic1") // Create a subscription on the topic details page in the console. Specify the subscription name here. .subscriptionName("sub_topic1") // Declare the consumption mode to be the Key_Shared mode. .subscriptionType(SubscriptionType.Key_Shared) .subscribe();
The following figure shows multiple consumers in the Key_Shared mode.



Sample in the Multi-Partition Topic and Failover Mode

Must-Knows:
In this mode, each partition is assigned only to one consumer instance at a time. When there are more consumers than partitions, the excess consumers cannot consume messages. This problem can be solved by adding more partitions than consumers.
Try to ensure that keys are evenly distributed during key design.
Delayed messages are not supported in Failover mode.
1. Sample code for message production
// Construct a producer.
Producer<byte[]> producer pulsarClient.newProducer()
.topic(topic)
.enableBatching(false) // Disable the batch feature.
.create();
// Set the key when messages are sent.
MessageId msgId = producer.newMessage()
// The message content.
.value(value.getBytes(StandardCharsets.UTF_8))
// Set the key here. Messages with the same key are sent to the same partition.
.key("youKey1")
.send();
2. Sample code for message consumption
// Construct a consumer.
Consumer<byte[]> consumer = pulsarClient.newConsumer()
// Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page.
.topic("persistent://pulsar-xxx/sdk_java/topic1")
// You need to create a subscription on the topic details page in the console. Specify the subscription name here.
.subscriptionName("sub_topic1")
// Declare the consumption mode to be the Failover mode.
.subscriptionType(SubscriptionType.Failover)
.subscribe();

Enable Message Ordering

Clusters of TDMQ for Apache Pulsar 2.9.2 support key-based sequential message delivery. To enable this feature, specify keySharedPolicy when creating a consumer instance.
// Construct a consumer.
Consumer<byte[]> consumer = pulsarClient.newConsumer()
// Full topic path, in the format of persistent://cluster (tenant) ID/namespace/topic name, copied from the Topic page.
.topic("persistent://pulsar-xxx/sdk_java/topic1")
// You need to create a subscription on the topic details page in the console. Specify the subscription name here.
.subscriptionName("sub_topic1")
// Declare the consumption mode to be the Key_Shared mode.
.subscriptionType(SubscriptionType.Key_Shared)
// Disallow out-of-order delivery.
.keySharedPolicy(KeySharedPolicy.autoSplitHashRange().setAllowOutOfOrderDelivery(false))
.subscribe();
Note:
Clusters of TDMQ for Apache Pulsar 2.7.2 do not support message ordering because it may cause message push blocking and consumption failures.
When message ordering is enabled, consumption rate decreases and message backlogs may occur after the consumer restarts. In message ordering mode, a new consumer can consume subsequent messages only after all messages produced before its launch are fully consumed (acknowledged).

Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback