Netpath
学习路径31 / 49 · 高性能网络看全程 →
原理深入预计 30 分钟

NVMe-oF:把 NVMe 协议搬到网络上

远端盘做到接近本地盘的延迟,靠的是不做协议转换。

学完这节你能做到

  • 区分 NVMe/RDMA、NVMe/TCP、NVMe/FC 三种传输
  • 解释 NVMe-oF 相比 iSCSI 的延迟优势来自哪里
  • 完成一次 discover 与 connect 并确认多路径

建议先学

跳过这几节会看不懂本节的部分推导

让远端盘像本地盘

本地 NVMe 盘的延迟在几十微秒量级。传统的网络块存储(iSCSI)要一百多微秒到毫秒—— 差距不在网络,而在协议转换。

iSCSI:    应用 → 块层 → SCSI 层 → iSCSI 封装 → TCP → 网络 → 反向拆一遍
NVMe-oF:  应用 → 块层 → NVMe 命令 → 直接放到网络上 → 对端直接执行
                          ↑ 没有 SCSI 这一层转换

NVMe-oF 的核心思想是"不做协议转换":本地 NVMe 用什么命令集, 网络上就传什么命令集,两端都是 NVMe。

队列模型才是关键

NVMe 相对 SCSI 的根本改进不是命令集,是队列模型:

SCSI / SASNVMe
队列数1 个最多 64K 个
每队列深度32–25664K
锁竞争单队列成为瓶颈每个 CPU 核一个队列,无锁

多队列的意义在多核服务器上很直接:每个核有自己的提交/完成队列, 不需要跨核同步。这个模型原样搬到网络上,就是 NVMe-oF—— 所以它天生适合高并发。

三种 fabric

传输延迟需要什么适合
NVMe/RDMA(RoCE 或 IB)最低无损网络、RDMA 网卡高性能存储,与 L2 那套要求一致
NVMe/TCP中普通以太网即可落地最容易,通用场景
NVMe/FC低光纤通道网络已有 FC 投资的传统存储环境

选择逻辑和 IB vs RoCE 那节一样:

  • 有无损网络与 RDMA 能力 → NVMe/RDMA,性能最好
  • 只有普通以太网、也没人调 PFC/ECN → NVMe/TCP,先跑起来
  • 已有 FC SAN → NVMe/FC 复用现有投资
✓NVMe/TCP 比想象中好用

很多人默认"要上 NVMe-oF 就得先建无损网络",于是项目卡在网络改造上。

实际上 NVMe/TCP 在普通以太网上就能跑,延迟虽然高于 RDMA, 但仍然明显优于 iSCSI(因为省掉了 SCSI 转换层)。

务实的路径是:先用 NVMe/TCP 把业务跑起来, 确认瓶颈真的在网络延迟上,再考虑改造成 RDMA。 这和 L2 里"团队没人会调 PFC 就先用高带宽 TCP"是同一个判断。

基本概念

概念含义类比
NQNNVMe Qualified Name,唯一标识iSCSI 的 IQN
subsystem服务端暴露的一组资源iSCSI 的 target
namespace一个可访问的块设备LUN
controller一次连接建立的会话—

NQN 长这样:

nqn.2014-08.org.nvmexpress:uuid:12345678-1234-1234-1234-123456789abc
nqn.2026-01.com.example:storage-01

客户端实操

# 装工具
dnf install -y nvme-cli        # 或 apt install nvme-cli

# ① 发现目标(TCP)
nvme discover -t tcp -a 10.0.20.10 -s 4420

# RDMA 场景把 -t 换成 rdma
nvme discover -t rdma -a 10.0.20.10 -s 4420
Discovery Log Number of Records 1
=====Discovery Log Entry 0======
trtype:  tcp
adrfam:  ipv4
subnqn:  nqn.2026-01.com.example:storage-01
traddr:  10.0.20.10
trsvcid: 4420
# ② 连接
nvme connect -t tcp -a 10.0.20.10 -s 4420 \
  -n nqn.2026-01.com.example:storage-01

# ③ 确认设备出现了
nvme list
lsblk | grep nvme
Node          SN        Model                  Namespace  Usage
/dev/nvme1n1  ...       Linux                  1          3.84 TB

