Kafka 消息顺序
Kafka 消息顺序
简介
在需要保证消息顺序的情况下应当采用如下的方式使用 Kafka。
概念说明
在 Kafka 中每个 topic
会有一个或多个 partition
,而在含有多个 partition
的情况下就无法保证消息有序了。
那我们可以通过限制 partition
数量的方式来确保顺序。
注: 由于 Kafka 的分区数量可以增加所以此处还需额外针对
key
和partition
进行维护。
官方说明
1 |
|
注:节选自 Kafka 官方文档 1.1 节
Main Concepts and Terminology
实现方式
所以可以得出以下结论:
在同 key
在同个 partition
中,Kafka 的消息顺序是可以保证的。
所以在实际使用中,我们可以为需要排序的内容指定 partition
的方式来确保消息顺序。
可能遇到的问题
当 Kafka 在遇到消息发送失败的情况下会进行如下图所示的重试:
而这种情况又会导致 乱序。
为了解决此问题有两种解决方案:
- 抛弃重试策略 (不可接受)
- 在重试时不接受其他消息
在《Kafka 权威指南》这本书里的描述是这样的:
Kafka 可以保证同一个分区里的消息是有序的。也就是说,如果生产者按照 一定的顺序发送消息,broker 就会按照这个顺序把它们写入分区,消费者也 会按照同样的顺序读取它们。在某些情况下,顺序是非常重要的。例如,往 一个账户存入 100 元再取出来,这个与先取钱再存钱是截然不同的!不过, 有些场景对顺序不是很敏感。 如果把 retries 设为非零整数,同时把 max.in.flight.requests.per.connection 设为比 1 大的数,那么,如果第一个批次消息写入失败,而第二个批次写入 成功,broker 会重试写入第一个批次。如果此时第一个批次也写入成功,那 么两个批次的顺序就反过来了。 一般来说,如果某些场景要求消息是有序的,那么消息是否写入成功也是 很关键的,所以不建议把 retries 设为 0。可以把 max.in.flight.requests. per.connection 设为 1,这样在生产者尝试发送第一批消息时,就不会有其 他的消息发送给 broker。不过这样会严重影响生产者的吞吐量,所以只有在 对消息的顺序有严格要求的情况下才能这么做。
参考资料
注:《Kafka 权威指南》有中文版