Kafka 消息队列如何保证顺序性?

爱被打了一巴掌 2021-09-25 03:04 609阅读 0赞

主要思路:相同key值的消息写入同一个partition(partition内的消息是有序的),一个partition的消息只会被一个消费者消费。

如果一个消费者是多个线程消费,则需要把pull来的消息按照key值写入不同的内存队列中,相同key值的消息写入同一个内存队列(内存队列内的消息是有序的),然后一个线程消费一个内存队列。

1、rabbitMq
问题分析:
imagepng
如图,data1 和 data2 是有顺序的,必须 data1 先执行,data2 后执行;这两个数据被不同的消费者消费到了,可能 data2 先执行,data1 后执行,这样原来的顺序就错乱了。

解决方案:
imagepng
如图,在 MQ 里面创建多个 queue,同一规则的数据(对唯一标识进行 hash),有顺序的放入 MQ 的 queue 里面,消费者只取一个 queue 里面获取数据消费,这样执行的顺序是有序的。或者还是只有一个 queue 但是对应一个消费者,然后这个消费者内部用内存队列做排队,然后分发给底层不同的 worker 来处理。

2、kafka
问题分析:
imagepng
如图,在 kafka 中,你对数据指定某个 key,那么这些数据会到同一个 partition 里面,在 partition 里面这些数据是有顺序的。从这里看没啥问题,插入到数据库的数据都是有序的。

但是,我们在消费端可能会使用多线程来处理,因为单线程的处理速度慢,为了加快处理时间和吞吐量,会使用 thread 来处理。在消费端加入线程之后,就会出现顺序不一致的情况。
imagepng
如图,就是使用了多线程之后,数据顺序不一致情况。

在使用了多线程之后,如何来解决数据顺序问题?
imagepng
如图,在消费端使用内存队列,队列里的数据使用 hash 进行分发,每个线程对应一个队列,这样可以保证数据的顺序。

3、rocketMq
imagepng

如图,生产者中把 orderId 进行取模,把相同模的数据放到 messagequeue 里面,消费者消费同一个 messagequeue,只要消费者这边有序消费,那么可以保证数据被顺序消费。

4、activeMq
imagepng
如图,activeMq 里面有 messageGroups 属性,可以指定 JMSXGroupID,消费者会消费指定的 JMSXGroupID。即保证了顺序性,又解决负载均衡的问题。

转自:https://www.pianshen.com/article/4100479924/

发表评论

表情:
评论列表 (有 0 条评论,609人围观)

还没有评论,来说两句吧...

相关阅读

    相关 如何保证消息顺序

    场景: 在一个订单场景中,本来我们期望的是订单生成,订单支付,订单完成这样一个流程下来,但是消费者一般部署集群,多个消费者消费一个队列queue,很可能订单支付在订单完成前

    相关 kafka保证消息顺序

    顺序保证 Kafka 可以保证同一个分区里的消息是有序的。也就是说,如果生产者按照一定的顺序发送消息,broker 就会按照这个顺序把它们写入分区,消费者也会按照同样的顺序

    相关 如何保证消息顺序

    如何保证消息的顺序性?其实这个也是用 MQ 的时候必问的话题,第一看看你了不了解顺序这个事儿?第二看看你有没有办法保证消息是有顺序的?这是生产系统中常见的问题。 剖析