消息中间件-kafka
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/MQ/mq-kafka.html
1. 为什么 Kafka 快
1.1 通过生产和缓冲区减少网络开销
Kafka 的生产者发送消息时,会将多条消息打包为一个 batch(发送缓冲区)一起发送
,等缓冲区大小达到阈值或者一定时间,批量发送,从而减少网络开销
1.2 根据不同 ack 配置,可以不刷盘、少刷盘就响应 ack
ack=0
:生产者发送消息后,不会等待 Broker 的响应,不保证消息是否到达 Brokerack=1
:生产者发送消息后,等待 Leader Broker 接收到消息后,返回 ACK 响应acks=all
或acks=-1
:生产者发送消息后,等待 Leader Broker 接收到消息,并且等待其他所有副本都成功复制消息(落盘),才会返回 ACK 响应
**注**: 节点接收到数据后不会立即刷盘
,会先暂存到 pagecache 里,等到一定的大小或者时间后才会刷盘
1.3 零拷贝
正常 IO 需要经过 5 次读写才能从磁盘读取数据发送给消费者,而零拷贝可以实现内核态之间硬件的数据拷贝,只需要 3 次 IO,不需要经过应用态,减少了 2 次非必要 IO
2. 如何实现 Kafka 延迟队列
2.1 分级主题循环等待
- 对于正常生产,如果消费时间未到,则
丢回队尾
,等待下次消费
一般采用相同(如 10 分钟)级别的 delayed-messages,以免前面的消息堵塞后面的数据
2.2 生产者方延迟发送消息
生产者可以将延迟消息丢到
第三方存储
(如 Redis/RocksDB)中,再启动异步线程任务将过期消息丢到目标主题完成延迟消息的消费
3. 如何实现 Kafka 顺序消费
3.1 单个分区+单个消费者
简单的处理方案,但也存在致命问题:
慢,吞吐低,而且容易因为脏数据出现阻塞问题
3.2 多个分区+多个消费者
借助partitioner,将有先后顺序的
同个业务的单
分到同个分区
消费
解决了大部分的吞吐低的场景,但也需要注意阻塞问题:
消息处理失败最好不要在消费时候重试或者等待,以免阻塞后面的数据。如,消息消费失败时,存到重试表让重试逻辑自己处理
4. 如何处理 Kafka 积压数据
4.2 各个 partition 数据分布不均
- 各个 partition 数据分布不均,个别因为数据分区规则导致个别 partition 数据量很大,而一些又很小
可以优化分区规则,如:把分区号由城市改为订单号
4.3 消息体过大、非必要消息量过多,导致 IO 问题(Kafka 2 次网络 IO,2 次磁盘 IO)
- 可以优化消息体与减少消息量
4.4 因为促销等业务高峰原因
- 可以制定风险预案,做动态线程池:
- 消费时改为多线程消费
- 改代码:
- 消费并发布到新主题,新主题的分区数为原来的 3 倍
- 原业务代码开 3 倍的消费者消费新的主题
- 消费者用高性能机器替换
5. 如何保证 Kafka 消费数据不丢失
5.1 生产者
- 配置为
ack!=0
,确保至少落到 Leader Broker 的磁盘后才给生产者 ack
5.2 消费者
- 保证至少是 At-least-once 消费模式:
5.2.1 消费端消费模式 及其一般实现方式
at most once
模式:
- 禁用自动提交偏移量
- 接收到消息立即 ack,然后再处理
at least once
模式:
- 禁用自动提交偏移量
- 接收到消息先处理,再提交偏移量
exactly once
模式:
- 禁用自动提交偏移量
- 处理消息,提交偏移量,保存消息 ID 信息到第三方存储
注: 需要在同一个分布式事务管理器
6. 如何处理 Kafka 补数
6.1 修改```auto.offset.reset`` 重新消费
- 消费者配置中,KafkaConsumer 类的 setProperty 方法设置
auto.offset.reset
配置:
earliest
,重头消费latest
,从当前消费(默认)none
,当前消费者组没有偏移量,报错
6.2 可以通过以下方式进行补数:
- 重置偏移量
- 上游重发
- 将需要补数的数据暂存到其他新主题,或外部存储,后续用特殊新逻辑重新消费
7. 如何保证 Kafka 高可用
- 多副本数据容易,保证数据『高可用』读写
- ISR(In-Sync Replicas)机制,只有同步了 Leader 的副本才可以参与读写,保证了数据的『一致性』
- zk 保证 broker 的『可用性』,当 broker 上下线、宕机,可以实现『分区自平衡』
- 持久化机制
- Leader 机制,Kafka 一个分区有一个 Leader + 多个 Follower 副本,Leader 负责读写,故障会选举出 Follower 作为新的 Leader
消息中间件-kafka