在某些业务场景下,我们需要保证对于有逻辑关联的多条
MQ
消息被按顺序处理,比如对于某一条数
据,正常处理顺序是
新增
-
更新
-
删除
,最终结果是数据被删除;如果消息没有按序消费,处理顺序可能
是
删除
-
新增
-
更新
,最终数据没有被删掉,可能会产生一些逻辑错误。对于如何保证消息的顺序性,主要
需要考虑如下两点:
如何保证消息在
Kafka
中顺序性;
如何保证消费者处理消费的顺序性。
如何保证消息在
Kafka
中顺序性
对于
Kafka
,如果我们创建了一个
topic
,默认有三个
partition
。生产者在写数据的时候,可以指
定一个
key
,比如在订单
topic
中我们可以指定订单
id
作为
key
,那么相同订单
id
的数据,一定
会被分发到同一个
partition
中去,而且这个
partition
中的数据一定是有顺序的。消费者从
partition
中取出来数据的时候,也一定是有顺序的。通过制定
key
的方式首先可以保证在
kafka
内部消息是有序的。
如何保证消费者处理消费的顺序性
对于某个
topic
的一个
partition
,只能被同组内部的一个
consumer
消费,如果这个
consumer
内部还是单线程处理,那么其实只要保证消息在
MQ
内部是有顺序的就可以保证消费也是有顺序的。但
是单线程吞吐量太低,在处理大量
MQ
消息时,我们一般会开启多线程消费机制,那么如何保证消息在
多个线程之间是被顺序处理的呢?对于多线程消费我们可以预先设置
N
个内存
Queue
,具有相同
key
的数据都放到同一个内存
Queue
中;然后开启
N
个线程,每个线程分别消费一个内存
Queue
的数据
即可,这样就能保证顺序性。当然,消息放到内存
Queue
中,有可能还未被处理,
consumer
发生宕
机,内存
Queue
中的数据会全部丢失,这就转变为上面提到的
如何保证消息的可靠传输
的问题了。