暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

为什么Kafka的数据不写了?

BUG侦探 2021-08-25
456


背景
服务器上有个go程序,用来抓取网卡eth2上的dns数据包,后写入kafka集群。但是每运行一小时左右后往kafka集群的写入量就变为零,因此针对这奇怪的现象进行了些许排查·····     
程序处理流程如下图:
使用到的库是
github.com/confluentinc/confluent-kafka-go/kafka
github.com/google/gopacket
github.com/google/gopacket/layers
github.com/google/gopacket/pcap

排查流程

1.当写入归零时查看程序状态
top查看: 
            cpu消耗0-1%
            内存占用1.4GB
strace查看:
            有futex超时现象
            无其他系统调用
2.怀疑是否是链接kafka的tcp链接断开了
通过ss命令查看进程持有的tcp链接,状态为establish
再通过,tcpdump分析,发现无数据包传输
3.综合以上因素,并未分析出有效的原因。试试在程序关键步骤打印输出来查看。
1)程序增加子协程心跳信息发现程序出问题时,子协程运行正常,说明程序整体运行正常
2)在kafka生产者发送消息前打印日志发现,主程序hang在了这里(如下图),似乎是这里的问题
4.查看confluent-kafka-go库的github(https://github.com/confluentinc/confluent-kafka-go)
1)从样例和说明文档中并未发现有特别需要注意的配置项
2)从issue中搜索关键字hang/block,发现了一个类似的问题
https://github.com/confluentinc/confluent-kafka-go/issues/251
维护者在回答某个提问者的问题时: 提到有个Events管道被装满,并且这是维护者也回答这个选项是开发层面的属性,所以没在配置文档中说明....
3)这个Events是什么东西呢,与我们发送数据又有什么关联呢,由于介绍文档中没有说明,只能从producer.go代码中(https://github.com/confluentinc/confluent-kafka-go/blob/master/kafka/producer.go)看是否能找到些说明..
producer.go中有介绍到Producer方法是个异步方法,消息发送结果都保存在一个Events()管道中
同时发现这个管道的容量配置默认为100000
同时调试发现,我们程序中按照样例写的子协程,在处理一条该管道中的数据就停掉了
那么猜测就是这个管道容量用完导致程序hang住了。。

调试

根据上面维护者提到的解决方法把go.delivery.reports置为false重新编译运行,发现这次程序运行十几个小时写入kafka数据正常,内存占用100MB左右。
至此,就确认了问题所在....

改进与思考

1.总结

(1)confluent-kafka-go库中的生产者Api发送数据是一个异步的过程。

(2)生产者Api通过一种叫做delivery reports的信息来描述该条消息发送结果成功与否,delivery reports默认被发送进名字是Events的信道中。

(3)Events管道的开关配置、最大容量在NewProducer实例化时配置,在实例调用Produce时可指定不同的Events

(4)Events管道容量耗尽时会阻塞生产者发送数据。

2.改进

服务器上的该Go程序的问题,可以有两种手段解决:

(1)在NewProducer实例化配置时设置go.delivery.reports为false,从而关闭该功能。

(2)默认情况下go.delivery.reports是开启的,需要确保子协程能一直处理Events中的delivery.reports数据。

3.建议

(1)如果业务场景不能容忍数据丢失的情况,则需要: 

a.NewProducer实例化时配置go.delivery.reports开启

b.增加子协程来处理Events管道中的delivery reports数据,对于delivery reports显示消息发送失败的情况,需要增加重传的逻辑,确保消息被Kafka端成功收到。

c.程序运行中需要关注该Events管道的容量,避免管道容量耗尽的情况。

(2)如果业务可容忍数据丢失时,可关闭该功能,以提高程序的性能。

4.思考

最初top排查程序异常时,发现内存占用1.4G,相对程序调试运行时的内存占用100MB 相差十倍,作为一个非大量数据计算存储程序,内存不应占用这么多,起初的思路也可以沿着程序中是否有数据积压的可能去排查。





🔍
作者介绍
🕵️‍♀️
ABOUT US
有 趣 灵 魂 集 结 地
思 路 总 结 大 本 营

SCAN AND FOLLOW US NOW
@BUG侦探




文章转载自BUG侦探,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论