香港云服务器NVMe磁盘I/O异常时,如何结合CPU、内存与进程状态排查高负载?

现场:NVMe磁盘先忙,还是整台云服务器先失去响应?
常见的运维现场是:香港云服务器上的网站接口开始变慢,监控显示系统负载升高,应用日志出现请求排队,磁盘监控中某个 NVMe 设备的 I/O 活跃度也明显上升。此时直接重启服务器,可能暂时恢复响应,却会丢失进程状态、队列和内核日志,后续很难判断真正原因。
更稳妥的顺序是:先记录故障时间和整体负载,再分别检查 CPU、内存、磁盘队列、进程状态与连接数,最后把资源指标和具体业务进程对应起来。只有当多个指标相互印证时,才能判断是 CPU 计算过载、内存不足导致换页、进程大量阻塞,还是并发请求和应用写入共同造成了 NVMe I/O 异常。
先理解“高负载”与NVMe I/O异常的关系
很多人会问:香港云服务器 NVMe 硬盘优势是什么?
NVMe 存储通常面向低延迟和高并发随机 I/O 场景,能够通过更适合现代存储设备的队列机制处理更多并行请求。但这并不意味着使用 NVMe 后就不会出现 I/O 等待。应用集中写日志、数据库批量操作、内存不足触发交换、文件系统空间或 inode 耗尽,都可能让磁盘队列快速堆积。
Linux 的 load average 也不只统计正在使用 CPU 的进程。处于可运行状态,或处于不可中断 I/O 等待状态的进程,也可能计入负载。因此:
load average高,不等于 CPU 使用率一定高;- NVMe 设备
%util高,不等于硬盘已经损坏; - CPU
iowait高,需要结合块设备的await、队列长度和进程状态判断; - 内存不足导致的 swap 读写,可能表现为磁盘 I/O 异常;
- 连接数突然增加,可能通过应用线程、日志和缓存读写间接推高磁盘负载。
第一步:保留现场,确认故障范围
排查应先从低风险、只读操作开始。执行命令前,记录当前时间、业务表现和是否刚发生过发布、批处理、备份或流量变化。下面的命令适用于常见 Linux 系统,通常不修改服务器配置。
date -Is
uptime
cat /proc/loadavg
free -h
df -hT
df -ih
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINT,ROTA
ss -s
重点观察以下信息:
uptime中的 1 分钟、5 分钟和 15 分钟负载是否持续上升;free -h中的available是否明显偏低;df -hT是否存在接近满容量的挂载点;df -ih是否 inode 已用尽,即使磁盘容量看起来还有剩余;lsblk中实际承载业务数据的设备名称和挂载点;ss -s中连接总量、TCP 状态是否明显异常。
如果负载只在短时间内升高后迅速恢复,可能是一次批量任务或流量尖峰;如果 5 分钟和 15 分钟负载都在上升,则更需要关注持续排队、进程泄漏或资源未释放。
接着获取短时采样。vmstat 通常随 Linux 系统提供,iostat 一般由 sysstat 工具包提供。
vmstat 1 5
command -v iostat || echo "iostat not installed; install the matching sysstat package for this distribution"
iostat -xz 1 5
这组命令本身不会改变业务状态,但会产生少量监控开销。若服务器已经处于严重卡顿状态,不要无限制地提高采样频率或同时运行大量磁盘扫描命令。
第二步:先排除CPU和内存方向
看CPU是否真的在计算
可以用进程列表快速定位消耗 CPU 的进程:
ps -eo pid,ppid,stat,pcpu,pmem,comm,args --sort=-pcpu | head -n 20
配合 vmstat 的结果判断:
us较高,通常表示用户态程序消耗 CPU,例如业务计算、脚本或应用线程繁忙;sy较高,说明内核态开销增加,可能与大量系统调用、网络处理或 I/O 请求有关;wa较高,说明 CPU 正在等待 I/O 完成,但还不能单独证明 NVMe 设备存在故障;r持续较高,表示等待运行的任务较多,需要继续查看 CPU 核数和进程状态;b持续较高,表示有较多任务处于阻塞状态,I/O 等待的可能性增加;st较高时,可能是虚拟化环境中的 CPU 调度等待,应结合实例监控和服务商侧信息判断。
如果 CPU 使用率接近满载,wa 较低,且某个进程的 pcpu 持续靠前,排查重点应放在该进程的请求量、线程数、循环计算和近期变更,而不是优先更换磁盘。
看内存是否通过swap放大了磁盘I/O
先查看内存和交换区:
free -h
swapon --show
随后观察 vmstat 中的 si 和 so:
si表示从交换区读入内存的速率;so表示从内存写入交换区的速率;- 两者持续出现,且
available很低,说明内存压力可能正在把磁盘 I/O 放大; - 如果
si、so基本为零,但磁盘写入很高,则不应把问题直接归因于 swap。
Linux 版本支持时,还可以查看内存压力信息:
if [ -r /proc/pressure/memory ]; then
cat /proc/pressure/memory
fi
内存不足时,不建议首先执行“清缓存”类操作。缓存本身是 Linux 用于提高文件访问效率的一部分,强行清理可能造成新的磁盘读压力。更合理的处理方式是先找到占用内存的进程,再根据业务情况降低并发、调整缓存规模或处理异常任务。
第三步:确认NVMe I/O是“忙”还是“排队”
重点看await、队列和读写方向
iostat -xz 1 5 的输出中,应重点关注实际承载业务的 NVMe 设备,而不是只看所有设备的汇总值:
r/s、w/s:每秒读写请求数量;rkB/s、wkB/s:每秒读写数据量;await:I/O 请求从提交到完成的平均等待时间;aqu-sz:平均队列长度;%util:设备处于处理 I/O 状态的时间占比;r_await、w_await:读请求和写请求的等待情况。
判断时要看组合关系,而不是单一字段。
| 现象组合 | 更可能的含义 | 下一步 |
|---|---|---|
wa 高、b 高、await 和队列长度同时升高 | 大量任务等待块设备完成 | 继续用 pidstat 定位产生 I/O 的进程 |
%util 高,但等待时间和队列并不高 | 设备正在持续处理请求,未必是异常 | 对比业务延迟和历史基线 |
写入量高、w_await 升高 | 日志、数据库或批处理写入集中 | 区分具体写入进程和业务任务 |
读写量不大,但 await 明显升高 | 请求可能被设备、文件系统或上层任务拖住 | 检查内核日志、进程 D 状态和设备健康信息 |
si、so 持续出现,同时读写增多 | 内存压力通过 swap 放大 I/O | 优先处理内存和进程占用 |
| 磁盘接近满或 inode 用尽 | 新文件、日志和临时文件操作可能受阻 | 先确认业务影响,再按保留策略清理 |
%util 达到较高水平,只能说明设备较忙,不能单独作为“NVMe 硬盘损坏”的证据。尤其在并行 I/O 场景下,应同时看等待时间、队列长度、业务延迟和进程阻塞状态。
检查空间、文件系统和内核日志
磁盘容量和 inode 都需要检查:
df -hT
df -ih
findmnt
如果某个挂载点容量满了,应用可能在写日志、创建临时文件或提交数据时失败;如果 inode 用尽,即使 df -h 显示尚有空间,也可能无法创建新文件。
再查看近期内核日志。以下命令只读取日志,不会修改设备:
sudo dmesg -T | grep -Ei 'nvme|I/O error|buffer I/O|ext4|xfs|filesystem'
使用 systemd 的系统还可以执行:
sudo journalctl -k --since "30 min ago" --no-pager | grep -Ei 'nvme|I/O error|timeout|reset|ext4|xfs|filesystem'
如果出现 I/O error、超时、设备重置、文件系统错误或挂载状态变化,应先保存故障时间、设备名称和完整日志,不要直接执行格式化、文件系统修复、设备重置或重启。此类操作可能扩大影响或清除关键现场,应该在备份、维护窗口和明确的回滚条件下进行。
部分云服务器不会向虚拟机完整暴露底层存储健康信息。如果系统安装了 NVMe 工具,可以先确认工具和设备是否可见:
command -v nvme
sudo nvme list
只有在 nvme list 明确列出设备后,才根据实际设备名称查询健康信息,例如:
sudo nvme smart-log /dev/nvmeX
这里的 nvmeX 只是占位符,不能未经确认直接替换或猜测设备名。如果工具不可用,或虚拟化环境没有暴露相关信息,并不能据此判定硬盘损坏;持续出现设备级错误时,应将日志和采样结果提交给云服务器服务商进一步核验。
第四步:从进程状态和进程级I/O找根因
系统级指标只能说明“哪里拥堵”,还需要找到“谁在制造拥堵”。
先查看进程状态:
ps -eo pid,ppid,stat,wchan:32,pcpu,pmem,comm,args --sort=-pcpu | head -n 30
常见状态含义如下:
R:正在运行或等待 CPU;S:可中断睡眠,很多正常等待中的服务也处于此状态;D:不可中断睡眠,常见于等待 I/O,不能简单理解为普通空闲;Z:僵尸进程,进程已经退出但父进程尚未回收;T:被暂停或被调试。
如果大量进程处于 D 状态,同时 vmstat 的 b、iostat 的 await 和队列长度都较高,说明进程确实在等待 I/O。此时不建议使用强制终止方式处理这些进程,因为它们可能尚未完成文件写入或数据提交,强行操作会增加业务风险。
使用 pidstat 查看进程级资源变化:
pidstat -dru -p ALL 1 5
重点关注:
-d:进程读写速率及 I/O 延迟相关信息;-r:缺页、内存等信息;-u:用户态和系统态 CPU 使用情况;- 同一个 PID 是否同时出现高 CPU、高内存和高 I/O。
如果已经从进程列表中找到可疑 PID,可以进一步读取其累计 I/O 计数:
pid=1234
sudo sh -c "cat /proc/$pid/io; printf '\n--- status ---\n'; cat /proc/$pid/status | grep -E 'Name|State|VmRSS|Threads'"
/proc/ 中的计数是累计值,不能只看一次就下结论。应在不同时间点采集两次,比较读写计数的增长速度。进程级读写很高,通常应继续结合应用日志、任务调度和请求量判断;如果进程没有明显读写,却有大量线程处于 D 状态,则更需要检查底层设备或文件系统。
第五步:把连接数和进程负载对应起来
连接数异常不一定直接造成磁盘 I/O,但连接突然增加可能带来更多工作线程、请求日志、临时文件和缓存读写。
先查看总体连接状态:
ss -s
ss -tan state established | awk 'NR>1{n++} END{print n+0}'
ss -tan state time-wait | awk 'NR>1{n++} END{print n+0}'
sudo ss -lntp
如果需要观察趋势,可以进行短时、低频采样:
for i in 1 2 3 4 5; do
date -Is
ss -s
sleep 5
done
判断连接数时要看变化趋势:
ESTABLISHED持续增加,同时应用进程数和 CPU 占用上升,可能是请求并发增加;TIME-WAIT短时间大量出现,可能是短连接建立和关闭频繁,需要结合应用连接复用策略分析;- 连接数不高,但大量进程处于
D状态,问题更可能在 I/O 路径; - 连接数高且日志写入量同步上升,可能是请求量通过日志系统放大了磁盘写入;
- 监听端口对应的进程数量、线程数异常时,应查看该服务的并发配置和近期变更。
不能仅凭连接总数就判断服务器遭遇异常流量,也不能在没有确认业务影响和规则备份的情况下直接修改防护或连接配置。
按优先级处理异常
1. 先降低新增压力
如果确认是可暂停的批处理、备份、报表生成或大规模日志任务造成 I/O 排队,应在业务负责人确认后暂停或错峰执行。记录原任务、执行时间和恢复条件,避免只停任务却忘记后续恢复。
如果是应用并发突然升高,应优先处理请求来源、线程数、连接池和日志级别等业务参数,而不是立即更换存储。参数调整前保存当前配置,确认新配置的适用版本,并准备恢复原值的步骤。
2. 处理内存压力和异常进程
如果 free -h 显示可用内存不足,且 vmstat 持续出现 swap 读写,应先降低应用并发或结束经过确认的异常任务。不要把“清理缓存”当成通用修复方法。
如果某个进程持续占满 CPU 或不断产生 I/O,应先保存 PID、命令行、日志位置和进程状态。对于由 systemd 管理的服务,重启前应确认服务依赖、配置状态和业务影响:
sudo systemctl status
sudo journalctl -u --since "15 min ago" --no-pager
只有在维护窗口或已获授权的情况下,才考虑重启服务:
sudo systemctl restart
sudo systemctl status --no-pager
重启会中断该服务的现有请求,可能导致连接重建。操作前应确保必要数据已落盘,并保存配置备份;如果重启失败,先查看服务状态和日志,确认配置无误后再使用 systemctl start 尝试恢复。处于 D 状态的进程不要直接使用强制终止方式处理。
3. 处理空间和日志问题
如果文件系统已接近满容量,应根据业务保留策略处理日志和临时文件。不要直接删除正在写入的日志文件,也不要使用不清楚影响范围的批量删除命令。清理前确认:
- 哪个挂载点接近满;
- 哪个目录或文件增长最快;
- 日志是否已有备份或集中留存;
- 删除后应用是否仍能正常写入;
- 是否需要先执行受控的日志轮转。
空间问题解决后,还要重新检查 inode、应用写入错误和服务日志,避免只释放了容量,却留下文件句柄或应用状态异常。
4. 遇到设备级错误时停止盲目操作
如果内核日志反复出现 NVMe 超时、I/O error、设备重置或文件系统错误,优先保存证据并联系服务商或平台技术支持。提交的信息至少包括:
- 故障开始和结束时间;
uptime、vmstat、iostat采样;- 设备名称、挂载点和文件系统类型;
- 相关进程 PID 与状态;
- 内核日志中的错误原文;
- 故障期间的业务表现。
不要在没有备份和回滚方案的情况下执行格式化、文件系统修复、设备重置或直接重启。重启有时能让暂时阻塞的服务恢复,但也会清除进程现场,不能作为第一排查步骤。
修复后如何验证已经恢复
处理完成后,至少重新采集一轮与故障前相同的指标:
uptime
free -h
df -hT
df -ih
vmstat 1 5
iostat -xz 1 5
pidstat -dru -p ALL 1 5
ss -s
验证不能只看某一个数字,而应进行前后对比:
load average是否停止上升,并逐步回落;vmstat中的b是否减少,wa是否回到业务正常水平;iostat中的await、队列长度和读写速率是否与当前业务量匹配;- 是否仍有大量进程处于
D状态; si、so是否停止持续增长;- 连接数是否回到与业务请求量相符的范围;
- 应用错误日志、请求延迟和成功率是否恢复;
- 文件系统容量和 inode 是否仍有余量。
如果只是重启服务后指标短暂恢复,但连接数、swap 或 I/O 队列再次上升,说明根因尚未消失。此时应回到进程级 I/O、应用日志和任务调度继续关联,而不是重复重启。
复盘时最容易漏掉的检查项
高负载事件结束后,最容易遗漏的是“触发条件”和“放大因素”。复盘时应确认:
- 是否有定时任务、批量导入、备份或日志突增;
- 是否出现过内存不足和 swap,导致原本正常的 I/O 被放大;
- 是否只查看了磁盘容量,没有查看 inode;
- 是否只看了
%util,没有结合await、队列和业务延迟; - 是否只看了 CPU 最高进程,没有检查处于
D状态的进程; - 是否只统计了连接总数,没有观察连接状态和应用线程变化;
- 是否保存了故障时间段的内核日志和进程采样;
- 云服务器内部看到的设备状态是否足以解释问题,是否需要平台侧进一步核验。
因此,香港云服务器使用 NVMe 硬盘的价值,应理解为更适合低延迟、并行 I/O 场景,而不是对任何高负载都提供自动兜底。真正有效的排查,必须把 CPU、内存、磁盘队列、连接数和进程状态放在同一条时间线上判断,才能区分“磁盘确实在排队”和“内存、并发或异常进程把磁盘拖忙”这两类不同问题。