kafka积压类问题

前言

Kafka消息积压的问题,核心原因是生产太快、消费太慢,处理速度长期失衡,从而导致消息积压(Lag)的场景,积压到超过队列长度限制,就会出现还未被消费的数据产生丢失的场景。

简单来说,之所以会产生积压,就是消费能力所致。

名词解释

Producer :消息生产者,就是向 Kafka broker 发消息的客户端;

Consumer :消息消费者,向 Kafka broker 取消息的客户端;

Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由消费组内一个消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。

Broker :一个 Kafka 实例就是一个 broker。一个集群由多个 broker 组成。一个broker可以容纳多个 topic。

Topic :可以理解为一个队列,生产者和消费者面向的都是一个 topic;

Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列;

Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 Kafka 仍然能够继续工作,Kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader 和若干个 follower。

leader:每个分区多个副本的"主",生产者发送数据的对象,以及消费者消费数据的对象都是 leader。

follower:每个分区多个副本中的"从",实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 leader。

如何衡量消息的生产量/消费量/积压量

生产量:Kafka Topic 在一个时间周期内各partition offset 起止时间差值之和。

消费量:Kafka Topic 在一个时间周期内某个消费者的消费量。

积压量:Kafka Topic 的某个Consumer Group残留在消息中间件未被及时消费的消息量

常见案例&应对方法

1. 消费端过载

原因:消费任务里有消费任务队列满载,消费线程阻塞,导致系统频繁 fullGC 问题

处理方案:根本解法是提升消费端的能力,增加消费线程数;事前预警,可以增加消费能力监控,以及消息消费积压报警。

2. 消息生产异常导致消费端消费能力不足

原因:生产者的一些错误导致重复、过多写入任务队列,消息消费能力不足导致该问题。

处理方案

1)最根本的处理方案是,代码方面增加健壮性处理,避免此类问题的发生。

2)真的遇到此类问题,需要快速止损,此案例是加速消费积压任务,上线增加消费进程,通过加资源方式修复此类问题。

3)提前预警可以增加队列内消息生产量、消费量等的阈值监控/报警。

3. 消息中间件异常导致消息消费失败

原因:Kafka broker有一台机器内存故障,导致新代理一台broker不可用,此时业务发布时报获取元数据超时异常

处理方案

1)如果公司Kafka等此类公共组件集群发生异常且异常未完全恢复,则不要进行上线等操作

2)当上线服务时发生异常应该立即回滚,而不是为了解决积压消息而全量发布

3)于Kafka组件应该设置开关,如果出现问题可以第一时间关闭相关服务,防止强依赖Kafka导致服务不可用

4)在消费Kafka的业务中不要异步使用自己的线程池,特殊情况会打满线程池

5)上线服务可以将故障Kafka节点从配置中删除,再进行上线重启

4. 消费者业务流程复杂,业务增长后,生产者流量超出消费者能力

原因:消费者业务流程复杂,生产量达到消费上限后,产生消息积压

处理方案

1)对partition扩容增加partition数量

2)将消费者代码修改为多线程并发消费

3)提高单条消息的处理速度,如:优化业务流程,增加缓存,去掉耗时操作

5. 消费者业务流程中存在慢查询

表现:同时存在MySQL慢查询问题、以及Kafka消息积压的问题,大概率属于慢查询导致的Kafka消息积压。

原因:消费逻辑中的写MySQL流程存在由于索引不合理导致的慢查询问题

处理方案:慢查询优化

6. 消费者依赖第三方服务

原因:回调第三方服务,因第三方接口波动,导致网络慢或者异常,从而影响整体消费端的能力。

处理方案

1)做好监控,及时反馈,让依赖的三方接口做优化

2)控制生产者生产速度

3)消费者做好过滤,避免重复处理

7. 消费者组频繁rebalance导致消息积压问题

现象

1)消息积压有报警

2)从Kafka manager看,该topic有3个分区,尾数A的ip消费了两个分区,尾数B和C的ip来回变换的消费2号分区,消费进度没有任何变化;从 broker 端日志看,该消费组在频繁的进行rebalance

原因

1)max.poll.records = 20,而 max.poll.interval.ms = 1000,也就是说consumer一次最多拉取 20 条消息,两次拉取的最长时间间隔为 1 秒。

也就是说消费者拉取的20条消息必须在1秒内处理完成,紧接着拉取下一批消息。否则,超过1秒后,Kafka broker会认为该消费者处理太缓慢而将他踢出消费组,从而导致消费组rebalance。

根据Kafka机制,消费组rebalance过程中是不会消费消息的,所以看到ip是B和C轮流拉取消息,又轮流被踢出消费组,消费组循环进行rebalance,消费就堆积了

处理方案:消费者客户端减小 max.poll.records 或 增加 max.poll.interval.ms 。RD 将 max.poll.records 设置为 1,重启消费者后消费恢复

补充说明

Rebalance 发生的时机有三个:

  • 组成员数量发生变化(新加消费者、删除消费者、消费者重启、消费超时等)
  • 订阅主题数量发生变化
  • 订阅主题的分区数发生变化

consumer客户端相关参数:

  • session.timeout.ms

    • 由于broker服务端设置了参数

      ini 复制代码
      group.min.session.timeout.ms = 6000
      group.max.session.timeout.ms = 300000
      • 客户端 session.timeout.ms 的值必须介于两者之间
  • heartbeat.interval.ms

  • max.poll.interval.ms

  • max.poll.records

常见处理方案总结

序号 处理方案
1 如果消费者无法提升消费能力,并且消费者数量已达分区数时,消费者增加partition扩容,partition扩容之后无法缩容
2 消费端增加Consumer消费者
3 优化单个消费处理流程:慢查询、慢日志优化、简化业务流程
4 极端情况,消费者无法短时间恢复,并且积压消息可以丢弃时,下线消费者Consumer
5 生产者限流
6 消费者限流
7 消费者端,需要慎重使用线程池方式异步消费,避免潜在的fullGC问题
8 基于业务特点,特别是针对核心场景,对消息生产量、消费量、积压量增加相应的监控、报警规则
相关推荐
追逐时光者1 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
盖世英雄酱581361 小时前
InnoDB 的页分裂和页合并
数据库·后端
小_太_阳2 小时前
Scala_【2】变量和数据类型
开发语言·后端·scala·intellij-idea
直裾2 小时前
scala借阅图书保存记录(三)
开发语言·后端·scala
星就前端叭3 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
漫无目的行走的月亮3 小时前
Ubuntu下C语言操作kafka示例
kafka·librdkafka
小林coding4 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
AI理性派思考者4 小时前
【保姆教程】手把手教你在Linux系统搭建早期alpha项目cysic的验证者&证明者
后端·github·gpu