1. Message storage
- Within a single Broker instance, all queues share a single CommitLog file, in which all messages are written sequentially
- Through CommitLogDispatcher. Dispatch method distributed asynchronous requests and construct ComsumerQueue and IndexFile file
1) Flush disks synchronously
When the write success status is returned, the message has been written to disk. The specific process is that the message is written to the PAGECACHE of the memory, immediately notify the flush thread flush disk, and then wait for the completion of the flush disk, flush the completion of the thread to wake up the waiting thread, the message is written back to the state of success.
2) Asynchronous disk flushing
When the write success status is returned, the message may just be written to the PAGECACHE of the memory. The return of the write operation is fast and the throughput is large. When the amount of messages in the memory accumulates to a certain extent, the disk is written quickly
2. High availability
The RocketMQ distributed cluster achieves high availability through the combination of Master and Slave.
2.1 message consumption is highly available
In the Consumer configuration file, there is no need to set whether to read from the Master or Slave. When the Master is unavailable or busy, the Consumer is automatically switched to the Slave. With the automatic Consumer switching mechanism, if a Master machine fails, the Consumer can still read messages from the Slave without affecting the Consumer program. This is high availability on the consumer side.
2.2 Message sending is highly available
2.3. Load balancing
1. Sender load balancing
- On the Producer side, when sending messages, each instance polls all message queues by default so that the messages are evenly placed on different queues. Since queues can be scattered across different brokers, messages are sent to different brokers, as shown below:
The labels on the arrow lines in the figure represent the order, with publishers sending the first message to Queue 0, then the second message to Queue 1, and so on
2. Load balancing for the receiver
1) Cluster mode
-
In cluster consumption, each message needs to be delivered to only one instance of the Consumer Group that subscribes to the topic. RocketMQ uses an active pull to pull and consume messages, specifying which message queue to pull.
-
Every time the number of instances changes, load balancing is triggered, and the queue is evenly distributed to each instance according to the number of queues and the number of instances.
-
The default allocation algorithm is AllocateMessageQueueAveragely, the diagram below:
- There’s another average algorithm is AllocateMessageQueueAveragelyByCircle, evenly between each queue, is just in the form of circular queue in turn points, the following figure:
- A queue can only be allocated to one instance. This is because if multiple instances of a queue consume messages at the same time, the same message will be consumed multiple times by different instances because the consumer controls which messages are pulled. So the algorithm allocates a queue to only one consumer instance. A consumer instance can be placed in different queues at the same time.
2) Broadcast mode
- Since broadcast mode requires that a message be delivered to all consumer instances under a consumer group, there is no such thing as a message being distributed.
- One of the differences in implementation is that when consumers are assigned queues, all consumers are assigned to all queues.
3. Message retry
1, sequence message retry
For sequential messages, when the consumer fails to consume the message, the message queue RocketMQ automatically retries the message repeatedly (at an interval of 1 second), at which point the application will be blocked from consuming the message. Therefore, when using sequential messages, it is important to ensure that the application can monitor and handle consumption failures in a timely manner to avoid blocking.
2, unordered message retry
For unordered messages (normal, scheduled, delayed, transactional), you can achieve message retry results by setting the return status when the consumer fails to consume the message.
The retry of unordered messages takes effect only for cluster consumption. The broadcast mode does not provide the failure retry feature. That is, after a failure is consumed, the failed message is not retried and new messages are consumed.
1) Retry times
Message queue RocketMQ allows a maximum of 16 retries per message by default, with the following interval for each retry:
The number of retries | The interval since the last retry | The number of retries | The interval since the last retry |
---|---|---|---|
1 | 10 seconds | 9 | 7 minutes |
2 | 30 seconds | 10 | Eight minutes |
3 | 1 minute | 11 | 9 minutes |
4 | 2 minutes | 12 | Ten minutes |
5 | 3 minutes | 13 | Twenty minutes |
6 | 4 minutes | 14 | 30 minutes |
7 | 5 minutes | 15 | 1 hour |
8 | 6 minutes | 16 | 2 hours |
If the message fails after 16 retries, the message will not be delivered. If a message fails to be consumed, 16 retries will be performed within the next 4 hours and 46 minutes. The message will not be delivered again after the retry period.
Note: No matter how many times a Message is retried, the Message ID of those retried messages does not change.
4. Dead letter queues
When an initial consumption of a message fails, the message queue RocketMQ automatically retries the message. If the consumption fails after the maximum number of retries is reached, it indicates that the consumer was not able to consume the message correctly under normal circumstances. In this case, the message queue RocketMQ does not immediately discard the message, but instead sends it to a special queue for the consumer.
In Message queuing RocketMQ, such messages that can’t normally be consumed are called dead-letter messages, and the special queues that store dead-letter messages are called dead-letter queues.
1. Dead letter feature
Dead-letter messages have the following features
- It’s not going to be consumed by consumers.
- The validity period is the same as the normal message, which is 3 days. After 3 days, the message will be automatically deleted. Therefore, please process the dead letter message within 3 days after it is generated.
Dead letter queues have the following features:
- A dead letter queue corresponds to a Group ID, not to a single consumer instance.
- If a Group ID does not generate a dead letter message, message queue RocketMQ will not create a corresponding dead letter queue for it.
- A dead letter queue contains all the dead letter messages generated for the corresponding Group ID, regardless of the Topic to which the message belongs.
5. Idempotence of messages
-
The message was repeated when sent
When a message has been successfully sent to the server and persistence has been completed, the server fails to respond to the client due to intermittent network disconnection or client breakdown. If at this point the producer realizes that the Message failed and tries to send the Message again, the consumer will then receive two messages with the same content and the same Message ID.
-
Messages duplicate when delivered
In the message consumption scenario, the message has been delivered to the consumer and the service processing is complete. When the client sends a reply to the server, the network is intermittently disconnected. To ensure that the Message is consumed at least once, the RocketMQ server in the Message queue will try to deliver the previously processed Message again after the network is restored, and the consumer will then receive two messages with the same content and the same Message ID.
-
Message duplication during load balancing (including but not limited to network jitter, Broker restart, and subscriber application restart)
Rebalance is triggered when a RocketMQ Broker or client in the message queue restarts, expands or shrinks, and consumers may receive repeated messages.
Only a unique identifier can be used for restriction