Linux 监控大量文件写入磁盘

背景

有个大量写入磁盘的需求,做了raid5。但是在写入过程中发现内存一直在增长,经过查询发现buffer/cached在稳定增加,于是非常疑惑。
为了查找原因,我经过了以下过程确认:

硬件确认

确认为软raid

最开始同事告诉我是做的硬件raid,但是测试过程总感觉不太对劲。

  1. 发现磁盘名称为md124、md126,这是Linux下软件raid的命名特征
  2. lsblk能够观察到实际使用的磁盘设备sda sdb sdc sdd
  3. 能够通过 cat /proc/mdstat 的方式查看到当前的raid硬盘信息
  4. 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到底是谁申请的,当前是否为脏页,对研究内存增长非常有效果。

posted @   风惊庭前叶  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
点击右上角即可分享
微信分享提示