如何用fio实测并优化NVMe SSD在香港裸金属服务器上的4K随机读写性能?

前段时间,我们公司在香港部署了一批裸金属服务器,主要用于高并发数据库和日志处理场景。为了追求极致 IOPS 和低延迟,我们选用了基于 PCIe 4.0 的企业级 NVMe SSD。然而,部署上线后发现,实际的 4K 随机读写性能远远达不到厂商标称的参数,尤其是写入性能严重波动,甚至影响了业务稳定性。
面对这种问题,我决定用 fio 工具对服务器进行全方位的存储性能测试,并针对不同指标进行优化。以下是我的完整实操过程与技术总结,供有类似需求的同学参考。
一、测试前准备
1.1 环境说明
- 服务器位置:香港数据中心(Equinix)
- 操作系统:Ubuntu 22.04 LTS
- CPU:Intel Xeon Gold 6338 (32 cores, 64 threads)
- 内存:256GB DDR4 ECC
- NVMe SSD:2TB Samsung PM9A3 x 2(PCIe 4.0)
- fio 版本:fio-3.33
1.2 安装 fio 工具
sudo apt update
sudo apt install fio
确认版本:
fio --version
# 输出应为 fio-3.33 或更新版本
二、fio 基准测试设计
我采用了典型的 4K 随机读写场景进行基准测试,这是数据库、消息队列等关键服务最敏感的性能维度。
2.1 4K 随机读测试脚本
fio --name=randread --filename=/dev/nvme0n1 \
--direct=1 --iodepth=32 --rw=randread \
--bs=4k --numjobs=4 --runtime=60 --time_based \
--group_reporting
2.2 4K 随机写测试脚本
fio --name=randwrite --filename=/dev/nvme0n1 \
--direct=1 --iodepth=32 --rw=randwrite \
--bs=4k --numjobs=4 --runtime=60 --time_based \
--group_reporting
三、测试结果分析与瓶颈定位
3.1 初始结果(未优化)
READ: IOPS=320K, BW=1280MiB/s, lat=150us
WRITE: IOPS=95K, BW=380MiB/s, lat=480us
读性能还可以接受,但写入 IOPS 明显偏低。根据经验,企业级 NVMe SSD 的 4K 写 IOPS 应在 200K 以上。初步判断为 I/O 调度、CPU NUMA、写缓存策略或 IO 队列设置问题。
四、逐项优化实践
4.1 优化 I/O 调度器
默认调度器为 mq-deadline,对顺序读写友好,但对小块随机写不理想。尝试切换为 none:
echo none | sudo tee /sys/block/nvme0n1/queue/scheduler
重新测试,写入性能提升约 20%。
4.2 禁用写入缓存(测试目的)
sudo hdparm -W0 /dev/nvme0n1
这会减少写缓存带来的虚假性能提升,更贴近真实的持久化写入能力。
⚠️ 注意:上线环境需酌情恢复写缓存,避免性能下降。
4.3 增加 IO 深度与并发任务数
我们发现在 IO 并发过低时无法压满 SSD 的硬件能力。尝试如下配置:
--iodepth=64 --numjobs=8
性能跃升至:
WRITE: IOPS=210K, BW=840MiB/s, lat=310us
4.4 固定 NUMA 亲和性
将测试进程绑定到与 NVMe 设备直连的 NUMA 节点上,避免跨 NUMA 引发的延迟:
numactl --cpunodebind=0 --membind=0 fio ...
进一步优化了写延迟,下降到 250us 以内。
五、fio 高级技巧与参数建议
使用 libaio 引擎比 sync 更高效:
--ioengine=libaio
显示延迟分布直方图,分析尾延迟:
--latency-percentiles=1 --log_avg_msec=1000
准备大文件测试真实设备(避免 cache 干扰):
fallocate -l 20G /mnt/testfile
然后测试:
fio --filename=/mnt/testfile ...
六、结论与建议
最终优化后的 4K 随机写 IOPS 达到了 220K,4K 随机读突破 350K,基本达到了该型号 NVMe SSD 的理论上限。在这次实践中,我总结了以下经验:
- fio 不只是测试工具,更是性能调优的指南针;
- 裸金属服务器的 NUMA 架构必须充分考虑;
- IO 深度和并发是性能的关键调节杆;
- 调度器选择影响明显,尤其是对写入密集型场景;
- 用“latency percentiles”去分析尾部延迟非常关键。
附录:fio 完整测试模板(可复用)
[global]
ioengine=libaio
direct=1
bs=4k
iodepth=64
numjobs=8
time_based
runtime=60
group_reporting
latency_percentiles=1
[randwrite]
rw=randwrite
filename=/dev/nvme0n1
[randread]
rw=randread
filename=/dev/nvme0n1
这篇文章希望能为你在部署裸金属 NVMe SSD 时提供切实可行的 fio 测试和优化思路。如果你也遇到类似问题,欢迎交流。