脏页“幽灵”的捕获与处理

夜深人静,结束了一天的工作,拖着疲惫的身体,我终于躺在了床上,闭上眼睛,享受着宁静的床。 "叮铃铃,叮铃铃",急促的电话铃声,划破安静,我努力睁开眼睛,看了下时间,零点十分。 又是那该死的幽灵,我只好爬起来,冲了杯咖啡,打开电脑,为抓取幽灵做好前期的准备。

问题现象

高可用服务突然因为心跳超时导致将整个节点给隔离了。 首先怀疑是网络问题,先查有没有网络异常。ip addr show看了下,隔离的节点网口状态都正常;dmesg -T看了下,未发现最近时间有网口异常的记录;sar -n EDEV看了下,所有网口都没有错误的记录。由此,基本排除了网络问题。 其次怀疑是资源问题,查cpu资源,sar看了下,未发现有cpu资源突增;查内存资源,sar -r看了下,未发现内存资源有突增;查io资源,sar -d -p看了下,发现系统盘的await值飙升到了6000+,妥妥的慢盘状态。

分析

发现明显异常,但磁盘io与网络逻辑上独立,所以需要快速验证下关联性。 使用工具模拟系统盘慢盘的状态,确实触发了高可用服务的心跳超时。再回到问题时间段,分析可能造成读写磁盘的压力增大的原因,发现logrotate的切割会在这个时间段触发。 再进行logrotate切割与磁盘io压力验证。 压测脚本:拷贝5个512M的文件到目标目录,日志切割(压缩后gz文件大小502M) 结果: 三星盘:logrotate触发时,await平均600-700,最大1000+,同时发现脏页存在快速增长和下刷的情况 英极盘:logrotate触发时,await平均2000,最大2300+,同时发现脏页存在快速增长和下刷的情况 幽灵抓到了!logrotate触发脏页快速增大,进而触发了系统盘集中下刷数据,系统盘产生慢盘,进而导致高可用服务的bug被触发,影响到了网络心跳监控进程的逻辑。

处理建议

现场环境升级服务通常比较难,在不升级服务解决高可用服务bug的前提下,来缓解问题。

脏页回写导致磁盘压力大、影响业务进程,通常意味着脏页堆积水位过高 ,触发了回写 时压力集中。你的核心目标应该是让回写从"集中爆发"变为"持续平滑" 。 针对这个问题,解决方案可以分为四层:临时处理、系统级调优、关键进程隔离、以及文件系统层优化。

  • 临时处理
  1. 日志切割配置分散:将logrotate的切割从整体划分为多个部分,分摊切割压力

  2. 减少缓存使用概率: 减少写缓存的使用概率

    编辑 /etc/fstab,添加 sync

    /dev/sda1 /data ext4 defaults,sync 0 0

    重新挂载生效

    mount -o remount,rw,sync /

  • 系统级调优

这是解决脏页回写压力的根本手段 。核心思路是降低触回写的水位、提高回写频率

复制代码
# 后台回写阈值:达到此值开始异步刷盘,建议 3-5%(原默认10%)
vm.dirty_background_ratio = 5
# 前台阻塞阈值:达到此值进程写入会被阻塞,建议 10-15%(原默认20%)
vm.dirty_ratio = 10
# 回写线程唤醒间隔:缩短至 1秒(原默认5秒),让回写更平滑
vm.dirty_writeback_centisecs = 100
# 脏页存活时间:缩短至 10秒(原默认30秒),避免脏页堆积过久
vm.dirty_expire_centisecs = 1000
# 元数据缓存:适当回收内存压力(默认100,内存紧张可加大)
vm.vfs_cache_pressure = 200
  • 关键进程隔离

如果系统中有多块磁盘 ,且只有某块盘(如数据盘)压力大 ,而系统盘或其它盘正常 ,可以针对单个块设备 进行回写带宽配额限制,避免"一台机器受影响,全盘应用都卡"。 这是比全局调优更精细、更有效的手段 ,尤其适合数据库、日志服务等独占磁盘的场景

查看设备号并设置回写配额

复制代码
# 查看设备 major:minor
lsblk
# 例如 nvme0n1 的 MAJ:MIN = 259:0
# 设置该设备最低回写带宽配额(保障其回写能力)
echo 20 > /sys/class/bdi/259:0/min_ratio
# 限制该设备最大回写带宽配额(防止其抢占系统盘带宽)
echo 60 > /sys/class/bdi/259:0/max_ratio

作用解析

参数 作用 典型场景
min_ratio 保障该设备最少获得X%的系统回写带宽 重要业务盘,避免被饿死
max_ratio 限制该设备最多占用X%的系统回写带宽 日志盘、非关键盘,防止干扰系统盘

⚠️ 注意 :该特性需要内核支持(Alibaba Cloud Linux 全系支持,主流发行版如RHEL/CentOS 8+ 部分支持),若不支持则/sys/class/bdi/下可能无此文件

  • 文件系统层优化 I/O调度器

  • SSD/NVMe :使用 nonenoop(减少调度开销)

  • HDD :使用 deadline(降低延迟)

    echo deadline > /sys/block/sda/queue/scheduler

🚫 常见误区(请一定避开)

错误操作 后果 正确做法
频繁执行 echo 3 > drop_caches 破坏缓存命中率,I/O 反升 仅用于基准测试或紧急内存释放
盲目调大 dirty_ratio 至 40%+ 回写时系统长时间卡死 普通服务器建议 ≤20%
认为调小脏页阈值一定会提升性能 阈值过小,频繁刷盘,写入性能下降 根据写多读少场景取舍

✅ 总结:推荐优先级方案

方案 难度 见效速度 适用场景
1. 全局脏页阈值调优 ⭐⭐ 立即 所有场景首选
2. 单盘回写配额控制 ⭐⭐⭐ 立即 多磁盘、关键业务隔离
3. I/O调度器调优 ⭐⭐ 立即 SSD/HDD 混合
4. 手动 drop_caches 瞬间 应急止血
相关推荐
zfxwasaboy4 小时前
Linux宏clamp(val, lo, hi)的作用
linux·运维·服务器
李彦亮老师(本人)8 小时前
【Linux系统】Rocky Linux 9.7操作系统简介
linux·运维·服务器·docker·kubernetes
minji...8 小时前
Linux 进程信号(二)信号的保存,sigset_t,sigprocmask,sigpending
linux·运维·服务器·网络·数据结构·c++·算法
何中应8 小时前
Grafana如何重置密码
linux·运维·服务器·grafana
手握风云-9 小时前
基于 Java 的网页聊天室(三)
服务器·前端·数据库
开开心心_Every10 小时前
限时免费加密、隐藏、锁定文件文件夹好工具
运维·服务器·人工智能·edge·pdf·逻辑回归·深度优先
野犬寒鸦10 小时前
Redis复习记录day1
服务器·开发语言·数据库·redis·缓存
龙俊俊10 小时前
服务器模型部署与加载
服务器·人工智能·深度学习
木木em哈哈11 小时前
记一次在线编辑器的探索
linux·服务器·网络
我要成为嵌入式大佬11 小时前
正点原子MP157--问题详解--二(NFS挂载根文件系统双网卡设置)
linux·服务器·网络