普通人:
Kafka如何去保证消息的顺序性这个问题,我需要去保证那个消息应该是在同一个分区里面。
因为Kafka的消息的这个分区他是有序的然后我们去拿消息的时候是通过offset来拿嘛,所以我只要去保证这个消息存储到Partition里面的有序性就好了。
然后消费的时候我直接去指定那个Partition去消费就好了。
高手:
好的,这个问题我从两个方面来回答。
- kafka为什么会存在无序消费
- kafka如何保证有序消费
首先,在kafka的架构里面,用到了Partition分区机制来实现消息的物理存储,
在同一个topic下面,可以维护多个partition来实现消息的分片。
生产者在发送消息的时候,会根据消息的key进行取模,来决定把当前消息存储到哪个partition里面。
并且消息是按照先后顺序有序存储到partition里面的。
在这种情况下,假设有一个topic存在三个partition,而消息正好被路由到三个独立的partition里面。
然后消费端有三个消费者通过balance机制分别指派了对应消费分区。因为消费者是完全独立的网络节点,
所有可能会出现,消息的消费顺序不是按照发送顺序来实现的,从而导致乱序的问题。
针对这个问题,一般的解决办法就是自定义消息分区路由的算法,然后把指定的key都发送到同一个Partition里面。
接着指定一个消费者专门来消费某个分区的数据,这样就能保证消息的顺序消费了。
另外,有些设计方案里面,在消费端会采用异步线程的方式来消费数据来提高消息的处理效率,那这种情况下,
因为每个线程的消息处理效率是不同的,所以即便是采用单个分区的存储和消费也可能会出现无序问题,
针对这个问题的解决办法就是在消费者这边使用一个阻塞队列,把获取到的消息先保存到阻塞队列里面,然后异步线程从阻塞队列里面去获取消息来消费。
以上就是我对这个问题的理解。
总结
关于这个问题,有些面试官还会这样问: 如果我不想把消息路由到同一个分区,但是还想实现消息的顺序消费,怎么办?
严格来说,kafka只能保证同一个分区内的消息存储的有序性。
如果一定要去实现,也不是不行,只是代价太大了没必要。