上一篇 下一篇 分享链接 返回 返回顶部

数据库读写IOPS突破30万是真的吗?香港NVMe RAID服务器如何核验性能数据?

发布人:Minchunlin 发布时间:2026-10-04 21:59 阅读量:4

“数据库读写 IOPS 突破 30 万”并非一定是假的,但它只有在明确测试条件时才有意义。4KB 随机读、较高队列深度、多个并发任务下,香港 NVMe RAID 服务器的存储层可能达到 30 万级 IOPS;这并不等于实际数据库在开启事务持久化、日志同步和混合读写后,也能稳定完成 30 万次有效数据库操作。

核验时不要只看宣传截图或一个峰值数字,应至少同时确认四件事:测试的块大小与读写比例、队列深度与并发方式、延迟分布尤其是 p99、以及数据库真实负载下的 TPS 和提交延迟。只有存储层结果、数据库层结果和持续运行表现能够相互对应,30 万 IOPS 才能作为有参考价值的性能结论。

先把“30万 IOPS”换算成可理解的指标

IOPS 是每秒完成的 I/O 操作次数,不是固定的带宽单位。相同的 IOPS,在不同块大小下代表完全不同的数据量。

计算方式是:

每秒数据量 = IOPS × 单次 I/O 数据量

例如:

先把“30万 IOPS”换算成可理解的指标配图

  • 300,000 IOPS × 4KB,约等于 1.2GB/s,换算为约 9.6Gbps;
  • 300,000 IOPS × 16KB,约等于 4.8GB/s,换算为约 38.4Gbps;
  • 300,000 IOPS × 1MB,则相当于 300GB/s,这已经不是通常意义上的 4KB 随机数据库测试场景。

这里按十进制换算:1GB=1000MB,1MB=1000KB,1Byte=8bit。由此可见,只写“30 万 IOPS”而不写块大小,几乎无法判断结果是否与数据库场景相关。

还要区分以下三类结果:

结果类型能说明什么不能说明什么
存储层随机读 IOPSRAID 卷在指定块大小、队列和并发下的处理能力不能代表写入能力和事务提交速度
存储层混合读写 IOPS指定读写比例下的物理 I/O 能力不能直接等同于数据库 TPS
数据库压测 TPS、提交延迟数据库引擎在具体参数下的实际业务处理能力不能脱离数据库版本、数据量和事务模型比较

因此,“读写 IOPS 突破 30 万”至少要继续追问:是随机读,还是混合读写?读写比例是多少?块大小是 4KB 还是 16KB?队列深度是多少?结果是峰值还是持续值?测试时是否启用了写回缓存?数据库是否开启了真正的日志落盘确认?

香港 NVMe RAID 服务器需要先核对什么

香港只是服务器所在地区,不能替代具体硬件和阵列配置。相同机房、相同带宽条件下,不同批次的 NVMe 盘数量、型号、RAID 级别、控制器缓存策略和文件系统,都可能使结果出现明显差异。

确认测试对象确实是 RAID 卷

测试前应在服务器本机执行信息采集,而不是仅在远程客户端通过网络发起一个应用请求。Linux 环境可以先查看块设备、NVMe 盘和阵列状态:

测试前应在服务器本机执行信息采集,而不是仅在远程客户端通过网络发起一个应用请求示意图

lsblk -o NAME,MODEL,SIZE,ROTA,TYPE,FSTYPE,MOUNTPOINTS
sudo nvme list
cat /proc/mdstat
df -hT /data

如果使用 Linux 软件 RAID,还应查看阵列详细信息:

sudo mdadm --detail /dev/md0

/dev/md0 只是示例路径,实际设备名应以 cat /proc/mdstat 和 lsblk 的结果为准。若使用硬件 RAID 或专用阵列控制器,操作系统可能只看到一个逻辑卷,此时还需要从服务商控制面板或控制器管理工具确认:

  • RAID 级别是 RAID0、RAID10 还是其他模式;
  • 阵列包含几块 NVMe 盘;
  • 是否存在写回缓存;
  • 写回缓存是否有电容、缓存保护或其他掉电保护;
  • 文件系统和数据库数据目录是否确实位于该阵列卷;
  • 数据目录、日志目录是否被拆分到不同设备。

