Kafka整理

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

kafka收发逻辑-零拷贝.png
kafka收发逻辑.png

kafka为什么快

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

生产者发送消息时,会将多条消息打包为一个batch(发送缓冲区)一起发送,等缓冲区大小达到阈值或者一定时间,批量发送

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

ack=0

生产者发送消息后(发到memory buffer后立马响应),不会等待Broker的响应,不保证消息是否到达Broker

ack=1

生产者发送消息后,等待Leader Broker接收到消息后,返回ACK响应。

acks=all或acks=-1

生产者发送消息后,等待Leader Broker接收到消息,并且等待其他所有副本都成功复制消息(落盘),才会返回ACK响应。

节点接收到数据后不会立马刷盘,会先暂存到pagecache里,等到一定的大小或者时间后才会刷盘

3. 零拷贝

  • 正常IO需要经过5次读写才能从磁盘读取数据发送给消费者
  • 零拷贝可以实现内核态之间硬件的数据拷贝,只需要2~3次IO,尽可能不需要经过应用态,减少了2-3次非必要IO,也减少了用户态内核态的切换

kafka实现延迟队列

1. 分级主题循环等待

  • 正常生产,消费时如果时间不到,丢回队尾

一般采用相同(如10分钟)级别的delayed-messages,以免前面的消息堵塞后面的数据

2. 生产者方延迟发送消息

    1. 生产者生产延迟消息丢到第三方存储

如Redis/RocksDB中,再启动异步线程任务将过期消息丢到目标主题完成延迟消息的消费


顺序消费

1. 单个分区+单个消费者

问题:慢

2. 多个分区+多个消费者

借助partitioner,把有先后顺序的同个业务单分到同个分区消费

需要注意的问题

  • 阻塞问题
    消息处理失败最好不要在消费时候重试或者等待,以免阻塞后面的数据
    如:消息消费时,先查一下重试表有没有这个单号的数据,没有就正常消费,否则保存到重试表让重试逻辑自己处理

处理积压数据

各个partition数据分布不均

各个partition数据分布不均,个别因为数据分区规则导致个别partition数据量很大,而一些又很小

  • 优化分区规则,如:把分区号由城市改为订单号

消息体过大、非必要消息量过多,导致IO问题(kfk2次网络IO,2次磁盘IO)

优化消息体与减少消息量

因为促销等业务高峰原因

1. 消费时改为多线程消费

2. 改代码:

  • 消费并发布到新主题,新主题的分区数为原来的3倍
  • 原业务代码开3倍的消费者消费新的主题
    慢,麻烦,有风险,需要新机器*2

3. 消费者用高性能机器替换

这里以后最好可以做好风险预案,做动态线程池


保证消费数据不丢失

1. 生产者

ack!=0,确保至少落到Leader Borker的磁盘后才给生产者ack

2. 消费者

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

1. at most onece模式

    1. 禁用自动提交偏移量
    1. 接收到消息立马ack,然后再处理

2. at least once

    1. 禁用自动提交偏移量
    1. 接收到消息先处理,再提交偏移量

3. exactly once

    1. 禁用自动提交偏移量
    1. 处理消息 & 提交偏移量 & 保存消息id信息到第三方存储
      注: 需要在同一个分布式事务管理器

补数

  • 配置上(重置偏移量)
    消费者配置中,KafkaConsumer 类的 setProperty 方法设置『auto.offset.reset』配置:

      1. earliest,重头消费
      1. lastest,从当前消费(默认)
      1. none,当前消费者组没有偏移量,报错
  • 业务上

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

自动提交偏移量(enable.auto.commit)

默认打开

在默认情况下,消费者会在每隔 5 秒钟的时间内将最近一次已消费消息的偏移量提交给 Kafka 服务器

如何保证高可用

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

神奇宝贝大师

发布于

2022-01-09

更新于

2022-03-14

许可协议

评论