
你有没有遇到过这种“诡异”的场景:
服务突然开始响应变慢,接口请求变得黏糊糊的,像泡在糖水里。你以为是数据库,又查不出慢 SQL;以为是 CPU,负载却正常;一圈排查下来,最后你才发现:
是磁盘 I/O 延迟突然飙高,几秒之内吞了整个服务的吞吐。
但问题是,它又恢复得很快,几秒钟之后像没事一样。这种“闪一下就跑”的问题,最容易逃过你的传统监控体系。
所以这次,我们要聊聊一件服务器运维中非常“隐蔽”的事:
如何在磁盘 I/O 突发延迟的瞬间,就能发现它,并自动触发告警,甚至关联到业务侧降级处理?
磁盘延迟 ≠ 磁盘利用率高
很多人做磁盘监控,只看使用率、剩余空间、读写次数。这些东西好像挺全,但它们都没法告诉你一个本质的问题:
“现在磁盘是不是在卡着?”
使用率可以很低,但延迟却很高。 比如你有个云盘,读写量没问题,但底层存储服务负载高,它的 IOPS 被限制了,这时候你磁盘延迟可能达到几十毫秒甚至几百毫秒,而你还蒙在鼓里。
怎么知道磁盘“正卡顿”?
从操作系统角度看,磁盘延迟主要体现在这两个指标上:
await
—— 平均每个 I/O 操作的等待时间(单位:ms)svctm
—— 服务时间(操作系统发出请求到完成的时间)
用 iostat
看是最直接的方式:
bashiostat -dx 1
输出中你会看到:
bashDevice: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
vda 0.00 0.00 10.00 5.00 100.00 50.00 10.00 0.50 45.00 2.00 90.00
👆 await
为 45ms,说明磁盘 I/O 已经有排队现象了。
如果你不做实时采样,等你 ELK 日志发现响应慢,早已错过告警窗口。
秒级监控,才是对付“突发”的唯一方式
我们遇到过最夸张的情况是:磁盘延迟持续 5 秒就恢复了,事后再也重现不了,但那5秒内,业务请求 504 暴涨、MQ 积压、DB死锁。
这时候你需要的是 秒级采集 + 秒级可视化。
Prometheus + Node Exporter:
安装好 Node Exporter 后,你会获取这些指标:
node_disk_read_time_seconds_total
node_disk_write_time_seconds_total
node_disk_io_time_seconds_total
node_disk_io_time_weighted_seconds_total
用这些你就能计算出磁盘等待时间变化趋势。
如何用 PromQL 计算 I/O 延迟?
promqlrate(node_disk_io_time_seconds_total[5s])
/
rate(node_disk_reads_completed_total[5s] + node_disk_writes_completed_total[5s])
单位是秒,可以乘以 1000 得到 ms。
你可以设定一个警戒线,比如:
promql(rate(...) * 1000) > 50
也就是 I/O 平均延迟超过 50ms 就触发。
Alertmanager 秒级告警配置
yamlgroups:
- name: io-latency
rules:
- alert: DiskIOLatencyHigh
expr: (rate(node_disk_io_time_seconds_total[5s]) / rate(node_disk_reads_completed_total[5s] + node_disk_writes_completed_total[5s])) * 1000 > 50
for: 10s
labels:
severity: warning
annotations:
summary: "磁盘 I/O 延迟过高"
description: "当前磁盘平均等待时间超过 50ms,可能引起请求阻塞"
设置 for: 10s
表示延迟必须持续 10 秒以上才告警,避免抖动误报。
Grafana 面板怎么做?
建议做以下可视化:
面板名称 | 说明 |
---|---|
I/O 延迟实时图 | 展示每个设备的 await |
写入/读取队列长度 | 展示 avgqu-sz |
IOPS 趋势图 | 总读写次数趋势 |
延迟 + 请求叠加图 | 分析是否“高请求 + 高延迟”还是“低请求 + 高延迟”(后者更危险) |
可以加个 Panel 显示告警日志实时回放,这样更直观。
延迟背后可能是“云磁盘抖动”
你在本地测试很快,部署上云就开始抖,怀疑人生。
为什么?
因为你是在共享 IOPS、共享带宽资源。
云盘尤其是按量计费的云服务,很可能因为其他租户造成后端磁盘拥堵,而你并无感知。
这时你能做的:
- 配置监控 → 量化延迟波动
- 联系云厂商支持 → 要求检查物理磁盘分布
- 开启弹性 IOPS 配额 → 设置最小基线
- 考虑落盘缓存方案,如使用 NVMe 做缓存盘
I/O 延迟大,会引发“蝴蝶效应”
磁盘不是慢一点那么简单。它一旦延迟高,整个链路都可能被拖死:
- DB 写入慢 → 连接积压 → DB 超时 → API 超时
- 日志写入慢 → 异常追踪丢失 → 无法回溯问题
- 缓存写盘失败 → 脏数据丢失 → 数据不一致
你以为它只是“慢了一点”,但其实业务已经开始“失血”。
结合业务维度的告警策略
不能只监控硬件级指标,还要结合业务指标,如:
- 接口响应时间 > 2s 的比例
- 错误码 5xx 增长速率
- 任务队列积压量
配合 disk_io_latency
指标,可以做如下联动告警:
yaml- alert: BusinessErrorAndDiskLatency
expr: (rate(http_5xx_total[1m]) > 10) and (disk_io_latency_ms > 50)
for: 30s
这说明你的磁盘延迟已经影响到用户了。
秒级监控带来的最大收益
- 你不再被用户先发现问题
- 你能在瓶颈还未波及全局前限流、降级
- 你可以留痕调查“瞬时异常”而不是“错过现场”
这就像赛车中的“爆胎预警系统”,爆炸的不是轮胎,是时间窗口。你早发现1秒,就能避免下一连串“追尾”。
如果你还在用 1 分钟采集周期的老监控方式,面对这种“只活5秒”的 I/O 闪断,你就只能等用户来投诉。
但如果你现在就升级 Prometheus 的抓取粒度、打通告警链路、加上 Grafana 的实时可视化,你就能提前10秒识别事故。
10秒听起来不多,但对服务器来说,足够救命。