不能把“服务器配有多块 NVMe”直接理解为“数据库正在使用 NVMe RAID”。如果 fio 测试文件写到了另一块单盘、临时盘或系统盘,结果就与目标阵列无关。

确认 RAID 级别和缓存策略

RAID0 可能在并行随机读写中取得较高峰值,但不提供盘级冗余;RAID10 通常更适合需要同时读写和恢复能力的数据库场景;带校验计算的阵列在小块随机写入中可能受到额外开销影响。这里不能只比较“盘的数量”,还要看数据写入路径和持久化策略。

尤其要警惕控制器或 SSD 的写回缓存。若设备先把数据放入易失缓存,再向测试程序返回完成,短时间内的写 IOPS 可能非常高,但这不代表掉电后数据已经安全落盘。对于数据库而言,真正有意义的是开启持久化确认后,事务提交仍能保持怎样的延迟和吞吐。

用四组指标核验存储层性能

存储层测试的目标不是制造一个最大的数字,而是把宣传数字还原成完整的测试组合。一个可复核的结果至少应包含以下字段:

指标必须记录的内容对结果的影响
块大小4KB、8KB、16KB 等决定单次 I/O 的数据量和访问模式
读写比例100%读、100%写、70/30 混合等写入通常更容易受到阵列和缓存影响
队列深度QD1、QD4、QD32、QD256 等队列越深,越容易堆出峰值,但不一定接近业务
并发任务数numjobs、线程或进程数量影响 CPU、队列和调度方式
访问方式随机或顺序、直接 I/O 或缓存 I/O决定测试的是设备还是操作系统缓存
延迟平均值、p95、p99、最大值反映业务请求是否出现长尾
持续时间预热时间、正式运行时间用于观察缓存耗尽和温度导致的下降
测试位置实际 RAID 挂载点避免测到错误设备

先做低队列深度测试

低队列深度能够观察单个或少量请求的响应能力。对于数据库,QD1 或较低并发下的延迟,往往比极高队列深度下的峰值更有解释力。

以下命令仅作测试格式示例。/data/bench 必须是专门用于测试的目录,不能指向生产数据库目录、生产日志目录或唯一数据盘。fio 会创建并写入测试文件,运行前应确认该路径有备份或其中没有需要保留的数据。

fio --name=randread-4k-q1 \
  --filename=/data/bench/fio-testfile \
  --size=20G \
  --rw=randread \
  --bs=4k \
  --ioengine=libaio \
  --direct=1 \
  --iodepth=1 \
  --numjobs=1 \
  --time_based \
  --runtime=300 \
  --ramp_time=30 \
  --group_reporting \
  --output-format=normal

这组测试主要观察:

  • QD1 下的 4KB 随机读延迟;
  • 单个任务是否能稳定完成 I/O;
  • 低并发时阵列是否存在明显响应抖动;
  • 结果是否与服务商给出的高队列深度数字差距过大。

如果 QD1 延迟较高,而 QD256 才能出现 30 万 IOPS,说明这个数字更接近阵列的并行处理上限,不宜直接用于推断单事务数据库性能。

再做混合读写和纯写测试

数据库通常不是纯读。即使业务以查询为主,也会产生 redo、binlog、WAL、临时表或后台刷盘。因此至少需要分别观察纯读、纯写和混合读写。

下面是一个 4KB、70%读和30%写的高并发示例:

fio --name=randrw-4k-70r30w \
  --filename=/data/bench/fio-testfile \
  --size=100G \
  --rw=randrw \
  --rwmixread=70 \
  --bs=4k \
  --ioengine=libaio \
  --direct=1 \
  --iodepth=32 \
  --numjobs=8 \
  --time_based \
  --runtime=600 \
  --ramp_time=60 \
  --group_reporting \
  --output-format=normal

iodepth=32、numjobs=8意味着理论上的总并发队列约为 256,但实际有效队列还会受到设备、内核和应用调度影响。测试文件大小也应根据设备容量和 fio 版本的任务分配方式核算,不能简单把 --size 当作整个阵列只会占用这一部分空间。

纯写测试可以用相同参数将 --rw=randrw 改为 --rw=randwrite,并移除 --rwmixread。纯写测试对 SSD 磨损和阵列缓存压力更大,必须使用隔离卷,不能在生产目录执行。正式测试前应确认备份、影响范围和剩余容量;测试文件后续只应在确认不再需要时单独清理,不要误操作生产目录。

