如何使用jemalloc分析Flink使用的native memory

前言

最近笔者因为flink集群运行在kubernetes上,由于不可抗力导致pod重生,job需要restart,在没有开启checkpoint的情况下,作业只要重启就会频繁被os kill,这明显是堆外内存超用的现象。

heap memory和direct memory被jvm控制了,显然不会被os kill,而是OOM,可以被flink 捕捉而爆出异常的,被os kill只有托管给rocksdb的native memory了。

如何分析native memory的leak呢,就需要引入jemalloc。

什么是jemalloc

系统的物理内存是有限的,而对内存的需求是变化的, 程序的动态性越强,内存管理就越重要,选择合适的内存管理算法会带来明显的性能提升。
比如nginx, 它在每个连接accept后会malloc一块内存,作为整个连接生命周期内的内存池。 当HTTP请求到达的时候,又会malloc一块当前请求阶段的内存池, 因此对malloc的分配速度有一定的依赖关系。

内存管理可以分为三个层次,自底向上分别是:

  • 操作系统内核的内存管理
  • glibc层使用系统调用维护的内存管理算法
  • 应用程序从glibc动态分配内存后,根据应用程序本身的程序特性进行优化, 比如使用引用计数std::shared_ptr,apache的内存池方式等等。
    当然应用程序也可以直接使用系统调用从内核分配内存,自己根据程序特性来维护内存,但是会大大增加开发成本

glibc malloc的实现是ptmalloc2,其替代品tcmalloc 和 jemalloc。

tcmalloc

tcmalloc是Google开源的一个内存管理库, 作为glibc malloc的替代品。目前已经在chrome、safari等知名软件中运用。
根据官方测试报告,ptmalloc在一台2.8GHz的P4机器上(对于小对象)执行一次malloc及free大约需要300纳秒。而TCMalloc的版本同样的操作大约只需要50纳秒。

jemalloc

jemalloc是facebook推出的, 最早的时候是freebsd的libc malloc实现。 目前在firefox、facebook服务器各种组件中大量使用。

对应的git地址如下

https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md

jemalloc有一项功能,对应长时间运行的程序可以trace内存,见文档[6]。

如果想更加详细的了解这三者的性能和对比,可以参考文档[5]

环境

笔者的flink集群版本是1.10.1,运行在1.17的kubernetes上。

编译jemalloc

下载

wget https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2

解压


tar -zxvf  jemalloc-5.2.1.tar.bz2

开始编译

./configure --enable-prof --enable-stats --enable-debug --enable-fill

一定要加上--enable-prof 才可以使用heap-prof的功能

make 
make install

对我们来说,需要的是

bin
lib

将文件打入flink镜像中

bin
lib

打入flink镜像

ADD jemalloc /opt/jemalloc/

不知道怎么自己构建镜像的可以参考

https://guosmilesmile.github.io/2020/05/27/Flink-on-native-kubernetes-%E4%BD%BF%E7%94%A8%E5%92%8C%E4%BF%AE%E6%94%B9/

配置jemalloc

如果flink的运行方式的native kubernetes,可以在构建集群的脚本添加

-Dcontainerized.taskmanager.env.LD_PRELOAD: /opt/jemalloc/lib/libjemalloc.so.2
-Dcontainerized.taskmanager.env.MALLOC_CONF: prof:true,lg_prof_interval:25,lg_prof_sample:17,prof_prefix:/opt/state/jeprof.out

如果是on kubernetes的standalone,那么需要修改deployment

env:
    - name: LD_PRELOAD
        value: /opt/jemalloc/lib/libjemalloc.so.2
    - name: MALLOC_CONF
        value: prof:true,lg_prof_interval:30,lg_prof_sample:17,prof_prefix:/opt/state/tmp/jeprof.out

配置解释:

LD_PRELOAD: 将内存分配从ptmalloc2改为libjemalloc.so.2

MALLOC_CONF: jemalloc的配置,prof_prefix是将生成的内存文件dump到指定文件。lg_prof_interval:30 是 2^30 byte(1G)生成一个文件,具体参数可以参考

https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md

进入容器补充工具

可以到/opt/state/tmp/下看到很多jeprof.out开头的heap文件

image

由于flink的容器是最简化模式,会缺少很多工具,想要直接使用jeprof是会缺少很多的,需要补充下载

