面试中经常被问到,如何保证kafka的消息顺序消费,当我回答了,使用一个分区后,也就是将需要保证顺序的消息发送到同一个分区,来保证的时候,面试官就说那你怎么保证性能?我说没法保证,然后就出门右拐了。 各位大佬能不能分析下?我也去知乎、csdn上看过一些,感觉内容很不负责任。
kafka的顺序保证
先回答第一个问题:
尽管kafka服务器保证了消息的顺序,消息还是异步的发送给各个消费者,消费者收到消息的先后顺序不能保证了。这也意味着并行消费将不能保证消息的先后顺序。
来自:kafka入门介绍
核心意思是:虽然服务端保障了消息的顺序,但是多个消费者程序的能力参差不齐,也会而导致顺序的错乱。
所以只能1个分区对应1个消费者,并且只有这种可能。
再来,性能问题
1个分区注定只能有1个消费者(多个消费者就是上面说的,还是会导致错乱)。
我们来想象一下需要强一致性的业务,AB、AB顺序不能乱,举个话费充值的场景,先扣款再充值,如果顺序乱了,充值后再扣款,如果扣款不成功就会导致资损。
一个消费者
那么,我们来尝试一下,只有一个消费者的情况下如何来提高性能,顺序拿到消息后,多线程? 很遗憾不行,多线程大家都明白是无序的(其实和多消费者一个道理)。
答案只有一个:顺序消费,一笔一笔的来。
将不同的业务发送到partition中?
不成立,那就是2个业务了,之间注定是没有耦合的,顺序根本谈不上了,所以也排除了。
根据业务时间戳?
也不行,因为你看不到整个消息的全貌,你怎么知道这条消息是最新的,也无法排序。
同一种业务再细分
将同一种业务,归类细分,比如手机号同一个地区的放到同一个分区里处理,这也是唯一能想到的基于业务拆分的性能提升方式了,kafka是做不到的。
最后
总接下来,通过kafka自身是无法做到的,只能在业务上动手脚(业务再细分),鱼和熊掌不可兼得。
半兽人就是面试官。
请出门往右走。
所以有大佬嘛,求个答案
你这样问让我很难过,我开始怀疑我是否解释清楚了,于是我又编辑了一下最后一句话,你看看是否是你要的答案:
确实,我刚才也想了一下,其实要有序只能在业务上做啊
我明白大佬的意思了,只是下次面试还是不知道怎么回怼。还有我看了上面那个大佬的讲解,我好像又多了一个疑问,就是一个topic下,假如有三个分区,如果有四个消费者,那么应该有一个消费者是不会消费任何内容吧,多出来这一个消费者并不会提高性能,是这样吧?
是的,多出来的,拿不到消息,也提高不了性能。
解法只有业务上做手脚。
比如还是手机充值业务,如果我把手机通过地区划分,这样在丢到不同的分区或者topic里,基于业务在细分,这样也算是提高了。
明白了,感谢大佬
你的答案