测试过程中,另一个终端应同步记录设备利用率、等待时间和系统资源:

用四组指标核验存储层性能|再做混合读写和纯写测试配图

iostat -xmd 1 660
vmstat 1
pidstat -d 1

重点不是某一秒的最高值,而是以下变化:

  • IOPS 是否在预热后迅速下降;
  • await 或读写等待时间是否逐步升高;
  • 设备利用率是否长期接近满载;
  • CPU 是否先达到瓶颈;
  • 混合写入时是否出现明显长尾;
  • 运行十分钟左右后,结果是否仍在同一量级。

如果测试只运行十几秒,且结果明显高于长时间运行结果,应将前者视为缓存峰值,而不是持续性能。

为什么必须进行数据库层测试

fio 只能回答“这个块设备在指定 I/O 模式下能处理多少请求”,不能回答“某个数据库在提交事务时能完成多少有效工作”。

数据库会额外涉及:

  • 页面读取和页面淘汰;
  • redo、WAL 或 binlog 写入;
  • fsync、flush 和提交确认;
  • 行锁、事务锁和并发控制;
  • SQL 解析、索引访问和 CPU 消耗;
  • 数据库缓冲池与操作系统缓存;
  • 后台刷脏页和检查点;
  • 网络往返或客户端线程调度。

因此,数据库层至少要记录 TPS、平均响应时间、p95 或 p99 延迟、物理读写量以及 CPU 利用率。数据库报告中的“操作次数”也不能直接等于磁盘 IOPS,一个事务可能包含多次页面访问,也可能大部分数据命中内存。

以 MySQL 为例检查持久化条件

先读取关键参数,不要在生产数据库上为了追求数字随意修改它们:

mysql -h 127.0.0.1 -u bench -p -e \
"SHOW VARIABLES WHERE Variable_name IN
('innodb_buffer_pool_size',
 'innodb_flush_log_at_trx_commit',
 'sync_binlog',
 'sync_log',
 'innodb_doublewrite');"

对于需要可靠事务提交的测试,至少应记录 innodb_flush_log_at_trx_commit 和 sync_binlog 的值。若测试关闭了日志同步,得到的 TPS 不能与开启持久化确认的结果放在同一张表里比较。

数据库测试应使用单独的测试库和测试账号。若测试库中已有数据,先完成备份;不要在生产库执行 prepare、批量写入或清理操作。下面是一个隔离测试库中的 sysbench 示例:

sysbench oltp_read_write \
  --mysql-host=127.0.0.1 \
  --mysql-port=3306 \
  --mysql-user=bench \
  --mysql-password='CHANGE_ME' \
  --mysql-db=sbtest \
  --tables=8 \
  --table-size=1000000 \
  --threads=32 \
  --time=600 \
  --warmup-time=60 \
  --report-interval=10 \
  --db-ps-mode=auto \
  run

如果测试库为空,需要先在该隔离库中准备数据:

sysbench oltp_read_write \
  --mysql-host=127.0.0.1 \
  --mysql-port=3306 \
  --mysql-user=bench \
  --mysql-password='CHANGE_ME' \
  --mysql-db=sbtest \
  --tables=8 \
  --table-size=1000000 \
  --threads=32 \
  --db-ps-mode=auto \
  prepare

prepare 会向测试库写入数据,不能指向生产数据库。测试数据量应根据服务器内存和数据库缓冲池调整:如果所有工作集都能完全放入内存,测试更接近缓存命中能力;如果数据量明显超过可用缓存,才更容易观察存储子系统的持续读写压力。两种测试都有价值,但必须明确属于哪一种。

记录数据库结果时不要只看 TPS

数据库测试结果至少应按下面的方式整理:

项目示例记录方式判断重点
测试引擎MySQL 版本、存储引擎、配置摘要不同版本和引擎不能直接横比
数据规模表数量、行数、总数据量、索引大小判断是否主要命中内存
并发数8、32、64 个线程等并发改变会显著影响 TPS
事务模型读写比例、每事务语句数决定物理 I/O 和锁竞争
持久化设置redo、binlog、fsync 相关参数影响提交安全性和延迟
结果TPS、平均延迟、p95、p99判断吞吐和长尾
资源状态CPU、内存、磁盘利用率、读写等待区分存储瓶颈和其他瓶颈