先将源改为国内的源

在容器内运行

mv /etc/apt/sources.list /etc/apt/sources.list.bak
echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >> /etc/apt/sources.list
echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list
echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list

apt-get update 


安装对应的工具

apt-get install -y binutils graphviz ghostscript 

分析内存

/opt/jemalloc/bin/jeprof --show_bytes `which java` /opt/state/tmp/jeprof.out.301.808.i808.heap

root@flink-taskmanager-69df85b5b9-dq42m:/opt/state/tmp# /opt/jemalloc/bin/jeprof --show_bytes `which java` /opt/state/tmp/jeprof.out.301.808.i808.heap 
Using local file /usr/local/openjdk-8/bin/java.
Argument "MSWin32" isn't numeric in numeric eq (==) at /opt/jemalloc/bin/jeprof line 5124.
Argument "linux" isn't numeric in numeric eq (==) at /opt/jemalloc/bin/jeprof line 5124.
Using local file /opt/state/tmp/jeprof.out.301.808.i808.heap.
Welcome to jeprof!  For help, type 'help'.
(jeprof) top
Total: 5580982945 B
2350833429  42.1%  42.1% 2350833429  42.1% os::malloc@8b2970
2002406207  35.9%  78.0% 2002406207  35.9% rocksdb::UncompressBlockContentsForCompressionType
1182793728  21.2%  99.2% 1183056000  21.2% rocksdb::Arena::AllocateNewBlock
11014112   0.2%  99.4% 13300172   0.2% rocksdb::LRUCacheShard::Insert
 9440064   0.2%  99.6% 2011846271  36.0% rocksdb::BlockBasedTable::PartitionedIndexIteratorState::NewSecondaryIterator
 6151347   0.1%  99.7%  6151347   0.1% std::string::_Rep::_S_create
 3335701   0.1%  99.7%  3335701   0.1% readCEN
 2621559   0.0%  99.8%  2621559   0.0% rocksdb::WritableFileWriter::Append
 2381515   0.0%  99.8%  3581933   0.1% rocksdb::VersionSet::ProcessManifestWrites
 2286059   0.0%  99.9%  2286059   0.0% rocksdb::LRUHandleTable::Resize
(jeprof) 

可以导出成pdf或者svg

Output type:
   --text              Generate text report
   --callgrind         Generate callgrind format to stdout
   --gv                Generate Postscript and display
   --evince            Generate PDF and display
   --web               Generate SVG and display
   --list=<regexp>     Generate source listing of matching routines
   --disasm=<regexp>   Generate disassembly of matching routines
   --symbols           Print demangled symbol names found at given addresses
   --dot               Generate DOT file to stdout
   --ps                Generate Postcript to stdout
   --pdf               Generate PDF to stdout
   --svg               Generate SVG to stdout
   --gif               Generate GIF to stdout
   --raw               Generate symbolized jeprof data (useful with remote fetch)

 /opt/jemalloc/bin/jeprof --show_bytes -svg `which java` /opt/state/tmp/jeprof.out.301.1009.i1009.heap  > 105.svg

image

Refernce

[1]Flink任务物理内存溢出问题定位

[2]jemalloc初体验

[3]Using jemalloc to get to the bottom of a memory leak

[4]Debugging Java Native Memory Leaks

[5]内存优化总结:ptmalloc、tcmalloc和jemalloc

[6]Use Case: Heap Profiling

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容

  • 一、x86 Linux 32位系统虚拟地址空间布局: 这里的段基址从0开始,可以访问管理的内存是4G;如果是段基址...
    mindhook阅读 1,080评论 0 1
  • linux内存寻址 3种地址:虚拟地址、物理地址、逻辑地址物理地址:内存的电路地址,对应内存地址线上的高低电平,物...
    grimlock44阅读 1,121评论 0 1
  • 前言 在互联网时代,大部分的应用程序基本都是IO密集型,而IO密集型的程序运行效率的关键在于内存管理,因此充分理解...
    淡泊宁静_3652阅读 1,873评论 0 8
  • 本文主要讲用户态进程的内存管理,而不是内核的内存管理。简单地说,就是和 malloc 和 free 相关的内存管理...
    linjinhe阅读 2,952评论 0 2
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,524评论 16 22