最近很多同学去面试,都被问到“MQ如何保证消费顺序性”这样一个问题

很多人都没回到上来,特别是面试官在面试的时候,还会再补充一句:“还有没有其他方案”。

然后求职者一脸懵逼,实在不知道该怎么回答。

Hi,大家好,我是Mic,一个工作了14年的程序员和创业者。

今天我们来分析一道 这样的面试题,“MQ是如何保证消费顺序性”

下面看看普通人和高手对这个问题的回答。

需要高手面试文档(附赠大厂内部十万字面试文档)或者有不懂的技术面试题想咨询的小伙伴可以后台私信【Mic】或者评论区留言。

普通人:

Kafka如何去保证消息的顺序性这个问题,我需要去保证那个消息应该是在同一个分区里面。

因为Kafka的消息的这个分区他是有序的然后我们去拿消息的时候是通过offset来拿嘛,所以我只要去保证这个消息存储到Partition里面的有序性就好了。

然后消费的时候我直接去指定那个Partition去消费就好了。

高手:

好的,这个问题我从两个方面来回答。

  • kafka为什么会存在无序消费

  • kafka如何保证有序消费

首先,在kafka的架构里面,用到了Partition分区机制来实现消息的物理存储

在同一个topic下面,可以维护多个partition来实现消息的分片。

生产者在发送消息的时候,会根据消息的key进行取模,来决定把当前消息存储到哪个partition里面。

并且消息是按照先后顺序有序存储到partition里面的。

在这种情况下,假设有一个topic存在三个partition,而消息正好被路由到三个独立的partition里面。

然后消费端有三个消费者通过balance机制分别指派了对应消费分区。因为消费者是完全独立的网络节点,

所有可能会出现,消息的消费顺序不是按照发送顺序来实现的,从而导致乱序的问题。

针对这个问题,一般的解决办法就是自定义消息分区路由的算法,然后把指定的key都发送到同一个Partition里面。

接着指定一个消费者专门来消费某个分区的数据,这样就能保证消息的顺序消费了。

另外,有些设计方案里面,在消费端会采用异步线程的方式来消费数据来提高消息的处理效率,那这种情况下,

因为每个线程的消息处理效率是不同的,所以即便是采用单个分区的存储和消费也可能会出现无序问题,

针对这个问题的解决办法就是在消费者这边使用一个阻塞队列,把获取到的消息先保存到阻塞队列里面,然后异步线程从阻塞队列里面去获取消息来消费。

以上就是我对这个问题的理解。

总结

关于这个问题,有些面试官还会这样问: 如果我不想把消息路由到同一个分区,但是还想实现消息的顺序消费,怎么办?

严格来说,kafka只能保证同一个分区内的消息存储的有序性。

如果一定要去实现,也不是不行,只是代价太大了没必要。

虽然没有标准答案,但是面试官要这么问,无非就是想考察你面对复杂问题的时候是如何思考的,以及你的技术底蕴怎么样。

大家记得点赞收藏加关注。

需要高手面试文档(附赠大厂内部十万字面试文档)或者有不懂的技术面试题想咨询的小伙伴可以扫描下方二维码

↓↓↓↓↓↓↓↓↓↓↓↓↓↓

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