如果数据库 TPS 在 CPU 已经接近满载时停止增长,不能简单归因于 NVMe RAID 性能不足;如果 CPU 负载不高、磁盘等待明显升高,同时提交 p99 延迟持续增加,才更可能是存储路径成为瓶颈。

如何阅读一组“30万 IOPS”示例数据

下面是一组用于说明阅读方法的示例数据,不代表任何具体香港服务器的实测结果:

如何阅读一组“30万 IOPS”示例数据配图

测试项目参数示例结果结果含义
4KB随机读QD1、1任务48,000 IOPS,p99 0.40ms低队列响应能力
4KB混合读写70%读、30%写,QD约256306,000 IOPS,p99 2.1ms高并发下的存储层峰值
4KB随机写QD约256175,000 IOPS,p99 4.9ms写入和落盘压力下的能力
数据库事务32线程,开启事务持久化13,800 TPS,提交p99 9.6ms具体数据库负载下的有效处理能力

这组数据并不矛盾。混合块设备测试达到 30 万 IOPS,而数据库只有 13,800 TPS,可能是因为一个数据库事务包含多次物理 I/O,还受到锁、CPU、日志提交和 SQL 执行开销影响。

反过来,如果某份报告只给出“4KB随机读 30 万 IOPS”,却把它描述为“数据库读写性能 30 万”,就存在明显的口径扩大。以下几种情况也不能直接认可为数据库读写 30 万:

  • 只测试了 100%随机读;
  • 只测试了几秒钟的突发峰值;
  • 队列深度和线程数没有公开;
  • direct=0,结果可能大量来自操作系统缓存;
  • 测试的是单块 NVMe,而数据库实际使用的是另一块卷;
  • 开启了写回缓存,但没有说明缓存保护;
  • 数据库关闭了日志同步或事务持久化;
  • 只展示 IOPS,没有延迟、TPS 和持续运行曲线;
  • 测试时的数据量远小于内存,无法说明真实存储压力。

复测时要保持哪些条件不变

性能复测最容易出现的问题,是表面上重复了测试,实际上改变了测试条件。要让两次结果可以比较,至少应保持以下内容一致:

  1. 相同的 RAID 级别、成员盘数量和阵列卷。
  2. 相同的文件系统、挂载点和测试文件位置。
  3. 相同的块大小、读写比例、队列深度和并发任务数。
  4. 相同的测试文件规模、预热时间和正式运行时间。
  5. 相同的数据库版本、数据规模、线程数和事务模型。
  6. 相同的持久化参数、日志设置和缓存策略。
  7. 相同的运行时段记录方式,包括 CPU、内存、磁盘等待和温度状态。
  8. 至少进行三次独立运行,并保留每次原始输出,而不是只保留最高成绩。

如果首次测试使用了刚启动、尚未升温的设备,复测则应在相近的预热状态下进行。若首次结果来自服务商提供的截图,复测时应要求完整命令、原始输出和环境信息,不能只对照截图上的一个数字。

选择时只认可以复核的结果

对于香港 NVMe RAID 服务器,30 万 IOPS 可以作为一个待验证的性能目标,但不应当被当作脱离条件的固定能力。比较可靠的判断方式是:

  • 存储层明确给出 4KB 或数据库相关块大小下的随机读、随机写和混合读写结果;
  • 公开队列深度、并发任务、测试文件规模、直接 I/O 设置和持续时间;
  • 同时提供平均延迟与 p99 延迟,而不是只给 IOPS 峰值;
  • 说明 RAID 级别、NVMe 盘数量、阵列缓存和掉电保护情况;
  • 在实际数据库配置下重新测试,并记录 TPS、提交延迟和磁盘等待;
  • 经过预热和较长时间运行后,结果没有明显跌落;
  • 能够在同一服务器的实际挂载卷上复测出相近结果。

如果只能确认“某次高并发 4KB 随机测试超过 30 万 IOPS”,那么准确表述应是“该阵列在特定存储测试条件下达到 30 万级峰值”。如果数据库在开启持久化、使用实际数据规模和混合读写事务后仍能保持目标 TPS,并且 p99 延迟处于可接受范围,才可以把这项存储能力与数据库业务性能建立联系。

目录结构
全文