我们有几台 90TB 服务器(Areca RAID-6 分区为 10 个 ext4 分区)。
该应用程序读取专用硬件设备并将数据以恒定的8 到 10 MB/秒的速度写入磁盘。(应用程序运行单独的读取器和写入器线程,其间有内存缓冲区)
有时文件操作会慢得像爬行一样,例如,fwrite()写入 200 字节数据需要 10-30 秒,ftell()获取文件位置也需要类似的时间等。
有时(但并非总是),当系统速度变慢时,top会显示所有进程的 CPU 利用率为 0%,类似于此服务器故障发布。
减速会持续几分钟,然后机器就会恢复正常。稍后还会再次发生。
没有“每日频率”的减速,所以我消除了通过cron/anacron等运行的东西。
然而,在减速期间,系统负载从 0.4(正常)变为 3-4。iotop经常显示kworker/u16:0+flush-8:112非常高的 I/O %。 top等vmstat显示非常高%wa,因此某个地方存在 I/O 瓶颈。
我已将 I/O 调度程序更改为mq-deadline.
此外,应用程序fsync每 5 秒在包含正在写入的打开文件的文件系统上运行一次。
我已经用谷歌搜索了几天,寻找可能导致速度下降的原因,以找到可以调整哪些参数,但到目前为止还没有运气。
关于如何针对这种持续写入场景调整 Linux 有什么建议吗?
森托斯8
# uname -a
Linux 4.18.0-147.el8.x86_64 #1 SMP Wed Dec 4 21:51:45 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
IOTOP输出
Total DISK READ : 161.32 K/s | Total DISK WRITE : 0.00 B/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b' 10666 rt/0 root 161.32 K/s 0.00 B/s 0.00 % 4.43 % MyWritingApp'
Total DISK READ : 239.58 K/s | Total DISK WRITE : 78.27 M/s
Actual DISK READ: 239.58 K/s | Actual DISK WRITE: 2.20 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b' 431412 be/4 root 135.01 K/s 0.00 B/s 0.00 % 44.80 % [kworker/u16:8-flush-8:32]'
b' 10666 rt/0 root 104.57 K/s 78.11 M/s 0.00 % 1.88 % MyWritingApp'
b' 8853 be/3 root 0.00 B/s 9.27 K/s 0.00 % 0.01 % [jbd2/sdh1-8]'
b' 1123 ?dif mysql 0.00 B/s 149.57 K/s 0.00 % 0.00 % mysqld --basedir=/usr'
Total DISK READ : 388.68 K/s | Total DISK WRITE : 14.98 M/s
Actual DISK READ: 469.32 K/s | Actual DISK WRITE: 1899.42 K/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b' 338764 be/4 root 388.68 K/s 0.00 B/s 0.00 % 89.25 % [kworker/u16:0+flush-8:112]'
b' 1123 ?dif mysql 0.00 B/s 955.83 K/s 0.00 % 0.00 % mysqld --basedir=/usr'
b' 2740 be/4 apache 0.00 B/s 1353.76 B/s 0.00 % 0.00 % httpd -DFOREGROUND'
b' 10664 be/4 root 0.00 B/s 1353.76 B/s 0.00 % 0.00 % php /usr/local/dvstor/bin64/DvStorStartRecording.php mode=ASI tsNum=0'
b' 10666 rt/0 root 0.00 B/s 14.04 M/s 0.00 % 0.00 % MyWritingApp'
Total DISK READ : 609.63 K/s | Total DISK WRITE : 15.87 K/s
Actual DISK READ: 609.63 K/s | Actual DISK WRITE: 31.74 K/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b' 338764 be/4 root 601.70 K/s 0.00 B/s 0.00 % 99.43 % [kworker/u16:0+flush-8:112]'
b' 711 be/4 root 7.93 K/s 0.00 B/s 0.00 % 3.00 % systemd-journald'
b' 9246 be/3 root 0.00 B/s 7.93 K/s 0.00 % 0.00 % [jbd2/sdi1-8]'
b' 933 be/3 root 0.00 B/s 1354.15 B/s 0.00 % 0.00 % auditd'
b' 1966 be/4 root 0.00 B/s 2.64 K/s 0.00 % 0.00 % rsyslogd -n'
b' 2740 be/4 apache 0.00 B/s 1354.15 B/s 0.00 % 0.00 % httpd -DFOREGROUND'
Run Code Online (Sandbox Code Playgroud)
VMSTAT 输出
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 2 194048 334164 612708 12537168 0 1 14 1114 13 217 1 2 95 1 0
0 2 194048 329368 614000 12540308 0 0 646 0 5136 6152 1 1 78 19 0
0 2 194048 324640 615288 12543276 0 0 622 96 5249 6541 1 2 79 18 0
0 2 194048 321584 616624 12546188 0 0 664 512 5660 6815 2 2 81 15 0
0 2 194048 317788 617884 12549124 0 0 626 52 6079 7983 2 3 80 15 0
15930768 K total memory
2445452 K used memory
2673404 K active memory
11678768 K inactive memory
318308 K free memory
617888 K buffer memory
12549120 K swap cache
8212476 K total swap
194048 K used swap
8018428 K free swap
Run Code Online (Sandbox Code Playgroud)
输入/输出调度程序
# for d in {b..k}; do echo -n "sd${d} " ; cat /sys/block/sd${d}/queue/scheduler; done
sdb [mq-deadline] kyber bfq none
sdc [mq-deadline] kyber bfq none
sdd [mq-deadline] kyber bfq none
sde [mq-deadline] kyber bfq none
sdf [mq-deadline] kyber bfq none
sdg [mq-deadline] kyber bfq none
sdh [mq-deadline] kyber bfq none
sdi [mq-deadline] kyber bfq none
sdj [mq-deadline] kyber bfq none
sdk [mq-deadline] kyber bfq none
Run Code Online (Sandbox Code Playgroud)
最后我认为问题与文件级碎片有关。
虽然fsck没有报告高百分比的碎片,但我运行了另一个工具(抱歉,可能忘记了是哪个filefrag),它显示大型媒体文件中的碎片非常高。
(文件系统有很多很多1GB的视频文件)。
系统级问题的解决方法是:
fallocate()使用系统调用将应用程序更改为预分配 1GB 空间