消息分区机制,基于因果关系的消息顺序消费

消息分区策略

这里不是说Kafka的主题为什么要分区,而是说在分区的结构下,如何让具有某种特点的消息发送到特定分区。

这里有一个很明显的问题,就是主题分区,那么生产者发送的消息到底被发送到了哪个分区呢?一般我们都知道有轮询机制或者是随机机制,这两种机制都比较好理解。而且Kafka也都支持,在新版本中默认使用的是轮询机制,如下图所示:

kafka 消息指定分区 kafka分区消息堆积不消费_新版本

但是在某些场景下我们需要控制某种类型的消息发送到特定分区或者说我们需要严格的进行消息的顺序消费,也就是说这些消息有因果关系,要想消费下一条必须先要消费前一条。消费者消费某个分区的消息肯定是顺序消费,但是由于消息不是顺序进入分区的,你可以从上图看到0002消息并不是在0001消息之后,这就导致有可能消费者程序先消费了0002。如果这些消息没有因果关系那么则没问题,只要保证消费者都消费完就可以了至于先后顺序无需关心。但是如果有因果关系就不行,这样会造成混乱。

要想实现因果关系的消费可以有2个办法

单分区模式

kafka 消息指定分区 kafka分区消息堆积不消费_python_02

我们创建一个具有单分区的主题,这样消息就顺序进入分区,消费者也就顺序消费。这样实现了全局顺性,不过这样就降低了吞吐量。

基于消息Key的分区策略

kafka 消息指定分区 kafka分区消息堆积不消费_kafka 消息指定分区_03

这种就是为消息设置Key,Key相同的发送到同一分区。要注意这里虽然是多个分区看似吞吐量增加,但是你可以设想一下如果你的因果消息Key都一样那么这种模式和上面的单分区模式其实一样。如果你的因果消息可以继续细分为几个不同的Key,那么在多分区模式下相对于整体来讲吞吐量是提高的。

如何使用

kafka-python 模块的使用

Java客户端的使用