2. 观测工具箱
本章目标
- 建立"指标 → 工具"的映射,而不是"命令 → 背输出"
- 掌握 iostat / vmstat / sar / pidstat / perf / BCC 的分工
- 学会看延迟分布,而不只看平均值
《Systems Performance》把观测手段分成三类。背命令是下策,理解这三条路,任何新工具你都能自己归位:
| 路径 | 原理 | 代表 | 特点 |
|---|---|---|---|
| 计数器 | 内核维护的累计值 | /proc、/sys | 开销为零,但只有"总量"没有"单个事件" |
| 快照/采样 | 定期读计数器求差 | iostat、vmstat、sar | 看趋势与负载量 |
| 追踪 | 记录每个事件 | perf、ftrace、BPF/eBPF | 有每个 IO 的细节,开销随事件数增长 |
选择原则:先计数器/快照定位"哪里不对劲",再上追踪工具问"具体哪个事件"。
2.1 iostat:磁盘 IO 的主战武器
bash
iostat -x 1 # 每秒刷新,扩展统计逐列精讲(只讲你要背下来的 8 列):
| 列 | 含义 | 怎么用 |
|---|---|---|
r/s w/s | 每秒读/写 IO 次数 | 就是 IOPS;× 平均 IO 大小 = 吞吐 |
rkB/s wkB/s | 每秒读/写数据量 | 带宽;判断负载是"IOPS 型"还是"带宽型" |
rrqm/s wrqm/s | 被块层合并的 IO | 顺序写合并率高是好事 |
r_await w_await | 平均完成延迟(毫秒) | 核心指标;NVMe >5ms、HDD >20ms 就要警惕 |
aqu-sz | 平均队列深度 | 排队证据;>1 说明设备已饱和或路径并发高 |
%util | 设备"忙"的时间占比 | HDD 上接近 100% = 饱和;NVMe 上会失真(并行能力强,100% 仍可能有余量) |
%util 失真是面试高频题:它统计的是"至少有一个 IO 在设备中"的时间比例,而 NVMe 可并行处理几十个 IO —— 所以并行设备上判断饱和要看 aqu-sz + await 的组合,而不是 %util。
2.2 vmstat / sar:内存与回写
bash
vmstat 1
sar -B 1 # 页统计(需要 sysstat)
sar -r 1 # 内存vmstat 关注四组:
si/so:swap 换入/换出 —— 非 0 说明内存已经不足,IO 慢可能是"假象"(真因是内存)bi/bo:块设备读/写速率(KB/s)—— 粗粒度的磁盘吞吐wa:等待 IO 的 CPU 时间占比 —— 高wa+ 高await= 磁盘是瓶颈st(虚拟机环境):被宿主机偷走的时间 —— 虚拟机"磁盘慢"的隐藏原因
脏页观察(呼应第 1 章):
bash
grep -E 'Dirty|Writeback' /proc/meminfo
cat /proc/vmstat | grep -E 'nr_dirty|nr_writeback'2.3 pidstat / iotop:进程级归因
集群运维最常见的追问不是"盘慢",而是"谁把盘写慢了"。
bash
pidstat -d 1 # 每个进程的读/写速率与延迟
iotop -o -P # 只显示有 IO 的进程pidstat -d 的 kB_rd/s kB_wr/s 直接给出进程归因。注意容器环境要进宿主机看(或用 cadvisor/pcp),容器内的 IO 计数默认不隔离 —— 这是 K8s 存储排障的常见坑(第三篇会再遇到)。
2.4 perf 与 BCC:显微镜
perf:CPU 侧看 IO
bash
perf record -g -e block:block_rq_issue -e block:block_rq_complete sleep 10
perf report更常用的其实是 perf record -g 找"CPU 都花在哪"——当 IO 慢其实是 CPU/锁慢时(比如 librbd 客户端压了太多 CPU)。
BCC(eBPF):存储运维的杀手锏
bash
biolatency-bpfcc 10 1 # 10 秒内块层延迟直方图
biosnoop-bpfcc # 每个IO一行:进程、设备、扇区、延迟
fileslower-bpfcc 10 # 超过 10ms 的文件操作
offcputime-bpfcc -K 5 # 谁在等(含等IO)—— 线程级阻塞归因biolatency 的直方图输出是你第一次见到"延迟分布":
text
usecs : count distribution
0 -> 1 : 0 | |
...
64 -> 127 : 1212 |************** |
128 -> 255 : 3411 |************************************ |
8192 -> 16383 : 87 | | ← 长尾!平均值 0.3ms 的盘上,P99 可能是 16ms —— 用户抱怨的恰恰是长尾。这是"平均延迟会骗人"的具象证据。
2.5 网络观测:存储网络的仪表盘
第二篇的 Ceph 集群健康与否,一半在网络。先把这五条记熟:
bash
ip -s link # 接口错误/丢包计数
ss -ti # TCP 连接的 rtt、cwnd、retrans(重传)
ethtool -S eth0 | grep -iE 'err|drop' # 网卡级丢包
sar -n TCP,ETCP 1 # 每秒重传数
ping -c 100 -i 0.01 <peer> # RTT 分布(min/avg/max/mdev)2.6 工具速查表
| 我想知道… | 用什么 |
|---|---|
| 磁盘 IOPS/吞吐/延迟 | iostat -x 1 |
| 磁盘是不是瓶颈 | iostat 的 await+aqu-sz + vmstat 的 wa |
| 谁在写盘 | pidstat -d 1 / iotop |
| IO 延迟分布(P99) | biolatency-bpfcc |
| 单个慢 IO 的细节 | biosnoop-bpfcc / fileslower |
| 内存是否泄漏到 swap | vmstat 1 的 si/so |
| 网络重传/丢包 | ss -ti / ethtool -S / sar -n TCP,ETCP |
| 历史回溯(当时发生了什么) | sar 的日志(提前开启 sysstat 收集) |
sar 的日志是运维的行车记录仪:
sar -f /var/log/sysstat/saXX可以回放任意一天的历史 —— 提前配好sysstat收集,故障后才有"案发当时"的证据。
本章小结
- 观测三路径:计数器(零开销)→ 快照(趋势)→ 追踪(单事件)
iostat -x的 8 列是每天都要用的基本功;%util在并行设备上不可靠- 延迟要看分布(biolatency 直方图),平均值会掩盖长尾
- 进程归因(pidstat)与网络五命令(ip/ss/ethtool/sar/ping)是集群运维的前置技能
自测
QuizNVMe 盘上 iostat 显示 %util 持续 100%、await 0.8ms、aqu-sz 8、80k IOPS,最合理的判断是?
Quiz用户反馈「偶尔卡一下」,但 iostat 平均延迟正常。下一步最应该做什么?
Lab · 给一台机器做一次全身体检入门
1. 用 fio 制造混合负载(随机读 70% + 写 30%):`fio --name=mix --rw=randrw --rwmixread=70 --bs=4k --size=2G --numjobs=4 --time_based --runtime=60 --directory=/tmp/fio` 2. 同时采集 `iostat -x 1`、`vmstat 1`、`pidstat -d 1`、`biolatency-bpfcc 60 1` 的输出并保存。 3. 写一份 5 行的"体检报告":IOPS、吞吐、平均/P99 延迟、队列深度、TOP 写入进程。 4. **验收标准**:报告里每个数字都能指出出处工具和含义;P99 来自直方图而不是平均值。