3. 性能瓶颈分析:CPU、内存、磁盘IO、网络带宽的常见瓶颈识别方法
在 Prometheus 监控体系中,性能瓶颈的识别是调优的前提。本章聚焦于四大核心资源——CPU、内存、磁盘 IO 和网络带宽,结合 Prometheus 的指标采集与查询特性,系统性地讲解如何通过关键指标、告警规则和可视化面板快速定位瓶颈。
核心原则: 瓶颈识别不是孤立地看单一指标,而是通过“资源使用率 → 饱和度 → 错误率”三层模型(USE 方法)进行交叉验证。Prometheus 的
rate()、irate()、avg_over_time() 等函数是分析时间序列趋势的核心工具。
3.1 CPU 瓶颈识别
CPU 瓶颈通常表现为用户态/内核态使用率持续高位、上下文切换频繁或运行队列堆积。Prometheus 通过 node_cpu_seconds_total 和 node_load* 系列指标暴露 CPU 状态。
3.1.1 关键指标与阈值
| 指标名称 | 含义 | 典型瓶颈阈值 |
|---|---|---|
node_cpu_seconds_total{mode="user"} |
用户态 CPU 时间 | 使用率 > 80% 持续 5 分钟 |
node_cpu_seconds_total{mode="system"} |
内核态 CPU 时间 | 使用率 > 30% 且持续上升 |
node_load1 / node_load5 / node_load15 |
系统平均负载(1/5/15 分钟) | 负载值 > CPU 核心数 * 0.7 |
node_context_switches_total |
上下文切换次数 | 每秒切换 > 10000 次(视核心数) |
3.1.2 典型查询与告警规则
# CPU 使用率(排除 idle 和 iowait)
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 上下文切换速率
rate(node_context_switches_total[5m])
# 告警规则:CPU 使用率过高
- alert: HighCpuUsage
expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Instance {{ $labels.instance }} CPU usage > 80%"
避坑提示: 不要直接使用
node_cpu_seconds_total 的原始值,必须通过 rate() 或 irate() 转换为每秒速率。另外,node_load 是值,需要结合 CPU 核心数判断,例如 4 核机器负载 3.5 属于正常,但 2 核机器负载 3.5 则已过载。
3.2 内存瓶颈识别
内存瓶颈主要体现为可用内存不足、交换分区(swap)频繁使用或 OOM Killer 触发。Prometheus 的 node_memory_* 指标族提供了详细的内存分布数据。
3.2.1 关键指标与阈值
| 指标名称 | 含义 | 典型瓶颈阈值 |
|---|---|---|
node_memory_MemAvailable_bytes |
可用内存(含缓存和缓冲区) | 低于总内存 10% |
node_memory_SwapTotal_bytes / node_memory_SwapFree_bytes |
交换分区总量与剩余 | Swap 使用率 > 50% |
node_vmstat_pswpin / node_vmstat_pswpout |
换入/换出页数 | 任何非零值持续出现 |
process_resident_memory_bytes(进程级) |
进程常驻内存 | 单个进程占用 > 总内存 50% |
3.2.2 典型查询与告警规则
# 内存使用率(基于可用内存)
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# Swap 使用率
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100
# 告警规则:可用内存不足
- alert: LowMemory
expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 < 10
for: 2m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} available memory < 10%"
专家建议: 内存瓶颈的“黄金信号”是
node_vmstat_pswpin 和 node_vmstat_pswpout。只要出现持续的换页操作,即使内存使用率只有 60%,也说明内存已经不足——因为系统被迫使用 swap 来腾出空间。此时应优先排查大内存进程或调整内核参数 vm.swappiness。
3.3 磁盘 IO 瓶颈识别
磁盘 IO 瓶颈通常表现为 IO 等待时间(iowait)升高、磁盘队列深度过大或吞吐量达到硬件上限。Prometheus 通过 node_disk_* 指标暴露磁盘性能数据。
3.3.1 关键指标与阈值
| 指标名称 | 含义 | 典型瓶颈阈值 |
|---|---|---|
node_disk_io_time_seconds_total |
磁盘 IO 时间(秒) | IO 使用率 > 80%(通过 rate 计算) |
node_disk_io_now |
当前正在处理的 IO 请求数 | 持续 > 磁盘队列深度(通常 2-4) |
node_disk_read_bytes_total / node_disk_written_bytes_total |
读写字节数 | 接近磁盘最大吞吐量(如 HDD 约 200MB/s) |
node_disk_io_time_weighted_seconds_total |
加权 IO 时间(反映等待时间) | 平均 IO 延迟 > 100ms |
3.3.2 典型查询与告警规则
# 磁盘 IO 使用率(基于 IO 时间占比)
rate(node_disk_io_time_seconds_total[5m]) * 100
# 平均 IO 延迟(毫秒)
rate(node_disk_io_time_weighted_seconds_total[5m]) / rate(node_disk_io_time_seconds_total[5m]) * 1000
# 告警规则:磁盘 IO 延迟过高
- alert: HighDiskIOLatency
expr: (rate(node_disk_io_time_weighted_seconds_total[5m]) / rate(node_disk_io_time_seconds_total[5m]) * 1000) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Instance {{ $labels.instance }} disk IO latency > 100ms"
避坑提示:
node_disk_io_time_seconds_total 是累积计数器,必须用 rate() 转换为每秒占比。另外,SSD 和 HDD 的延迟阈值差异很大:SSD 平均延迟应 < 10ms,HDD 可接受 < 50ms。不要用统一阈值。
3.4 网络带宽瓶颈识别
网络瓶颈通常表现为带宽利用率过高、丢包率上升或 TCP 重传率异常。Prometheus 的 node_network_* 指标提供了网络接口的流量和错误数据。
3.4.1 关键指标与阈值
| 指标名称 | 含义 | 典型瓶颈阈值 |
|---|---|---|
node_network_receive_bytes_total / node_network_transmit_bytes_total |
接收/发送字节数 | 带宽利用率 > 80% |
node_network_receive_drop_total / node_network_transmit_drop_total |
接收/发送丢包数 | 丢包率 > 0.1% |
node_network_receive_errors_total / node_network_transmit_errors_total |
接收/发送错误数 | 任何非零错误持续出现 |
node_netstat_Tcp_RetransSegs |
TCP 重传段数 | 重传率 > 2% |
3.4.2 典型查询与告警规则
# 网络带宽利用率(假设网卡带宽为 1Gbps)
rate(node_network_receive_bytes_total[5m]) * 8 / 1e9 * 100
# TCP 重传率
rate(node_netstat_Tcp_RetransSegs[5m]) / rate(node_netstat_Tcp_OutSegs[5m]) * 100
# 告警规则:网络丢包率过高
- alert: HighNetworkDropRate
expr: rate(node_network_receive_drop_total[5m]) / rate(node_network_receive_packets_total[5m]) * 100 > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Instance {{ $labels.instance }} network receive drop rate > 0.1%"
实用技巧: 网络带宽利用率需要结合网卡实际带宽计算。如果不知道网卡带宽,可以通过
node_network_speed_bytes 指标获取(部分 exporter 支持)。对于 TCP 重传,建议同时关注 node_netstat_Tcp_CurrEstab(当前连接数),因为大量短连接也会导致重传率虚高。
3.5 瓶颈识别综合流程图
以下 SVG 图展示了从指标采集到瓶颈定位的完整流程,涵盖四大资源的交叉验证方法。
3.6 瓶颈识别速查表
以下表格汇总了四大资源瓶颈的典型表现、核心 PromQL 和应对方向,便于日常运维快速参考。
| 资源类型 | 典型表现 | 核心 PromQL | 初步应对 |
|---|---|---|---|
| CPU | user/system 使用率 > 80%,load > 核心数 | 100 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 |
排查高 CPU 进程,考虑扩容或优化代码 |
| 内存 | 可用内存 < 10%,Swap 持续换页 | (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 |
释放缓存、增加内存、调整 vm.swappiness |
| 磁盘 IO | IO 使用率 > 80%,延迟 > 100ms | rate(node_disk_io_time_weighted_seconds_total[5m]) / rate(node_disk_io_time_seconds_total[5m]) * 1000 |
更换 SSD、调整 IO 调度器、优化读写模式 |
| 网络 | 带宽利用率 > 80%,丢包率 > 0.1% | rate(node_network_receive_bytes_total[5m]) * 8 / 1e9 * 100 |
升级带宽、优化网络拓扑、启用连接复用 |
工程实践要点:
- 时间窗口选择: 瓶颈识别建议使用 5m 或 10m 的
rate()窗口,避免短时毛刺导致误告警。 - 多维度聚合: 使用
by(instance, device)等标签聚合,区分不同磁盘或网卡。 - 基线对比: 将当前指标与历史同期(如上周同一时段)对比,更容易发现异常趋势。
- 告警分级: CPU/内存使用率 > 80% 设为 warning,> 95% 设为 critical,避免告警疲劳。