Linux 监控大量文件写入磁盘
背景
有个大量写入磁盘的需求,做了raid5。但是在写入过程中发现内存一直在增长,经过查询发现buffer/cached在稳定增加,于是非常疑惑。
为了查找原因,我经过了以下过程确认:
硬件确认
确认为软raid
最开始同事告诉我是做的硬件raid,但是测试过程总感觉不太对劲。
- 发现磁盘名称为md124、md126,这是Linux下软件raid的命名特征
- lsblk能够观察到实际使用的磁盘设备sda sdb sdc sdd
- 能够通过 cat /proc/mdstat 的方式查看到当前的raid硬盘信息
- lshw | grep -i raid,发现只存在一个raid设备:Intel Corporation C610/X99 series chipset sSATA Controller,经过查询,发现此设备本质上为CPU RAID设备,并非硬件RAID
经过多方确认,可以认定当前硬盘状态为软件raid
查内存泄漏
valgrind查内存泄漏
# 下载valgrind $ apt install valgrind # 使用valgrind对内存泄漏进行排查 $ valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log ./MyProgram
用valgrind对进程进行内存泄漏查询,发现并不存在内存泄漏的情况。
strace查询内存相关系统调用
- 系统调用可以通过man 2进行查看
# 跟踪内存相关系统调用 # -f:fork,跟踪子进程 # -e:过滤,trace=memory,即跟踪内存相关 # -p PID:跟踪进程PID $ strace -f -e trace=memory -p $(pgrep MyProgram)
发现确实存在大量的内存mmap和munmap,但是申请内存和释放内存基本次数基本等同
判断内存碎片
确认IO瓶颈
监控内存真实增长的实际上为buffer/cached
在后台持续挂监控脚本进行查询,随后拉出表来进行统计
# 实时监控内存信息 # nohup [command] &: 挂后台执行 # watch -n 5 [command]:每5s执行一次命令 # free | grep Mem:执行free命令查询内存信息,过滤Mem内存相关信息,并且将标准输出重定向到sys_memwatch.log文件中 $ nohup watch -n 5 "free | grep Mem >> sys_memwatch.log" & # 实时监控文件 $ tail -50f sys_memwatch.log
经过查看,发现进程增长的内存实际上为buffer/cacahed
怀疑是否是因为数据写入瓶颈,因为如果直接向内存写入文件是不会发生此类情况的。
监控CPU内存写入缓存
简单监控读写速率
# 示例,并非真实数据 $ iostate Linux 5.15.167.4-microsoft-standard-WSL2 (DESKTOP-GMG6327) 02/13/25 _x86_64_ (12 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.06 0.00 0.23 0.02 0.00 99.69 Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd sda 0.18 11.73 0.00 0.00 74453 0 0 sdb 0.02 0.35 0.00 0.00 2248 4 0 sdc 9.51 198.08 241.02 792.10 1257645 1530296 5029280
可以确认iowait
检查未写入的脏页数量/proc/meminfo
- 脏页:内存中已被修改但尚未写入磁盘的数据页。
# 查询dirty页面数量(演示用,非真实数据) $ grep Dirty /proc/meminfo # 查看未写入数据量 Dirty: 0 kB
分析内存使用 pmap
# 查看进程内存分布,储存在my_progress_map.log中 $ pmap -x $(pgrep MyProgress) >> my_progress_map.log 157697: ./MyProgress Address Kbytes RSS Dirty Mode Mapping 000056549c233000 428 428 0 r---- MyProgress 000056549c29e000 4960 4164 0 r-x-- MyProgress 000056549c776000 1656 348 0 r---- MyProgress # 过滤结果 $ cat my_progress_map.log |grep libtest.so 00007f7b1029a000 616 616 0 r---- libtest.so 00007f7b10334000 608 564 0 r-x-- libtest.so 00007f7b103cc000 168 60 0 r---- libtest.so 00007f7b103f6000 4 0 0 ----- libtest.so 00007f7b103f7000 4 4 4 r---- libtest.so 00007f7b103f8000 32 32 32 rw--- libtest.so
这个工具性能非常强劲,甚至可以查到实际使用的RSS到底是谁申请的,当前是否为脏页,对研究内存增长非常有效果。
合集:
Linux
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