到这里 /dev/nvme1n1 就是一个普通块设备,可以格式化、挂载、给数据库用—— 上层完全不知道它在网络对面。

# ④ 断开
nvme disconnect -n nqn.2026-01.com.example:storage-01

# 开机自动连接
nvme connect-all -t tcp -a 10.0.20.10 -s 4420
systemctl enable nvme-autoconnect.service    # 发行版名称可能不同

多路径:别只连一条

生产环境要走两条独立路径,否则单条链路故障就丢盘:

# 连两个不同的地址(两张网卡、两个交换机)
nvme connect -t tcp -a 10.0.20.10 -s 4420 -n <nqn>
nvme connect -t tcp -a 10.0.21.10 -s 4420 -n <nqn>

# 查看多路径状态
nvme list-subsys
nvme-subsys1 - NQN=nqn.2026-01.com.example:storage-01
\
 +- nvme1 tcp traddr=10.0.20.10 trsvcid=4420 live optimized
 +- nvme2 tcp traddr=10.0.21.10 trsvcid=4420 live optimized

两条都是 live 才算冗余生效。

多路径实现说明
NVMe 原生多路径(ANA)内核 nvme_core.multipath=Y,推荐
device-mapper multipath传统方案,与 SCSI 时代一致
!两条路径要真的独立

常见的假冗余:两条路径走同一张物理网卡的两个 IP、或者经过同一台交换机。 这种配置在软件层面看是双路径,物理上仍是单点。

真正的独立要求:

  • 不同的物理网卡
  • 不同的交换机(以太网规划 里的双上行)
  • 最好是不同的存储控制器

验证方法很朴素:拔一根线,看业务还在不在。

网络侧的要求

NVMe-oF 对网络的要求比普通业务高,而且这些要求 L0–L3 都讲过:

要求为什么参考
低延迟每个 I/O 都要一个往返三个指标
不丢包(RDMA 场景)go-back-N 会让带宽雪崩RoCE
MTU 一致大块 I/O 会打满 MTU二层与三层
存储网独立恢复流量不能影响业务以太网规划
1:1 无收敛(存储侧)多客户端同时读写规划那节
# 排查时的常规动作
ping -M do -s 8972 10.0.20.10       # MTU 端到端一致性
nstat -az | grep -i retrans          # TCP 场景看重传
ethtool -S bond0 | grep -i pause     # RDMA 场景看 PFC

和其它存储方案的对照

方案延迟适合
本地 NVMe几十 μs单机、无需共享
NVMe/RDMA接近本地需要共享的高性能场景
NVMe/TCP中通用共享块存储
iSCSI高兼容性优先的遗留环境
Ceph RBD更高(多副本 + 分布式)要弹性扩展与自愈

关键取舍:NVMe-oF 提供的是低延迟的共享块设备, 但它本身不提供分布式冗余——数据保护要靠后端存储阵列或上层方案。 Ceph 这类分布式存储牺牲延迟换来的是弹性与自愈能力。

想深入存储侧可以看 Storpath, 这里只讲网络这一面。

检查点

Checkpoint单选

NVMe-oF 相比 iSCSI 延迟明显更低,主要原因是什么?

Checkpoint单选

团队想上 NVMe-oF 但没有无损网络,也没人会调 PFC/ECN。合理的做法是?

Checkpoint单选

nvme list-subsys 显示两条路径都 live,但拔掉一根网线后业务中断。最可能的原因?

这节课的落点

  • NVMe-oF 的核心是不做协议转换:两端都是 NVMe 命令集,省掉 SCSI 转换层
  • 根本优势来自多队列模型:每核一个队列、无锁,天生适合高并发
  • 三种 fabric:RDMA(最快)、TCP(最易落地)、FC(复用已有投资)
  • NVMe/TCP 值得先试:普通以太网就能跑,仍明显优于 iSCSI
  • 四个概念:NQN、subsystem、namespace、controller;操作就是 discover → connect → nvme list
  • 连上后就是普通块设备,上层完全无感
  • 生产必须多路径且物理独立:不同网卡、不同交换机;验证靠拔线
  • 网络侧要求(低延迟、不丢包、MTU 一致、存储网独立、1:1)在 L0–L3 都讲过
  • NVMe-oF 给的是低延迟共享块设备,冗余要靠后端或上层,与 Ceph 的取舍不同

延伸资料