问题现象
Linux 系统在运行高负载写入时,系统日志(dmesg / /var/log/messages)可能出现如下警告:
echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
INFO: task blocked for more than 120 seconds.
Not tainted 3.10.0-xxx.el7.x86_64 #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
原因分析
-
默认缓存机制: 默认情况下,Linux 最多会使用 40% 的可用内存 作为文件系统缓存(Page Cache)。当脏页数量超过阈值后,文件系统会将缓存中的脏数据同步写入磁盘,导致后续的 I/O 请求变为同步写入。
-
超时机制与 I/O 瓶颈: 系统在将缓存写入磁盘时,默认设定了 120 秒的超时等待时间(
hung_task_timeout_secs)。若后端存储或 I/O 子系统的写入处理速度不够快,未能在 120 秒内将大量累积的脏数据全部同步完成,就会触发此错误。由于 I/O 响应迟缓,更多请求在队列中阻塞堆积,最终可能导致系统内存耗尽甚至失去响应。 -
大内存机器的放大效应: 此现象通常发生在大内存服务器上。内存越大,40% 对应的缓存数据量就越大,短时间内将数十甚至上百 G 数据全部 flush 到磁盘所需的 I/O 时间更长,超时的概率也随之显著增加。
关键内核参数解析
文件系统缓存由以下两个关键内核参数协同控制:
-
vm.dirty_background_ratio: 指定当文件系统缓存中的脏页数量达到系统内存的百分比(如 5% 或 10%)时,后台回写进程(pdflush/flush/kdmflush)被唤醒,开始异步将脏页写入外存,此时不会阻塞前台应用进程。 -
vm.dirty_ratio: 指定当脏页数量达到系统内存的百分比(如 10% 或 20%)时,系统进入强制同步刷盘阶段。在此过程中,进行 I/O 写入的前台应用进程将被挂起并阻塞,必须等待脏页被写回磁盘后才能继续。
解决方法与参数调优
将默认的 40% 缓存比例下调至 10% 或更低,缩减每次突发刷盘的数据量,使 I/O 写入更加平滑平稳。
1. 查看当前内核参数
sysctl vm.dirty_ratio
sysctl vm.dirty_background_ratio
2. 临时生效调整(推荐配置)
sysctl -w vm.dirty_background_ratio=5
sysctl -w vm.dirty_ratio=10
3. 永久生效配置
编辑配置文件 /etc/sysctl.conf:
# 限制脏页比例,防止突发大量刷盘导致120秒超时阻塞
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
执行以下命令重新加载使配置生效:
sysctl -p
优化后,系统将更早、更平稳地触发后台异步刷盘,有效避免短时间内大脏页积压导致 I/O 阻塞超时。