kafka线上问题整理和优化

一、前言

博主现在负责触达平台的建设,众所周知,对于4000万客户的推送来说,高流量的推送会导致系统负载更高,所以就会使用大量的消息队列来缓冲请求,达到削峰;但是由于网络抖动或者流量高峰期间可能会存在一些报错,现在记录下来并作为分享。

二、生产者问题整理

问题一:生产者写入超时

现象:

org.apache.kafka.common.errors.TimeoutException: Expiring 59 record(s) for mkt_push_statistics_filter-7: 30375 ms has passed since batch creation plus linger time

【[CAT异常告警]】

>**内容摘要**:<font color="warning">[异常告警]: [ 异常名称: TimeoutException  异常总量:1528.0 ]

[业务负责人: lili5 ] [告警间隔时间]5分钟</font>

>**告警节点**:ext-spring-jyyx-mkt-push-channel

>**告警级别**:<font color="warning">P0</font>

>**告警时间**:2021-05-13 20:40:04

>**故障ID**:4bca28cc0638bc3fc36a3db0ae9eac59

>**告警来源**:CAT

>**详情访问**:[Solaris告警平台](https://solaris.xxx.cn/solarisHistory/alert-detail?eventId=4bca28cc0638bc3fc36a3db0ae9eac59)

 分析:

生产者发送超时,根据报错信息分析是否是代码问题,因为一直没有报错,突然报一波,怀疑是网络抖动,然后分析到生产者一般都是批量提交消息到brocker处,肯定会超时时间,查了request.time.out默认视为30s,现在刚好到达改时间;

具体原因如下:

producer send方法的callback函数执行缓慢导致;

producer往broker发送数据时是串行的,只有上次batch全部写入broker,并且全部callback函数执行完毕后,才会继续下一次发送。如果上一次发送全部callback函数执行时间超过了request.timeout.ms(30s),就会导致后续batch的message发送时间大于创建时间30s以上,然后被producer丢弃并抛出异常;

解决办法:

1、增大request.time.out=60m;

2、根据业务增加重试次数和重试间隔

关于重试,我想说几点:

第一:一般kafka默认重试间隔是100ms,我们设置重试次数为3,所以恢复该数据需要花费:30000*3+200=900200ms,约等于90秒 一分钟半,一半情况网络抖动 不会立刻恢复,所以会导致重试后还是失败的;

第二:如果系统对数据为弱一致性,允许一定量消息丢失时,这种少量的重试后失败的,可以忽略;

第三:如果对数据要保持最终一致性,即保证消息不可丢失时,可以对抛出的异常进行捕获并持久化到数据库中,然后进行job补偿;

 问题二:消费者提交offset失败

问题:


	1. [Consumer clientId=consumer-2, groupId=messageBoxMessageListener] Offset commit failed on partition mkt_push_box_message-7 at offset 40771: The coordinator is not aware of this member;


          [Consumer clientId=consumer-2, groupId=directPushMessageListener] Offset commit failed on partition mkt_direct_push_customer_message-1 at offset 8306283: The coordinator is not aware of this member.

elk查询如下:

分析:

 

1、consumer group 消费者组,consumer消费者,group coordinator组协调者,主要管理消费者组的健康状态和分区分配问题;

2、在一个线程(用户线程)里面执行kafka consumer 的while true循环逻辑的,其实这里有2个线程:一个是用户线程,另一个是心跳线程。心跳线程,主要根据heartbeat.interval.ms参数配置的值周期性向coordinator发送心跳包以证明consumer还活着;

3、每次poll消息太多,消息处理逻辑过重,调用三方接口超时,也即用户线程需要执行很长的时间处理消息,然后再提交offset,这时达到pool最大间隔时间了,会发生reblance;

 

session.timeout.ms:consumer group  coordinator在多少秒内没有没收到consumer 心跳命令时就会认为当前consumer死了,然后会触发rebalance

heartbeat.interval.ms:consumer实例间隔多少ms向consumer group  coordinator发 join group的命令表示自己活着

max.poll.interval.ms:消费者线程每次poll的最大间隔时间

max.poll.records:每次poll消息的最大条数,默认是500

解决措施:

1、对kafka消费者参数调整:

增大max.poll.interval.ms至10分钟(默认五分钟)

降低 max.poll.records至200,默认为500

提高session.timeout.ms至15秒,默认为6秒;

2、指定推送消息幂等校验(后期);

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值