消息中间件-kafka

[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/MQ/mq-kafka.html

1. 为什么 Kafka 快


1.1 通过生产和缓冲区减少网络开销

Kafka 的生产者发送消息时,会将多条消息打包为一个 batch(发送缓冲区)一起发送,等缓冲区大小达到阈值或者一定时间,批量发送,从而减少网络开销

1.2 根据不同 ack 配置,可以不刷盘、少刷盘就响应 ack

  • ack=0:生产者发送消息后,不会等待 Broker 的响应,不保证消息是否到达 Broker
  • ack=1:生产者发送消息后,等待 Leader Broker 接收到消息后,返回 ACK 响应
  • acks=allacks=-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 因为促销等业务高峰原因

  • 可以制定风险预案,做动态线程池:
  1. 消费时改为多线程消费
  2. 改代码:
    • 消费并发布到新主题,新主题的分区数为原来的 3 倍
    • 原业务代码开 3 倍的消费者消费新的主题
  3. 消费者用高性能机器替换

5. 如何保证 Kafka 消费数据不丢失


5.1 生产者

  • 配置为ack!=0,确保至少落到 Leader Broker 的磁盘后才给生产者 ack

5.2 消费者

  • 保证至少是 At-least-once 消费模式:

5.2.1 消费端消费模式 及其一般实现方式

  • at most once 模式:
    1. 禁用自动提交偏移量
    2. 接收到消息立即 ack,然后再处理
  • at least once 模式:
    1. 禁用自动提交偏移量
    2. 接收到消息先处理,再提交偏移量
  • exactly once 模式:
    1. 禁用自动提交偏移量
    2. 处理消息,提交偏移量,保存消息 ID 信息到第三方存储
      注: 需要在同一个分布式事务管理器

6. 如何处理 Kafka 补数


6.1 修改```auto.offset.reset`` 重新消费

  • 消费者配置中,KafkaConsumer 类的 setProperty 方法设置 auto.offset.reset 配置:
  1. earliest,重头消费
  2. latest,从当前消费(默认)
  3. none,当前消费者组没有偏移量,报错

6.2 可以通过以下方式进行补数:

  1. 重置偏移量
  2. 上游重发
  3. 将需要补数的数据暂存到其他新主题,或外部存储,后续用特殊新逻辑重新消费

7. 如何保证 Kafka 高可用


  1. 多副本数据容易,保证数据『高可用』读写
  2. ISR(In-Sync Replicas)机制,只有同步了 Leader 的副本才可以参与读写,保证了数据的『一致性』
  3. zk 保证 broker 的『可用性』,当 broker 上下线、宕机,可以实现『分区自平衡』
  4. 持久化机制
  5. Leader 机制,Kafka 一个分区有一个 Leader + 多个 Follower 副本,Leader 负责读写,故障会选举出 Follower 作为新的 Leader
作者

神奇宝贝大师

发布于

2021-01-12

更新于

2021-08-19

许可协议

评论