一次解决kafka producer发送很慢的经历

一次解决kafka producer发送很慢的经历

使用场景:kafka发送producer为单实例并且使用同步发送,发送kafka使用线程池执行发送任务,任务队列大小为2000,kafka连接server端使用kerboeros认证
当业务下发从nginx进入,两个tomcat节点进行发送kafka处理,1200TPS时会偶现几次处理时延很长,直接导致nginx504,第一时间打开debug日志,发现最长处理kafka发送时延也就1秒多,nginx配置超时时间为60s,怎么会导致nginx超时呢?
问题分析:
分析kafka日志发现,每次发送数据大部分时间在0-1ms,出现时延的情况时发现都是连续出现的,由于发送端只有一个producer实例,这样当一个message发送阻塞了,将会瞬间导致TPS急剧下降,正常情况下一个kafka实例在1秒内能够处理1000个发送请求,但出现1秒的时延将会导致1秒只能处理1个发送请求,这样会阻塞后面数据的处理,马上将线程池任务队列塞满,后面的nginx请求也就随之阻塞,当nginx在60s后没有收到任何相应就504的问题
问题原因:
由于producer是线程安全的,所以采用单实例,但一次发送阻塞(因为使用同步发送,每次发送都会等待结果,这个过程是同步的),将会影响到后续的数据处理
修改策略:
将producer改为多实例,使用数组将多个实例缓存起来,每次使用producer是在数组轮询取出一个进行使用,修改之后连续长稳环境跑了24小时,打开日志发现发送kafka时延还是有少量100ms以上的长时延,但基本都在100ms-500ms之间,不算很长,并且当不会连续出现了,nginx也没有出现504这种情况了,说明多实例修改是有效果的
额外发现注意项
在数据停止下发一段时间,重新进行数据下发,发现一个挺有意思的问题,kafka前面几条数据居然出现发送时延为30s以上,这又是咋了?原来是kafka producer处于空闲状态超过IDLE最大时间会和服务端断开连接,以节省资源,重新使用时,有将会重新进行kerbores认证和连接,这个时间挺长导致的(其实我也不清楚这个认证为什么要花这么长时间,对kerbores除了知道是认证的作用外就一无所知,希望大佬指点一二),所以如果业务实时性要求高一点最好是让这个连接不要IDLE,简单的办法就是在IDLE超时间时间范围内进行一次发送数据,让连接不会断开。

你可能感兴趣的:(Kafka)