| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 为什么Kafka的数据不写了? -> 正文阅读 |
|
[大数据]为什么Kafka的数据不写了? |
背景服务器上有个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 相差十倍,作为一个非大量数据计算存储程序,内存不应占用这么多,起初的思路也可以沿着程序中是否有数据积压的可能去排查。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 17:08:22- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |