A5数据双路EPYC香港服务器配2×1.92TB NVMe Gen4,如何判断存储I/O是否成为瓶颈?
单看 iostat 里的磁盘利用率、CPU 的 iowait,或者某一次接口变慢,都不足以判断存储 I/O 已经成为瓶颈。可靠判断需要把同一时间窗口内的磁盘服务时间、I/O 队列、读写吞吐、应用响应时间、错误率、CPU、内存和网络放在一起观察,并确认它们是否存在同步变化。
以 A5数据双路 EPYC 香港服务器配备的 2×1.92TB NVMe Gen4 SSD 为例,如果业务延迟升高的同时,目标 NVMe 设备的 await、aqu-sz 和读写队列持续上升,应用发起的 I/O 数量明显增加,而 CPU 没有达到计算饱和、内存没有发生持续换页、网络也未接近带宽上限,那么存储 I/O 很可能是当前限制因素。反过来,如果磁盘吞吐很高但延迟稳定、队列很短,或者只有接口响应变慢而磁盘指标没有同步变化,就不能仅凭“磁盘很忙”得出瓶颈结论。
先区分“磁盘忙”和“存储瓶颈”
2×1.92TB NVMe Gen4代表什么
两块 1.92TB SSD 按十进制容量计算,原始容量约为 3.84TB。这里的容量描述只说明可用存储空间的基础规模,不等于业务一定能获得某个固定的 IOPS、吞吐或延迟。
两块盘可能有多种使用方式:
| 使用方式 | 可见容量与故障边界 | 对 I/O 判断的影响 |
|---|---|---|
| 两个独立文件系统 | 容量分别使用,业务可能只落在其中一块盘 | 需要按设备、挂载点和进程分别观察,不能只看总盘指标 |
| RAID1 | 原始容量约 3.84TB,格式化前可用容量通常接近 1.92TB | 读请求可能分散,写入和同步提交需要结合阵列实现分析 |
| RAID0 | 格式化前可用容量通常接近 3.84TB | 并行吞吐可能增加,但任一成员盘故障都可能影响整个阵列 |
| LVM、文件系统或其他存储层 | 设备名和业务路径之间增加映射层 | 需要同时观察底层 NVMe、阵列层、逻辑卷和文件系统路径 |
因此,判断前应先确认业务到底写入哪个路径、该路径对应哪一块 NVMe,或者对应哪个软件阵列、逻辑卷。不能看到两块盘就直接把它们的理论性能相加,也不能因为服务器采用双路 EPYC,就认为存储请求会自动均匀分布到两块 SSD。
围绕数据库、接口服务与批处理等读写密集型业务,A5数据提供香港单路及双路AMD EPYC物理服务器,搭配不同容量的内存与NVMe存储,为数据库缓存、并发计算和本地数据读写提供资源基础。其香港产品还覆盖大容量机械硬盘存储方案,可承载文件备份与历史数据归档,让在线业务数据与长期留存数据拥有不同的部署选择。
存储 I/O成为瓶颈的可执行定义
可以把“存储 I/O 瓶颈”定义为:
在业务负载基本不变的情况下,存储层处理请求的等待时间和排队程度持续上升,并且这种变化同步推高了应用或数据库的端到端延迟;当存储等待得到缓解后,业务指标也随之改善。
这个定义包含三个条件:
- 存储请求确实出现压力:队列、服务时间、I/O 延迟或设备错误出现持续变化。
- 业务结果同步受影响:接口
p95、p99、事务耗时、数据库提交延迟或请求超时上升。 - 其他资源不能更好地解释现象:CPU、内存、网络、锁等待、线程池和上游依赖没有出现更直接的异常。
缺少其中任意一个条件,都更适合称为“存在磁盘活动”或“出现 I/O 相关现象”,而不是直接认定存储已经成为瓶颈。
建立统一的观察窗口
先确认设备、路径和软件拓扑
在开始采集数据前,先确认操作系统、挂载点、设备名以及中间层。以下命令适用于常见 Linux 环境,命令只读取系统信息,不会修改数据:
date -Is
cat /etc/os-release
lsblk -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS,MODEL
findmnt -T /var/lib
df -hT
df -ih
/var/lib 只是示例路径,应替换为数据库目录、业务数据目录或日志目录。若业务目录位于 /data,就使用 findmnt -T /data。
重点核对以下关系:
- 业务进程实际打开的文件是否位于目标 NVMe 对应的挂载点;
- 两块盘是否分别对应
nvme0n1、nvme1n1,还是已经被md0、LVM 或其他设备层封装; - 数据文件、日志文件、临时文件和备份文件是否落在不同路径;
- 文件系统剩余空间和 inode 是否充足;
- 是否有容器、虚拟机或网络挂载层改变了实际 I/O 路径。
如果应用数据在一块盘,而备份、日志或临时文件集中写入另一块盘,整体设备平均值可能掩盖单一路径的压力。

