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

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

问题现象

高可用服务突然因为心跳超时导致将整个节点给隔离了。 首先怀疑是网络问题,先查有没有网络异常。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 瞬间 应急止血
相关推荐
茶杯梦轩5 天前
从零起步学习RabbitMQ || 第二章:RabbitMQ 深入理解概念 Producer、Consumer、Exchange、Queue 与企业实战案例
服务器·后端·消息队列
YuMiao7 天前
gstatic连接问题导致Google Gemini / Studio页面乱码或图标缺失问题
服务器·网络协议
Sinclair10 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
Rockbean11 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek
茶杯梦轩11 天前
CompletableFuture 在 项目实战 中 创建异步任务 的核心优势及使用场景
服务器·后端·面试
海天鹰12 天前
【免费】PHP主机=域名+解析+主机
服务器
不是二师兄的八戒12 天前
Linux服务器挂载OSS存储的完整实践指南
linux·运维·服务器
芝士雪豹只抽瑞克五12 天前
Nginx 高性能Web服务器笔记
服务器·nginx
失重外太空啦12 天前
Tomcat
java·服务器·tomcat
Henry Zhu12312 天前
数据库:并发控制基本概念
服务器·数据库