一次Kafka内存泄露排查经过

一、现象

服务部署后内存总体呈上升趋势

一次Kafka内存泄露排查经过

二、排查过程

通过go tool pprof收集了三天内存数据

2月11号数据:

一次Kafka内存泄露排查经过

2月14号数据:

一次Kafka内存泄露排查经过

2月15号数据:

一次Kafka内存泄露排查经过

我们使用sarama客户端连接kafka,可以看到newPartitionProducer持续增长,可定位到是kafka的问题。而newPartitionProducer是分区生产者,因此查看分区相关的数据。

最近增加的topic:ai_face_process_topic,这个是AI换脸的,每生成一个视频都要通过Kafka中转消息到视频处理服务器。

一次Kafka内存泄露排查经过

查阅数据库看视频生成记录。2022.1.25上线到今天2022.2.15一共20天,只增长了701个视频,平均每天35个视频。

但这个topic有64个分区。这是因为视频生成过程比较耗时,当时考虑到需要提高并发量,所以需要分区数比较多。

一次Kafka内存泄露排查经过

查看sarama客户端的API代码,给每个分区发消息时会判断这个分区的handler是否存在,不存在则创建。

sarama创建partition handler的关键代码:

     handler := tp.handlers[msg.Partition]
if handler == nil {
handler = tp.parent.newPartitionProducer(msg.Topic, msg.Partition)
tp.handlers[msg.Partition] = handler
}

且创建后需要手动close,否则内存一直占用,这是官方说明:

一次Kafka内存泄露排查经过

而我们使用sarama客户端的producer是全局的,一直不会close,所以会一直占用内存。

再看看我们使用sarama的partitioner是NewRandomPartitioner,即每条消息随机匹配到partition。

这样,按照每天三十多的视频生成量,出现前几天新增分配二三十个handler,逐渐减少,直到分配完64个handler。

我们设置了ChannelBufferSize = 1024 * 1024,newPartitionProducer使用64位指针的带缓冲channel缓存消息,因此每个handler会分配8MB内存,也就出现了上面的内存数据:152MB,264MB,172MB。

三、结论与优化

内存增长几天稳定后则不会继续增长。

其他分区数比较多的topic没有观察到内存持续增长情况是因为数据量比较大,服务启动没多久就分配完了每个分区的handler。

优化:

单个AI换脸视频处理服务耗时较长,决定了我们需要比较大的并发量,所以后面分区数还可能增加。而64个分区已经使每个服务占用64*8=504MB内存,严重影响扩展性。

因此后面ai_face_process_topic考虑迁移到redis做消息中转。

四、参考链接

sarama API

githup sarama memory leak问题

kafka memory leak问题

Original: https://www.cnblogs.com/leavygood/p/15899162.html
Author: leavygood
Title: 一次Kafka内存泄露排查经过

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516440/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【golang】 关于for range中只存储最后一个元素的问题

    前言: 今天用for range写了个demo,发现无论怎么运行,最后的结果是一直是最后一个。自己思考过后,又和其他伙伴商量了下,最终算是解决了自己的疑惑。 正文: 下面我们来看个…

    Go语言 2023年5月25日
    054
  • 从Go编程看IO多路复用Select

    IO多路复用通过某种机制使进程监听某些文件描述符,当文件描述符中有读或写就绪时,进程能够收到系统内核发送的相应通知从而进行相应的IO操作;IO多路复用有:select、poll、e…

    Go语言 2023年5月25日
    050
  • go语言学习笔记-初识Go语言

    Go语言是怎样诞生的? Go语言的创始人有三位,分别是图灵奖获得者、C语法联合发明人、Unix之父肯·汤普森(Ken Thompson)、Plan 9操作系统领导者、UTF-8编码…

    Go语言 2023年5月25日
    075
  • 对不起,我错了,这代码不好写

    hello,大家好呀,我是小楼。 前几天不是写了这篇文章《发现一个开源项目优化点,点进来就是你的了》嘛。 文章介绍了Sentinl的自适应缓存时间戳算法,从原理到实现都手把手解读了…

    Go语言 2023年5月25日
    064
  • golang拾遗:自定义类型和方法集

    golang拾遗主要是用来记录一些遗忘了的、平时从没注意过的golang相关知识。 很久没更新了,我们先以一个谜题开头练练手: package main import ( &quo…

    Go语言 2023年5月25日
    052
  • Go之Logrus用法入门

    Logrus是Go (golang)的结构化日志程序,完全兼容标准库的API日志程序。Logrus is a structured logger for Go (golang), …

    Go语言 2023年5月25日
    061
  • go学习笔记(一)

    零值的 slice等于 nil。 nil值的 slice没有底层数组 nil值的 slice的长度和容量都是 0。但是也有非 nil值的 slice的长度和容量为 0的,如 []i…

    Go语言 2023年5月25日
    031
  • Go语言之变量与基础数据类型

    Go 是静态(编译型)语言,是区别于解释型语言的弱类型语言(静态:类型固定,强类型:不同类型不允许直接运算) 例如 python 就是动态强类型语言 1、Go 的特性: 跨平台的编…

    Go语言 2023年5月25日
    053
  • Go语言之高级篇beego框架之日志收集系统

    一、日志收集系统架构设计 图1 图2 二、开发环境 1、安装jdk jdk-8u51-windows-x64.exe 安装目录:C:\Program Files\jdk8 2、安装…

    Go语言 2023年5月29日
    051
  • [grpc快速入门] 一 grpc生成与调用

    下载通用编译器 地址:https://github.com/protocolbuffers/protobuf/releases选择对应的版本,解压后将文件夹下bin目录配置到环境变…

    Go语言 2023年5月25日
    081
  • Ebiten-纯Golang开发的跨平台游戏引擎

    Go语言不是让你玩的啊喂! 昨天跟好基友聊开发的事,他说他等着闲下来的时候就用 PYGame写个像那个最近挺火的”文X游X”一样的游戏.(没收广告费啊!) …

    Go语言 2023年5月25日
    082
  • go-zero单体服务使用泛型简化注册Handler路由

    一、Golang环境安装及配置Go Module https://go-zero.dev/cn/docs/prepare/golang-install mac OS安装Go 下载并…

    Go语言 2023年5月25日
    072
  • AES加解密(golang <--> crypto-js)

    AES(Advanced Encryption Standard) 是一种对称加密算法,是比 DES 更好的对称加密算法类。 使用AES,在前后端之间传送密码等相关数据时,能简单高…

    Go语言 2023年5月25日
    044
  • go语言面向对象编程之类型系统

    go语言类型系统 类型系统,顾名思义是指一个语言的类型体系结构,一个典型的类型系统通常包含如下基本内容 基础类型:如byte,int,bool,float等 复合类型:如数组,指针…

    Go语言 2023年5月29日
    039
  • Go切片全解析

    目录结构:数组切片 底层结构 创建 普通声明 make方式 截取 边界问题 追加 拓展表达式 扩容机制 切片传递的坑 切片的拷贝 浅拷贝 深拷贝 var n [4]int fmt….

    Go语言 2023年5月25日
    075
  • 【Go语言】(一)环境搭建与了解VScode工具

    视频链接(p1~p8): golang入门到项目实战 [2022最新Go语言教程,没有废话,纯干货!] 参考链接: 用vscode开发go的时候,安装go包报错:connectex…

    Go语言 2023年5月25日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球