选择能够覆盖完整业务周期的时间段
观察窗口不能只截取一次高峰值。建议至少包含:
- 一段相对平稳的基线;
- 业务流量上升阶段;
- 延迟或错误率出现变化的阶段;
- 负载回落阶段;
- 必要时增加一次可控复测阶段。
例如,持续采集 10~15 分钟、每秒或每 5 秒一个采样点,通常比只执行一次命令更容易判断因果关系。若业务具有明显周期,应覆盖完整的批处理、定时任务或流量高峰,而不是只看一个瞬间。
不同指标的采样周期最好接近。磁盘每秒采集一次,而应用只提供 1 分钟平均延迟时,二者很难准确对齐。数据库提交延迟、接口响应时间和 I/O 设备统计应尽量使用相同的时间戳或统一监控时间轴。
基础采集命令
若系统已安装 sysstat,可以使用以下只读命令进行基础观察:
iostat -xz 1 10
vmstat 1 10
mpstat -P ALL 1 10
pidstat -d -p ALL 1 10
free -h
sar -n DEV,TCP,ETCP 1 10
cat /proc/pressure/io
cat /proc/pressure/memory
不同发行版的 iostat、mpstat、pidstat 和 sar 通常由 sysstat 提供,使用前可通过 command -v iostat mpstat pidstat sar 检查。若命令缺失,应先根据系统发行版确认安装包名称,并在维护窗口执行,不要在生产高峰期临时变更软件包。
观察内核日志时,可以把时间范围限制在问题窗口内:
journalctl -k --since "2025-01-01 10:00:00" --until "2025-01-01 10:15:00" \
| grep -Ei 'nvme|I/O error|timeout|reset|abort|thermal'
日期仅为示例,应替换为实际观察时间。没有 systemd 或没有访问内核日志权限时,不要据此判断没有硬件问题;可以让具备权限的运维人员核对对应日志。
指标A变化后,要寻找指标B的联动
磁盘侧应该看什么
iostat -x 常见字段包括:
| 指标 | 含义 | 判断时应关注什么 |
|---|---|---|
r/s、w/s | 每秒读写请求数 | 请求数量是否随业务负载同步增加 |
rMB/s、wMB/s 或 rkB/s、wkB/s | 读写吞吐 | 注意命令输出的实际单位,不要把 MB/s 当作 Mb/s |
r_await、w_await | 读写请求平均等待时间,通常以毫秒显示 | 读写哪一侧延迟上升,是否与应用慢请求同步 |
await | 综合 I/O 请求等待时间 | 是否在高负载窗口持续升高 |
aqu-sz | 平均队列长度 | 队列是否从接近空闲持续堆积 |
%util | 设备存在未完成 I/O 的时间比例 | 只能作为忙碌程度参考,不能单独等同于瓶颈 |
avgqu-sz | 某些版本中的平均队列字段 | 与 await、吞吐和业务延迟结合观察 |
svctm | 部分旧版本可能提供的服务时间 | 新版本未必显示,不应依赖该字段单独判断 |
不同版本的 iostat 字段和吞吐单位可能略有差异,应以命令输出的表头为准。尤其要区分:
- MB/s 是字节速率;
- Mb/s 是比特速率;
- 1MB/s 按十进制口径约等于 8Mb/s;
- 若输出为 KiB/s 或 MiB/s,则是二进制单位,不能直接与十进制 GB/s 混用。
%util 达到较高水平时,只能说明设备在统计窗口内较忙。NVMe 设备可以同时处理大量请求,某些场景下 %util 较高但请求延迟仍然稳定;反过来,单线程同步写入、数据库日志提交或队列深度很浅时,设备利用率可能不高,但单个请求已经等待很久。
应用侧需要同步观察什么
存储是否影响了业务,最终要通过应用结果验证。建议同时记录:
- 请求量或事务量;
- 平均延迟、
p95、p99; - 超时数、5xx 数量和连接错误;
- 应用线程池、任务队列或协程等待数;
- 慢请求对应的操作类型;
- 读请求、写请求、同步提交和后台任务的比例。
平均延迟没有明显变化,而 p99 持续变差,往往说明只有部分请求遇到了 I/O 排队。此时只看平均值很容易漏掉存储层的尾延迟问题。
数据库侧需要补充什么
数据库对存储延迟非常敏感,但“数据库慢”不等于“SSD 慢”。应按数据库类型采集对应指标,例如:
| 数据库观察项 | 可能说明的问题 |
|---|---|
| 数据文件物理读比例 | 缓存未命中导致更多随机读,可能增加存储压力 |
| WAL、redo、binlog 或日志提交延迟 | 同步写入、文件系统或日志盘可能成为限制 |
| checkpoint、刷脏或后台写入耗时 | 写入突发、脏页积累或写带宽不足 |
| 锁等待、事务等待 | 可能是并发控制问题,不应直接归因于 SSD |
| 活跃会话数与排队数 | 数据库线程可能在等待锁、I/O、连接或外部服务 |
| 慢查询的扫描行数和临时表使用 | 查询计划或索引问题可能是 I/O 增长的根源 |
| 缓存命中率变化 | 内存压力、工作集扩大或配置变化可能诱发物理 I/O |
例如,一条缺少索引的查询在短时间内扫描大量数据,会把 NVMe 的读请求推高。此时“磁盘是当前受压资源”可能成立,但“更换更快 SSD 是根因修复方案”并不一定成立。应用查询计划仍然是根因,存储压力只是直接表现。
按六个步骤形成判断
第一步:建立基线和问题窗口
把正常时段与异常时段放在同一张时间轴上,至少记录:
- 应用请求量;
- 接口或事务延迟;
- 错误率和超时;
- CPU 总体与单核利用率;
- 内存可用量、换页和 PSI;
- 每块 NVMe 的读写 IOPS、吞吐、
await、队列; - 网络吞吐、丢包、重传和连接队列;
- 数据库提交、锁等待和活跃会话。
不要只保存一张“异常时刻截图”。截图无法说明指标是先变化还是后变化,也无法区分正常的周期性峰值与真正的退化。
第二步:找到最先变化的指标A
在时间轴上寻找变化顺序,而不是只找最高数值。
一种典型的存储压力顺序是:
- 请求量和写入量上升;
- NVMe 的
r/s或w/s增加; aqu-sz开始积累;await或读写尾延迟升高;- 数据库提交或应用接口
p99上升; - 超时和错误率增加。
如果应用 p99 先升高,而 NVMe 的队列和延迟几秒或几十秒后才变化,可能是应用线程阻塞、数据库锁等待或上游依赖先出问题,后续又触发了日志、重试或缓存写入。此时磁盘异常可能是结果,而不是起点。
第三步:确认指标B是否联动
指标A出现变化后,要寻找同一时间段的第二组证据。
例如,磁盘 await 从约 0.8ms 上升到 8ms,只有当以下指标也发生对应变化时,存储瓶颈判断才更有依据:
- I/O 队列从接近 0 增长到持续排队;
- 应用线程的 I/O 等待时间增加;
- 数据库日志提交或物理读耗时上升;
- 接口
p95、p99在相同窗口内变差; - CPU 仍有可用算力,且没有明显单核饱和;
- 内存没有持续 swap in、swap out;
- 网络未达到带宽或连接队列上限。
如果只有 await 上升,但应用延迟、数据库提交延迟和错误率都不变,可能只是后台备份、扫描或预取任务产生了额外 I/O,当前并未构成业务瓶颈。
第四步:排除替代解释
CPU瓶颈
双路 EPYC 提供了较多计算资源,但总 CPU 利用率低并不代表没有 CPU 瓶颈。单线程程序、单个数据库执行线程或锁竞争,都可能让一个核心接近满载,而整体利用率仍然不高。
建议结合以下现象判断:
- 单个或少数 CPU 核心长期接近满载;
run queue持续高于可运行核心数;- 应用线程主要处于运行或锁等待,而不是 I/O 等待;
- 磁盘
await和队列没有同步上升; - 提升并发后吞吐不再增加,但磁盘仍有明显余量。
iowait 也不能直接作为磁盘瓶颈证据。它表示 CPU 处于等待 I/O 的时间比例,但可能受到异步 I/O、并发任务、内核统计方式和其他设备等待影响。应将它与设备队列和应用延迟对应起来。
内存瓶颈
内存不足会通过回收、换页和文件缓存失效间接增加磁盘读写。此时磁盘确实可能变忙,但直接原因未必是 NVMe 本身处理能力不足。
重点观察:
free -h中available是否持续下降;vmstat的si、so是否持续出现;/proc/pressure/memory中some或full是否在异常窗口上升;- major page fault 是否增加;
- 文件缓存是否被频繁回收;
- 数据库缓冲区命中率是否下降。
如果内存回收先发生,随后磁盘读请求增加,且业务延迟同步上升,优先处理工作集、缓存和内存配置,而不是直接把问题归类为 SSD 性能不足。
网络瓶颈
香港服务器上的业务请求可能来自不同网络位置。若请求方、应用层、数据库或对象存储不在同一网络位置,往返延迟和重传可能让接口变慢,即使本地 NVMe 仍然空闲。
检查:
- 网卡接收和发送速率是否接近端口能力;
- TCP 重传、丢包、连接建立时间是否增加;
- socket 接收或发送队列是否积压;
- 数据库连接池是否耗尽;
- 应用是否在等待远程 API、缓存或数据库;
- 网络异常时间是否与磁盘队列时间一致。
如果远程数据库响应时间上升,但本地磁盘 await、队列和吞吐没有变化,优先调查网络路径和远端服务。不能因为业务运行在香港服务器上,就把所有延迟变化归因于本地存储。
应用瓶颈
应用自身的队列、锁、线程池或重试机制,也会制造类似 I/O 瓶颈的表象。
常见表现包括:
- 工作线程已被锁或连接池占满;
- 某个请求重复读取同一数据;
- 失败重试导致读写量成倍增加;
- 日志级别临时提高,产生大量同步写入;
- 批处理将大量小写入集中在同一时刻;
- 序列化、压缩或加密占用 CPU,业务响应变慢但磁盘正常。
应用日志中的“等待数据库”并不自动等于“等待磁盘”。还需要查看数据库内部是在等待物理 I/O、锁、日志提交,还是在等待连接和执行计划。
数据库瓶颈
数据库锁等待、索引缺失、检查点集中执行和日志刷盘,都可能同时伴随磁盘活动。
可以按以下顺序区分:
- 慢查询是否在异常时段明显增加;
- 慢查询扫描量是否变化;
- 数据库会话是在等待 I/O、锁还是连接;
- 日志提交延迟是否和底层写延迟同步;
- 检查点或刷脏操作是否造成写入突发;
- 优化查询或减少并发后,磁盘队列是否随之下降。
若减少一个错误查询后,磁盘 I/O 和接口延迟都恢复,说明 I/O 压力可能是查询问题引起的。此时需要修复查询、索引或访问模式,而不是只扩大存储规格。
第五步:形成带条件的判断
可以使用下面的判断矩阵:
| 观察结果 | 更可能的解释 | 下一步 |
|---|---|---|
await、队列和应用 p99同时上升,CPU和内存正常 | 存储 I/O 可能成为直接瓶颈 | 区分读写、同步与异步 I/O,继续按业务路径复测 |
%util高,但await稳定、队列短、业务延迟稳定 | 设备较忙,但未必限制业务 | 观察是否为正常吞吐型任务,不要仅凭利用率扩容 |
iowait高,但NVMe队列不高 | 可能存在其他设备、网络文件系统或统计误差 | 检查实际 I/O路径和进程级等待 |
| 内存可用量下降,swap和物理读增加 | 内存压力诱发磁盘活动 | 先排查工作集、缓存和内存配置 |
| 单核满载、磁盘空闲、请求延迟上升 | CPU、锁或单线程执行受限 | 查看热点线程、锁和应用并发模型 |
| 网络重传、RTT或连接队列上升,磁盘指标稳定 | 网络或远端依赖瓶颈 | 检查请求路径和远程服务 |
| 数据库日志提交延迟上升,写队列同步积累 | 同步写入或日志路径可能受限 | 区分日志盘、数据盘和文件系统提交行为 |
| 只有单个进程I/O很高,其他业务正常 | 进程或任务局部受限 | 定位进程、文件路径和访问模式 |
这里的“可能”是必要边界。监控指标通常只能先定位受压层,还需要通过降载、改变访问模式或受控复测确认因果关系。
第六步:复测并验证因果
一次有效复测应尽量只改变一个关键变量。例如:
- 暂停非必要的备份、扫描或批处理任务;
- 降低某类查询并发,观察队列和应用延迟是否一起下降;
- 将日志写入路径与数据路径分开,观察同步提交耗时;
- 在非生产文件或隔离环境中测试不同块大小和队列深度;
- 将应用从单线程 I/O 改为合理的批量或并发访问后重新观察。
如果存储压力下降后,应用 p99、数据库提交延迟和超时率也在同一时间恢复,因果关系更可信。若磁盘指标改善但业务延迟没有变化,存储可能只是伴随现象;若业务延迟恢复但磁盘仍然繁忙,则可能存在缓存、请求量或服务端排队等其他因素。
用模拟数据理解一条完整证据链
下面是一组用于解释判断方法的模拟监控数据,不代表 A5数据服务器的实际监控结果。假设业务在 10:05 开始批量写入,采集粒度为 1 分钟:
| 时间 | 请求量 | 写IOPS | 写await | aqu-sz | CPU利用率 | 内存换页 | 接口p99 | 错误率 |
|---|---|---|---|---|---|---|---|---|
| 10:03 | 7,800/s | 18,000 | 0.9ms | 0.2 | 42% | 0 | 85ms | 0.08% |
| 10:04 | 8,100/s | 22,000 | 1.1ms | 0.4 | 46% | 0 | 92ms | 0.09% |
| 10:05 | 8,400/s | 61,000 | 3.8ms | 6.7 | 49% | 0 | 160ms | 0.21% |
| 10:06 | 8,500/s | 76,000 | 8.6ms | 18.4 | 51% | 0 | 310ms | 0.74% |
| 10:07 | 8,300/s | 78,000 | 10.2ms | 24.1 | 50% | 0 | 420ms | 1.10% |
| 10:08 | 6,200/s | 39,000 | 2.4ms | 2.1 | 48% | 0 | 145ms | 0.16% |
这组数据具有较完整的联动关系:
- 业务请求量只小幅增加,但写 IOPS 明显增加;
- 写
await和队列连续上升; - CPU 利用率仍在中等水平;
- 没有换页迹象;
- 接口
p99和错误率与写队列同步变差; - 负载回落后,磁盘等待和接口延迟一起下降。
在这个模拟场景中,存储写入路径成为直接限制因素的可能性较高。但仍要继续确认写入是数据库日志、数据文件、应用日志,还是批处理临时文件;还要检查是否存在单个异常任务放大 I/O 的问题。
再看另一种场景:
| 时间 | 请求量 | 磁盘await | 磁盘队列 | TCP重传 | CPU利用率 | 接口p99 |
|---|---|---|---|---|---|---|
| 11:00 | 6,000/s | 0.8ms | 0.3 | 0.02% | 45% | 90ms |
| 11:01 | 6,100/s | 0.9ms | 0.4 | 0.04% | 46% | 95ms |
| 11:02 | 6,000/s | 0.9ms | 0.4 | 0.60% | 46% | 210ms |
| 11:03 | 5,900/s | 1.0ms | 0.5 | 1.20% | 47% | 390ms |
这里接口延迟上升,但磁盘队列和 await 基本稳定,网络重传明显增加。这个时间关系不支持“NVMe 是首要瓶颈”的判断,应优先检查网络链路、远程数据库或上游依赖。

