跳转至

磁盘 IO 指标自查手册(node_exporter / Grafana node-exporter-full)

建立 2026-10-03 | 性质:只读参考文档,不含任何变更动作 | 用途:自查磁盘性能指标时逐项对照 对象:Grafana 大盘 node-exporter-full(uid rYdddlPWk,1860 r45)的 Storage Disk 行 关联:docs/BASELINE.md(环境事实)、env-monitor-deploy/artifacts/dashboards/node-exporter-full-1860-r45.json(面板定义)

0. 这份文件怎么用

  • 先看第 3 节的「自查速查表」做初判(正常 / 注意 / 异常三档),再回第 2 节查该指标的确切定义。
  • 第 6 节是本环境 2026-10-03 的基线读数,后续对比"是否变差"以它为参照。
  • 第 7 节给出复现命令,结论可自己重跑验证。

1. 数据链路(先确认数据是真的)

/proc/diskstats ──► node_exporter(:9100) ──► Prometheus ──► Grafana 面板
   内核计数器         转成 node_disk_*        按 job 抓取      PromQL rate()
环节 本环境事实
采集端 目标主机的 node_exporter,暴露 node_disk_*(dell-R620 上为 apt 包 1.7.0,sda/sdb 共 36 条)
Prometheus https://prometheus.rainchen.top,共 19 类 node_disk_* 指标
面板 grafana.rainchen.top/d/rYdddlPWk/node-exporter-full,磁盘面板在 Storage Disk 行(默认收起,需点开)

坑(job 标签单复数):dell-R620 的 job 标签是 external-node-exporter(单数), 其余 14 台集群外主机是 external-node-exporters(复数),K8s 节点是 node-exporter。 面板变量选错就会全盘空白。


2. 面板逐项详解

通用约定(读任何一张图都适用)

约定 说明
双向纵轴 read (−) / write (+) 零轴以上是写、以下是读。同一设备有两条线:读在负半轴、写在正半轴
颜色 = 设备 橙/黄 = sda,紫 = sdb;同色出现两次(一次读、一次写)
图例 Min / Mean / Max 不是瞬时值,是所选时间窗内该序列的最小 / 平均 / 最大。Max 才是"最坏那一刻"
数据本质 node_disk_*_total 是单调递增的累计计数器,面板一律用 rate(...[$__rate_interval]) 换算成每秒速率

2.1 Disk Read/Write IOps —— 每秒请求次数

rate(node_disk_reads_completed_total{instance="$node",job="$job"}[$__rate_interval])
rate(node_disk_writes_completed_total{instance="$node",job="$job"}[$__rate_interval])
项 内容
含义 每秒完成的读 / 写请求个数(不是字节)
内核字段 diskstats 第 1(reads completed)/ 第 5(writes completed)字段
单位 io/s
判读 只计次数、不计大小:IOPS 高 + 吞吐低 = 小块随机 IO(最伤盘);IOPS 低 + 吞吐高 = 大块顺序 IO(最省盘)

2.2 Disk Read/Write Data —— 每秒吞吐

rate(node_disk_read_bytes_total{...}[$__rate_interval])
rate(node_disk_written_bytes_total{...}[$__rate_interval])
项 内容
含义 每秒读 / 写的字节数(真正的带宽)
内核字段 diskstats 第 3(sectors read)/ 第 7(sectors written)字段 × 512 字节
单位 B/s,面板自动切 kB/s → MB/s
派生用法 平均单请求大小 = Data ÷ IOPS —— 两个面板一起看即可判断顺序 / 随机

2.3 Disk Average Wait Time —— 平均等待延迟(=iostat 的 await)

(rate(node_disk_reads_completed_total{...}) > bool 0)
  * (rate(node_disk_read_time_seconds_total{...}) / rate(node_disk_reads_completed_total{...}))
项 内容
含义 一个请求从入队到完成的平均耗时,含排队等待 + 真正被服务两段
内核字段 分子用第 4(time spent reading)/ 第 8(time spent writing)字段
单位 秒(面板自动显示 µs / ms / s / min)
为何最关键 IOPS / 吞吐只说"做了多少",只有 await 说"慢不慢"——直接决定上层(ES 写入、Grafana 查询、NFS 挂载)卡不卡
> bool 0 的作用 该设备该方向这期间无请求时,分母 rate 为 0 → 结果 NaN 会让曲线断开;强制成 0 使曲线连续

阈值参考:

盘类型 正常 偏慢 明显拥塞
NVMe / 企业级 SSD < 1 ms 1–5 ms > 10 ms
SATA SSD < 2 ms 2–10 ms > 20 ms
机械 HDD < 10 ms 10–20 ms > 20 ms(随机负载下 100 ms+ 常见)

2.4 Average Queue Size —— 平均队列长度(=iostat 的 aqu-sz)

rate(node_disk_io_time_weighted_seconds_total{instance="$node",job="$job"}[$__rate_interval])
项 内容
含义 设备队列里平均有多少个请求在排队 / 在途
内核字段 第 11(weighted time spent doing I/Os,加权 IO 时间:每个在途请求按其等待时长加权累加)
单位 无量纲(个)

阈值参考:

值 含义
≈ 0 基本空闲
≈ 1 平均总有 1 个请求在跑 / 等 —— 接近满负荷、尚未积压
持续 > 1 开始排队,上层开始感到延迟
2–4 明显饱和
远大于 4 严重积压(多为机械盘 / 远端 NFS 后端)

2.5 同行的其它面板(一句话备查)

