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 on 2025-02-13 00:31  风惊庭前叶  阅读(66)  评论(0)    收藏  举报