赞
踩
首先,在Kafka的整个架构里面,用到Partition的分区机制来去实现消息的物理存储。
也就是说在同一个topic里面,可以维护多个Partition,来去实现消息的一个分片。
那么生产者在发送消息的时候会根据消息的key来进行取模,把当前的消息存储到哪一个Partition里面。
而且消息是按照先后有序的去存储在Partition里面,那么在这种情况下呢,假设一个topic里面有三个Partition,而消息正好被路由到三个独立的Partition里面。然后消费端有三个消费者去通过balance的一个机制去分别指派了对应的消费分区。因为消费者是完全独立的一个网络节点,所以可能会出现消息的消费顺序不是按照发送顺序来实现的,从而导致消息的消费乱序的一个问题。
所以我们针对这个问题一般的解决方法就是自定义消息分区的一个路由算法,然后把指定的key都发送到同一个Paritition里面。我们再指定一个消费者专门去消费某一个分区的数据。这样的话就保证了消息的顺序消费了。
另外在有些设计方案里面,在消费端会采用异步线程的方式来消费数据,以提高消息的一个处理效率。
那么这种情况下,每一个线程的消息处理效率是不同的,所以即便是采用了单个分区的存储和消费。也可能会出现无序访问的一个问题。
那么针对这样一个问题的解决方法,就是在消息消费端这一边采用一个阻塞队列,把获取到的消息先保存到阻塞队列里面,然后采用一个异步线程从阻塞队列里面去获取消息,来进行消费。
如果不想把消息路由到同一个分区,但是还是想去实现消息的一个顺序消费,应该如何解决?
严格来说,Kafka只能去保证同一分区内消息存储的一个顺序性,如果一定要去实现也不是不行,但是代价太大,没有必要。
参考资料:Kafka如何保证消息消费的顺序性
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。