为什么mq会产生消息顺序问题
产生背景:
- 消费者集群
- Mq服务端是集群
单个消费者情况下,mq的队列会根据先进先出的原则,消费的顺序是不会被打乱的。但是当我们的生产者往同一个队列存放的消息的行为不统一,可能会存在消息顺序的问题。
为什么多个mq服务端(broker),单个消费者消费消息会存在消息顺序问题?
答:因为我们的投递消息分别存放在多个不同的broker存放,单个消费者获取所有的broker建立长连接,获取顺序可能是随机的。
Mq如何保证消息的顺序?
消息出现顺序消费的场景
- 如果我们的额生产者往我们的mq投递消息的行为不一样,可能会产生消息顺序问题。如果我们的投递的消息到同一个队列行为是一样的情况下,没有必要在意消息的顺序问题。
- 我们的mq存放消息默认的情况下本身就有一定顺序,遵循先进先出的原则(单个mq的情况下)
- 如果我们有多个消费者订阅同一个队列的情况下,可能会产生消费者顺序被打乱。
- 如果我们的broker是集群的情况下,因为不同的消息可能会存放到不同的broker中,单个消费者在获取消息的时候顺序可能会被打乱。
核心解决思路:保证我们的顺序消息存放到同一个broker中,对应的消费者只有一个来消费。
kafka解决方式:kafka中对我们的消息设置相同的key,key可以根据业务来定,根据key的hash值取余(broker的数量)来选择broker。但是我们的单个消费者消费消息吞吐非常低(一个broker只能对应一个消费者,无法对应多个消费者来实现顺序消费),可以采用消费者批量获取我们的消息,然后采用内存队列实现存放。(也会根据消息的key 计算 相同的key存放到同一个内存队列中。)每个内存队列只会对应一个线程实现处理。
kafka的消费者分组
特征:
- 一个消费者只能属于一个消费组。
- 同一个消息可以被不同的消费者组的消费者消费。
- 消费组订阅同一个主题只能被其中的一个消费者实现消费
在kafka中提出的Rebalance协议 有两种分配策略 Range\round-robin
kafka吞吐量高的原因
- 使用顺序写方式实现数据存储
Kafka是采用不断的将数据追加到文件中,该特性利用了磁盘的顺序读写性能比传统的磁盘读写可以减少寻地址浪费的时间; - 能够支持生产者与消费者(支持批量发送和批量消费) 减少io操作
可以将消息投递到缓存区中,在以定时或者/缓存大小方式将数据写入到MQ服务器中,
这样可以减少IO的网络操作,但是这种方式也存在很大缺陷数据可能会丢失。 - 数据零拷贝 NIO支持
- 实现数据的topic分区存放 ,根据Partition实现对我们的数据的分区
- 数据的压缩 会对我们的数据实现压缩,减少网络(带宽)的传输