面板 一句话
Disk R/W Merged 内核把相邻请求合并的次数/s;合并率高说明顺序访问多、效率好
Time Spent Doing I/Os 设备"有 IO 在跑"的时间占比(≈ busy%),趋近 100% 说明盘被打满
Disk Ops Discards / Flush SSD 的 TRIM / 丢弃请求 与 flush 请求数
Disk Sectors Discarded Successfully 成功丢弃的扇区数(SSD 健康相关)
Instantaneous Queue Size 采样瞬间的在途请求数(diskstats 第 9 字段 io_now),与 §2.4 的"平均"互补
Disk I/O Utilization 磁盘忙碌时间比例(同类行另一处的 node_disk_io_time_seconds_total)

3. 自查速查表(先看这张)

观察到的现象 判读 下一步
await 个位数 ms 以内、队列 < 1 正常 无需动作
await 持续 > 20 ms(HDD)或 > 10 ms(SSD) 注意 看是否伴随业务高峰;核对是否有大批量写入
await 均值到数百 ms、峰值到分钟级 异常 查该设备承载什么、哪个进程在写
队列持续 > 1 开始排队 结合 await 判断是盘慢还是请求太密
队列出现数千量级尖峰 严重积压 立即查这一时段的应用日志(ES / TSDB / 备份任务)
IOPS 高 + 吞吐低 小块随机 IO 检查是否可改为顺序 / 批量写
吞吐高 + IOPS 低 大块顺序 IO 属健康形态
某设备曲线整体消失 / 断口 设备无请求 或 设备异常 对照 node_disk_info 与主机日志核实

联动判据(Little 定律):

平均队列长度 ≈ 到达率(IOPS) × 平均驻留时间(await)      # L = λ × W

三者同源,会在时间轴同步起落。若某盘"await 高 + 队列长 + 吞吐却不高", 基本可锁定为小随机 IO 或后端(机械盘 / NFS)瓶颈,而非应用发得太猛。


4. 本环境基线读数(2026-10-03 快照,窗口 = 近 24h)

对象:dell-R620(192.168.31.250:9100,job external-node-exporter),设备 sda / sdb。

指标 sda sdb 判读
写 IOPS(/s) 百级 数十级 负载以写为主
读 IOPS(/s) 十级 个位数 读压力很小
读吞吐峰值 数百 kB/s 110 MB/s 读为偶发大块突发
写 await(min / mean / max) 198 µs / 794 µs / 10.4 ms 19.2 ms / 393 ms / 2.21 min sdb 明显拥塞
队列(min / mean / max) 0.009 / 0.026 / 0.298 0.177 / 6.07 / 2044 sdb 常年排队

结论(2026-10-03): 1. sda(系统盘)全程健康 —— await 微秒级、队列 < 0.3,无需关注。 2. sdb 是重负载盘且部分时段顶到瓶颈 —— 该盘承载宿主的 NFS 后端(Prometheus TSDB + ES 全部数据), 大量写入落在这里,尖峰属预期;但若数百 ms 的 await 长期维持,会拖慢 ES 写入与 Grafana 查询。 3. 图中 14:00–15:00 的竖线是同一波写入在 await / 队列 / 吞吐三个面板上的同步投影; 20:00 附近 IOps 曲线的剧烈抖动(读侧打到负半轴)多为"该刻无请求 / 设备短暂静默",需与主机日志对照核实。

注:kubelet_volume_stats_*(PVC 层)在本环境失真不可用(nfs-csi 的同一后端上所有 PVC 报同一 used、 capacity 报后端卷总量),NFS 卷水位与性能一律看宿主 node_*,不看 PVC 指标。


5. 后续自查时怎么对比

  1. 打开 Storage Disk 行,把窗口设为与本次相同的 24h,逐项对照第 4 节表格。
  2. 只看 Mean 与 Max 两列:Mean 判断常态、Max 判断最坏。
  3. 若 sdb 的 await Mean 由 393 ms 量级持续上升,或队列 Mean 长期 > 10,即为劣化信号。
  4. 劣化时按第 3 节速查表定位,再用第 6 节命令取原始数据复现。

6. 复现命令(只读)

# 1) 采集端:确认指标在暴露(把 <host> 换成目标主机)
curl -s --max-time 5 http://<host>:9100/metrics | grep -E '^node_disk_(read_bytes|written_bytes|io_time_seconds)_total'

# 2) Prometheus 端:确认指标种类与设备(需可访问 prometheus.rainchen.top)
B=https://prometheus.rainchen.top/api/v1/query
curl -s -G "$B" --data-urlencode 'query=count by (__name__)({__name__=~"node_disk_.*"})'
curl -s -G "$B" --data-urlencode 'query=count by (device)(node_disk_read_bytes_total{instance="192.168.31.250:9100"})'

# 3) 面板定义:查某个面板的确切 PromQL(磁盘面板在 8790~9180 行附近)
grep -n 'Disk Read/Write IOps\|Disk Read/Write Data\|Disk Average Wait Time\|Average Queue Size' \
  env-monitor-deploy/artifacts/dashboards/node-exporter-full-1860-r45.json

7. 相关文档

文档 关系
docs/BASELINE.md 环境事实:主机、Prometheus / Grafana 入口、job 与标签
docs/MONITORING-ROADMAP.md 监控蓝图;G3「硬件层太薄」= RAID(perccli) / 盘 SMART / 电源 / 网卡错误,与本手册互补(本手册只覆盖 OS 层磁盘 IO)
env-monitor-deploy/docs/SOP.md 监控工程本体与面板下发机制
control-plane-metrics-20261003/docs/SOP.md 容量水位告警(含宿主 NFS 后端盘)

来源:/home/rain/Documents/k8s_ins/docs/DISK-IO-METRICS.md | 最后更新:2026-10-03 02:08(由 build/sync.py 同步,请勿在站点侧修改)