消息队列通识
为什么需要消息队列
- 解耦
- 削峰填谷
- 异步调用
消息队列如何保持幂等
- 重复源泉
- 生产端重发
- 发送ACK没有回复继续发送
- 消费端重复
- 生产端重发
- 解决方案
- 唯一消息ID,生产者发送时携带messageId
- 幂等表
- 状态机校验
- 乐观锁 / 版本号
- 分布式锁
- 核心原则
- 消费逻辑天然幂等
为什么需要消息队列
- 解耦
- 异步
- 削峰
消息队列的模型有哪些
- 点对点模型
- 发布订阅模型
如何保证消息不丢失
- 生产端
- ack
- broker 持久化
- 生产环境副本因子 >= 3
- 消费端
- 手动提交 offset
如何保证消息有序
- 让需要保持有序的消息落到同一个分区
- 给唯一的key,且key以后不会重复
- Kafka保证唯一分区内有序,跨分区无序
RabbitMQ
RabbitMQ 如何保证消息不丢失
- 哪些情况会丢失
- publisher -> exchange
- 生产者确认机制
- ack publish-confirm
- nack publish-confirm
- ack publish-return
- 消息失败之后如何处理
- 回调方法
- 记录日志
- 保存到数据库中然后定时重发
- 生产者确认机制
- exchange -> queue
- 消息持久化
- 交换机持久化
- 队列持久化
- 消息持久化
- 消息持久化
- queue
- queue -> consumer
- 消费者确认机制
- publisher -> exchange
RabbitMQ 消息的重复消费问题是如何解决的
重复消费的原因
- 网络抖动
- 消费者挂了
解决方案
- 每条消息设置一个唯一的标识id
- 幂等方案
- 分布式锁
- 数据库锁
- 悲观锁
- 乐观锁
RabbitMQ 中的死信交换机(延迟队列)
延迟队列 = 死信交换机
消息堆积问题
- 增加消费者
- 消费者端开启线程池
- 扩大队列容积
- 惰性队列
RabbitMQ 的高可用机制
- 普通集群
- 镜像集群
- 仲裁队列
Kafka
Kafka 如何保证消息不丢失?
- 丢失的三个情况
- producer发送方式
- 同步
- get
- 异步
- 同步
- 解决生产者丢失
- 设置异步发送
- 消息重试
- 解决broker存储中丢失
- 发送确认机制
- acks
- 0
- 1
- all
- acks
- 发送确认机制
- 解决消费者主从 broker 接收消息丢失
- 禁止自动提交偏移量,改为手动提交偏移量
- 同步提交
- 异步提交
- 同步+异步组合提交
- 禁止自动提交偏移量,改为手动提交偏移量
如何解决Kafka的消息重复消费问题
- 关闭自动提交
- 同步+异步提交
- 幂等方案
Kafka 如何保证消费的顺序性
- 指定分区号
- 发送消息时按照相同的业务设置相同的key
Kafka 高可用机制了解过吗
- 集群
- 分区备份机制
- ISR副本(In-Sync Replica)
- 普通副本
解释一下复制机制中的ISR?
分区副本的follwer分为两类 一类是ISR与leader副本同步保存数据 另一个是普通副本异步保存数据
Kafka 数据清理机制了解过吗?
- Kafka 文件存储机制
- 分段存储
- .index
- .log
- .timeindex
- 分段的好处
- 减少单个文件内容大小,查找数据方便
- 方便kafka进行日志清理
- 分段存储
- 数据清理机制
- 日志的清理策略
- 根据消息保留时间,如果消息超过指定时间,触发清理
- 默认7天
- 根据topic存储的数据大小,日志文件大小超过一定阈值进行清理(默认关闭)
- 日志的清理策略
Kafka 中实现高性能的设计有了解过吗?
- 多性能是多方面协同的结果
- 主要体现
- 消息分区
- 顺序读写
- 页缓存
- Linux系统的缓存。将磁盘数据缓存到内存,提高性能
- 零拷贝
- 减少上下文切换以及数据拷贝
- 消息压缩
- 提供多种消息压缩算法,减少磁盘和网络IO
- 压缩耗费CPU
- 分批发送
- 将消息打包分批发送,减少网络开销
零拷贝的含义
用户空间 kafka 内核空间 页缓存 Socket缓冲区 硬件 磁盘文件 网卡
节省了页缓存到网卡的中间开销
页缓存直接到网卡
ZooKeeper 的作用,为什么抛弃?
- 作用
- broker 注册
- topic / partition 元数据
- controller 选举
- ISR 变更
- 抛弃原因
- 运维两套系统麻烦
- ZK 成为元数据规模的瓶颈
- ZK 为了保证高性能,将整个数据树完全保存在内存中
- Kafka能管理的分区总数,受限于 ZK 服务器的物理内存
- 故障恢复慢
- Leader 宕机或集群重启时,必须完成一套严格的恢复流程
Kafka 为什么这么快
- 顺序IO写磁盘
- 分区并行
- 批量发送
- 零拷贝
- 数据在操作系统内核空间直接传递
- 避免内核空间和用户空间之间多次拷贝和上下文切换
- Kafka 的零拷贝是指利用 Linux 的 sendfile 系统调用,让数据从磁盘 PageCache 直接发送到网卡,绕过了用户态内存拷贝,从而极大降低了 CPU 开销并提升了消费吞吐量