When a producer sends messages to ApsaraMQ for RocketMQ, ApsaraMQ for RocketMQ evenly distributes them to individual queues based on the load balancing policy that is configured for the producer. This helps prevent overloaded queues and performance bottleneck issues. This topic describes the load balancing policies provided by ApsaraMQ for RocketMQ for producers.

Background information

Familiarizing yourself with the load balancing policies provided by ApsaraMQ for RocketMQ can help you determine the appropriate measures to take when confronted with the following scenarios:
  • Disaster recovery: You can determine how messages are switched over when local nodes fail.
  • Message ordering: You can better understand how ApsaraMQ for RocketMQ ensures strict first-in-first-out message ordering.
  • Load balancing: You can understand the distribution pattern of messages across multiple nodes and configure suitable traffic migration and scaling solutions.

Round robin

Usage scope

Round-robin load balancing is the default load balancing policy and the only load balancing policy that is supported for unordered messages (normal, scheduled, and transactional messages) in ApsaraMQ for RocketMQ.

How the policy works

In round-robin load balancing, a producer sends messages to all queues in a specified topic in a cycle to ensure that messages are evenly distributed across all the queues in the topic.

Load balancing policy for producers

In the preceding figure, Queue 1, Queue 2, and Queue 3 are queues in the topic, and the combination of the letter M and a number indicates a message that is sent in order.

The producer sends messages to the queues in a cycle. The producer sends the first message M1 to Queue 1, the second message M2 to Queue 2, and the third message M3 to Queue 3, and then repeats the distribution pattern until all messages are sent.

Exception handling

When a message fails to be delivered to a queue, ApsaraMQ for RocketMQ determines whether to skip the node where the queue resides for a specified period of time based on the cause of the delivery failure. This way, you can implement automated fault isolation.

Features

Round-robin load balancing is supported for only unordered messages. This policy ensures that messages are evenly distributed to maximize the performance of topics.

Example

By default, round-robin load balancing is enabled for unordered messages. The following sample code provides an example of round-robin load balancing:

// By default, round-robin load balancing is enabled for normal messages. 

        // Send normal messages. 
        MessageBuilder messageBuilder = null;
        for (int i = 0; i < 10; i++) {
            // You do not need to configure round-robin load balancing to deliver normal messages. The SDK includes the logic that is required to perform round-robin messaging to evenly distribute messages. 
            Message message = messageBuilder.setTopic("normalTopic")
                    // Specify the message index key so that the system can use a keyword to accurately locate the message. 
                    .setKeys("messageKey")
                    // Specify the message tag so that consumers can use the tag to filter the message. 
                    .setTag("messageTag")
                    // Configure the message body. 
                    .setBody("messageBody".getBytes())
                    .build();
            try {
                // Send the messages. Focus on the result of message sending and exceptions such as failures. 
                SendReceipt sendReceipt = producer.send(message);
                System.out.println(sendReceipt.getMessageId());
            } catch (ClientException e) {
                e.printStackTrace();
            }
        }


         

MessageGroupHash

Usage scope

MessageGroupHash-based load balancing is the default load balancing policy and the only load balancing policy that is supported for ordered messages in ApsaraMQ for RocketMQ.

How the policy works

MessageGroupHash-based load balancing uses a SipHash algorithm to distribute messages. In the MessageGroupHash-based load balancing mode, a producer sends messages in the same message group to the same queue based on the built-in SipHash algorithm and ensures that messages in the same message group are stored in the queue in the order in which the messages are sent.

Note For more information, see SipHash.
SipHash algorithm-based distribution

In the preceding figure, G1-M1 is the first message in MessageGroup 1, G1-M2 is the second message, and G1-M3 is the third message. The producer sends the messages to the same queue (MessageQueue 1) and ensures that the three messages are stored in the queue in the same order in which the messages are sent.

Features

MessageGroupHash-based load balancing is supported for only ordered messages. This load balancing policy ensures the ordered delivery of messages in the same message group.

If the numbers of messages in multiple message groups are significantly different, MessageGroupHash-based load balancing cannot ensure even distribution of messages across and performance scaling. In specific scenarios, MessageGroupHash-based load balancing may cause most messages to be stored in a small number of queues. We recommend that you distribute the messages across multiple message groups to prevent a large number of messages from being stored in a small number of message groups.

Example

By default, MessageGroupHash-based load balancing is enabled for ordered messages. The following sample code provides an example of MessageGroupHash-based load balancing:

// By default, MessageGroupHash-based load balancing is enabled for ordered messages. 

for (int i = 0; i < 10; i++) {
            Message message = messageBuilder.setTopic("fifoTopic")
                    // Specify the message index key so that the system can use a keyword to accurately locate the message. 
                    .setKeys("messageKey")
                    // Specify the message tag so that the consumer can filter the message based on the specified tag. 
                    .setTag("messageTag")
                    // Configure MessageGroup. Messages in the same message group are distributed to the same queue based on the SipHash algorithm. 
                    .setMessageGroup("fifoGroupA")
                    // Configure the message body. 
                    .setBody("messageBody".getBytes())
                    .build();
            try {
                // Send the messages. Focus on the result of message sending and exceptions such as failures. 
                SendReceipt sendReceipt = producer.send(message);
                System.out.println(sendReceipt.getMessageId());
            } catch (ClientException e) {
                e.printStackTrace();
            }
        }

Version compatibility

  • MessageGroupHash

    MessageGroupHash-based load balancing is supported in ApsaraMQ for RocketMQ version 5.0 and later. ApsaraMQ for RocketMQ versions 4.x and 3.x do not support this feature.

    If you update ApsaraMQ for RocketMQ from version 4.x or 3.x to version 5.x, make sure that ordered messages use the same sending mechanism to prevent message ordering issues. For example, you can wait for consumers to consume all messages in a topic in Message Queue for RocketMQ version 4.x or 3.x before you update to version 5.x.

  • Round robin

    Round-robin load balancing does not cause version compatibility issues to occur. Round-robin load balancing is supported in Message Queue for RocketMQ versions 3.x, 4.x and 5.x.

Usage notes

Avoid overloading queues when you use MessageGroupHash-based load balancing

In the MessageGroupHash-based load balancing mode, ApsaraMQ for RocketMQ delivers messages in the same message group to the same queue. If most messages are stored in one or more message groups on the producer application side, ApsaraMQ for RocketMQ delivers the messages to one or more queues. This affects storage performance on the server side, causes queue overloading, and hinders scalability of topic performance.

We recommend that you distribute the messages across multiple message groups. For example, you can use order IDs and usernames as the keywords of message groups in e-commerce scenarios to ensure that messages are distributed among multiple message groups and that user-specific messages are processed in order.

Avoid sending messages to one queue

To ensure performance scaling and disaster recovery, we recommend that you use more than one queue for load balancing for ordered messages and unordered messages. If a topic contains only one queue, messages are sent only to the queue, regardless of the load balancing policy. This can cause performance bottleneck issues and disaster recovery issues.