结合NVMe工作负载判断性能形态
顺序吞吐高不代表数据库一定快
Gen4 NVMe 的接口带宽更适合大块顺序读写和高并发数据流,但数据库在线事务通常混合了:
- 小块随机读;
- 小块随机写;
- 日志同步写;
- 文件系统元数据操作;
- 检查点和后台刷盘;
- 多个线程的混合队列。
如果业务主要是大文件顺序读取,关注吞吐和队列深度更有意义;如果是在线事务,单次 I/O 延迟、同步提交耗时和尾延迟通常更重要。一个测试工具给出的顺序读吞吐,不能直接替代真实数据库负载下的判断。
IOPS和吞吐要同时换算
吞吐量可以用以下方式核对:
吞吐量 = IOPS × 每次 I/O 的块大小
例如,若某时间窗口有 80,000 次每秒的写请求,每次写入 8KiB:
- 80,000 × 8KiB = 640,000KiB/s;
- 640,000 ÷ 1,024 ≈ 625MiB/s。
如果使用十进制单位,将每次写入按 8,000 字节计算:
- 80,000 × 8,000 = 640,000,000字节/s;
- 640,000,000 ÷ 1,000,000 = 640MB/s。
两种结果只是单位口径不同,不能把 625MiB/s 和 640MB/s 当作相互矛盾的数据。实际判断还要加入读写混合比例、队列深度、同步提交和压缩等因素。
小块同步写是常见的敏感点
数据库日志、事务提交和某些文件写入会等待数据真正完成。此类请求即便 IOPS 数量不高,也可能因为每次提交都等待完成而影响事务延迟。
需要特别观察:
w_await是否高于r_await;- 日志提交延迟是否与写队列同步;
- 是否存在大量
fsync或等价同步操作; - 应用是否逐条提交,而不是合理批量提交;
- 文件系统和数据库是否共用同一写入路径;
- 写入是否集中发生在某一块盘或某个阵列层。
如果把大量小写入合并成批量写后,IOPS 下降、队列减少、事务延迟改善,原问题可能是访问模式和同步策略放大了存储压力,而不仅是设备规格问题。
双路EPYC环境下不要只看总CPU
双路 EPYC 服务器通常可以同时运行更多并发任务,但多核数量也会掩盖局部资源瓶颈。建议把以下数据分开看:
- 总 CPU 利用率;
- 每个逻辑核心的利用率;
- 用户态、内核态和
iowait; - 调度运行队列;
- 应用进程线程数;
- 数据库活跃会话和等待事件;
- NUMA 节点之间的内存访问情况。
如果一个应用只有少量工作线程,即使服务器总 CPU 利用率只有 20%~30%,单个核心或单个执行线程也可能已经达到上限。此时增加磁盘并不能改善 CPU 串行执行问题。
同样,如果多个业务共享两块 NVMe,而某个备份任务持续占用写队列,数据库可能表现为日志提交变慢。此时需要按进程和文件路径定位,而不能只看两块盘的总吞吐。
有限风险的受控复测
生产环境先用无侵入采集
前述 iostat、vmstat、pidstat、sar 和 /proc/pressure 读取的是系统统计信息,通常不会修改业务数据。采集时仍应注意:
- 不要在高峰期频繁执行高开销进程级扫描;
- 统一服务器时区或使用带时区的时间戳;
- 记录采集命令、采样间隔和业务事件;
- 对监控数据设置合理保留周期;
- 保护进程名、路径和业务日志中的敏感信息。
文件级读测试只能验证一部分能力
在非高峰期、隔离文件系统或专用测试目录中,可以使用已有的非关键测试文件进行只读测试。以下命令只是示例,/data/bench/seed.bin 必须是已经存在、属于测试路径且允许读取的文件:
fio --name=randread \
--filename=/data/bench/seed.bin \
--readonly \
--rw=randread \
--bs=4k \
--iodepth=32 \
--numjobs=4 \
--direct=1 \
--runtime=60 \
--time_based \
--group_reporting
该测试只能说明特定文件系统、块大小、并发度和随机读模式下的结果,不能代表数据库写入、同步提交或真实混合负载。测试过程中应同步采集 iostat、应用延迟和错误率,否则只得到一个孤立的性能数字。
不要直接把测试目标指向生产数据库原始设备、数据库数据文件或未确认的块设备。写入类测试可能覆盖数据、制造大量脏页并消耗 SSD 写入寿命;如果确需写测试,应先完成数据备份、确认影响范围、安排维护窗口,并准备恢复方案。没有明确的恢复路径时,不应在生产盘上执行写入测试。
健康状态和温度也要纳入复测
NVMe 在高负载、长时间写入或散热条件变化时,可能出现温度升高、降速或控制器重置。若系统安装了 nvme-cli,可以先确认设备名,再读取健康信息:
command -v nvme
lsblk -d -o NAME,SIZE,MODEL
sudo nvme list
sudo nvme smart-log /dev/nvme0
sudo nvme smart-log /dev/nvme1
设备名必须以实际 nvme list 输出为准,不要盲目替换或操作未知设备。重点关注温度、警告项、介质错误、错误日志和累计写入量,并与问题时间对齐。读取 SMART 信息通常不会改写数据,但仍应遵循服务器权限和运维审计要求。
若日志出现 NVMe timeout、reset 或 I/O error,应先保留现场信息并确认备份状态,再由具备权限的人员制定故障处理和回滚方案。不要为了“恢复速度”直接重置控制器、卸载生产文件系统或删除日志。
识别真正需要优化的层级
存储 I/O成为瓶颈后,还要继续区分“设备能力不足”和“业务访问方式不合理”。
更接近设备层的问题
以下组合更接近设备或存储层受限:
- 多个独立业务同时访问同一设备时,延迟一起上升;
- 读写请求已经合理分散,但队列仍持续堆积;
- 内存、CPU、网络和数据库锁均无明显异常;
- 在相同访问模式下,受控复测能够重复出现高延迟;
- SSD 健康、温度和内核错误需要进一步排查。
更接近业务访问层的问题
以下现象更像应用或数据库访问模式问题:
- 只有一个异常查询制造大量随机读;
- 逐条同步提交导致提交次数过多;
- 日志级别变化产生大量小文件和同步写入;
- 批处理与在线事务在同一时间争用存储;
- 增加缓存或修复索引后,磁盘队列随之恢复;
- 只有某个进程或某个路径延迟异常。
两类问题可以同时存在。业务访问方式不合理会先把设备推到高负载,而设备延迟上升又会放大应用超时。判断时应分别记录“直接受压资源”和“产生压力的根因”,避免把更换硬件作为所有 I/O 问题的唯一方案。
下一次应同时观察的指标组合
针对 A5数据双路 EPYC 香港服务器的 2×1.92TB NVMe Gen4 存储路径,下一次出现接口变慢、数据库提交变慢或批处理耗时增加时,建议在同一时间轴上至少保留以下组合:
| 观察层 | 建议同时记录的指标 |
|---|---|
| 业务结果 | 请求量、平均延迟、p95、p99、超时、错误率 |
| 进程与应用 | 进程级读写量、线程池、任务队列、重试次数 |
| CPU | 总利用率、每核利用率、运行队列、用户态、内核态、iowait |
| 内存 | available、swap in/out、major fault、内存 PSI、数据库缓存命中率 |
| 存储设备 | 每块盘的读写 IOPS、吞吐、r_await、w_await、aqu-sz、%util |
| 存储路径 | 挂载点、文件系统、LVM或阵列层、数据盘与日志盘对应关系 |
| 数据库 | 物理读、日志提交、检查点、锁等待、活跃会话、慢查询 |
| 网络 | 入出带宽、RTT、TCP重传、连接队列、远程依赖耗时 |
| 系统健康 | NVMe温度、错误日志、timeout、reset、文件系统剩余空间 |
最终判断不应写成“磁盘利用率超过某个数值,所以一定是瓶颈”,而应形成完整链路:业务延迟何时变化、哪个 I/O 指标先变化、队列是否持续积累、CPU和内存是否排除、网络与数据库等待是否匹配、复测后业务是否同步恢复。只有这些指标在同一时间语境中相互印证,才能判断 2×1.92TB NVMe Gen4 是否真正限制了当前业务。



