NVMe 架构详解
NVMe 协议演进
存储协议演进历史:
IDE/PATA(1986)→ SATA(2003)→ SAS(2004)→ NVMe(2011)
关键突破:
SATA/SAS:基于 SCSI 命令集,为 HDD 设计,队列深度有限
NVMe:专为 Flash 设计,充分发挥 SSD 并行性NVMe 技术优势
命令队列对比
SATA:
1 个命令队列
队列深度:32
SAS:
1 个命令队列
队列深度:254
NVMe:
65535 个命令队列
每队列深度:65535
总并发命令:65535 × 65535 ≈ 43 亿
实际意义:
NVMe SSD 内部有数千个 Flash 芯片并行工作
NVMe 的多队列设计充分利用这种并行性
SATA/SAS 的单队列成为瓶颈CPU 开销对比
SATA/SAS I/O 路径:
应用 → 系统调用 → VFS → 块层 → SCSI 层 → 驱动 → 控制器
CPU 中断次数:每次 I/O 1 次中断
NVMe I/O 路径:
应用 → 系统调用 → VFS → 块层 → NVMe 驱动 → 控制器
CPU 中断次数:可批量处理(Interrupt Coalescing)
CPU 开销降低:约 50%(相比 SATA)NVMe SSD 内部架构
NVMe SSD 内部结构:
NVMe 控制器
├── 主机接口(PCIe 4.0 x4)
├── Flash 控制器
│ ├── ECC 引擎(纠错)
│ ├── 磨损均衡(Wear Leveling)
│ └── 垃圾回收(Garbage Collection)
└── Flash 存储阵列
├── Die 0(并行单元)
├── Die 1
├── ...
└── Die N(通常 8-32 个 Die)
Flash 类型:
SLC(1 bit/cell):最快,最耐用,最贵
MLC(2 bit/cell):平衡
TLC(3 bit/cell):主流,性价比高
QLC(4 bit/cell):最便宜,耐用性较低NVMe-oF 网络存储
协议栈
NVMe-oF 协议栈:
主机端:
应用
↓
NVMe 驱动(内核)
↓
NVMe-oF 传输层
├── NVMe/FC(FC 网络)
├── NVMe/RoCE(以太网 RDMA)
└── NVMe/TCP(普通以太网)
存储端:
NVMe-oF Target
↓
NVMe SSD(本地)NVMe/TCP 配置
bash
# 主机端配置(Initiator)
# 加载 NVMe/TCP 模块
modprobe nvme-tcp
# 发现目标(Discovery)
nvme discover -t tcp -a <storage-ip> -s 4420
# 连接到 NVMe 子系统
nvme connect -t tcp \
-a <storage-ip> \
-s 4420 \
-n nqn.2024-01.com.h3c:storage01
# 查看连接的 NVMe 设备
nvme list
nvme list-subsys
# 存储端配置(Target)
# 加载 NVMe/TCP target 模块
modprobe nvmet
modprobe nvmet-tcp
# 创建子系统
mkdir /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01
echo 1 > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01/attr_allow_any_host
# 创建命名空间(关联 NVMe 设备)
mkdir /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01/namespaces/1
echo /dev/nvme0n1 > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01/namespaces/1/device_path
echo 1 > /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01/namespaces/1/enable
# 创建端口
mkdir /sys/kernel/config/nvmet/ports/1
echo tcp > /sys/kernel/config/nvmet/ports/1/addr_trtype
echo <storage-ip> > /sys/kernel/config/nvmet/ports/1/addr_traddr
echo 4420 > /sys/kernel/config/nvmet/ports/1/addr_trsvcid
echo ipv4 > /sys/kernel/config/nvmet/ports/1/addr_adrfam
# 关联子系统到端口
ln -s /sys/kernel/config/nvmet/subsystems/nqn.2024-01.com.h3c:storage01 \
/sys/kernel/config/nvmet/ports/1/subsystems/性能调优
bash
# NVMe SSD 性能调优
# 1. I/O 调度器(NVMe 推荐 none)
echo none > /sys/block/nvme0n1/queue/scheduler
# 2. 队列深度
cat /sys/block/nvme0n1/queue/nr_requests # 查看当前值
echo 1024 > /sys/block/nvme0n1/queue/nr_requests
# 3. 预读(顺序读场景增大,随机读场景减小)
echo 0 > /sys/block/nvme0n1/queue/read_ahead_kb # 随机读
echo 4096 > /sys/block/nvme0n1/queue/read_ahead_kb # 顺序读
# 4. 文件系统挂载选项(XFS 推荐)
mount -o noatime,nodiratime,discard /dev/nvme0n1 /data
# noatime:不更新访问时间(减少写入)
# discard:启用 TRIM(维护 SSD 性能)
# 5. 性能测试
fio --name=nvme-test \
--ioengine=io_uring \ # 最新高性能 I/O 引擎
--iodepth=256 \
--rw=randread \
--bs=4k \
--direct=1 \
--size=100G \
--numjobs=8 \
--runtime=60 \
--group_reporting \
--filename=/dev/nvme0n1