- 消息队列优势
- 异步
- 解耦
- 削峰
- 存在的问题及如何解决
- 系统复杂性
- 数据一致性
- 可用性
- 高可用: 一定是分布式部署(集群)
- 消息丢失: 消息持久化问题
- 消息有序
- 重复消费
场景:一个消息有多个消费者,当其中一个消费失败,要求重新发送一次消息。那么其他消费成功的也会再次收到同样的消息。
解决方案:首先涉及到重要的接口需要做强校验,例如:可以有一个流水表,操作完之后,就会向流水表写一条记录(消费和流水写记录放到一个事务去做)。下次相同的消息在来的时候,先从流水表查询,有记录直接返回。没有记录重新消费。涉及到非重要性接口,例如:短信通知,可以加个临时缓存,就算丢失也无可厚非
- 消费顺序错乱
场景: 例如:下单、支付和发货三个消息,是顺序产生的,当发送到消息队列时一个topic 有多个队列,为了保证顺序消费,需要把这些消息发送给 一个队列,然后队列采用 fifo,顺序消费。
方案: 为了发送到同一个队列,可以使用 订单号hash取模,使相同的订单号都落到相同的队列。为了保证下游消费顺序,一般前面的消费成功后,在发下一个消息
- 高吞吐、低延迟:几十万/秒
- 可扩展: 支持热扩展
- 持久性、可靠性: 支持持久化,支持数据备份
- 容错性: 容许集群中节点失败,
- 高并发:支持数千个客户端同时读写
- 消息丢失 -- 当消息被发送出去之后仅仅被标记为已发送状态,当接到 consumer 已经消费成功的通知后才标记为已被消费的状态
- 消息重复消费 --
- kafka 的 ack 的三种机制
request.required.acks 有三个值 0 1 -1(all)
-
0:生产者不会等待 broker 的 ack,这个延迟最低但存储的保证最弱当 server 挂掉的时候就会丢数据。
-
1:服务端会等待 ack 值 leader 副本确认接收到消息后发送 ack 但是如果 leader挂掉后他不确保是否复制完成新 leader 也会导致数据丢失。
-
-1(all):服务端会等所有的 follower 的副本受到数据后才会收到 leader 发出的ack,这样数据不会丢失
- Kafka 与传统 MQ 消息系统之间有三个关键区别
- Kafka 持久化日志,这些日志可以被重复读取和无限期保留
- Kafka 是一个分布式系统: 它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性
- Kafka 支持实时的流式处理