spdk-nvmf指南
spdk-nvmf指南
概述
NVMe协议制定了本机高速访问PCIe SSD的规范,为了把本地高速访问的优势暴露给远端应用, 诞生了NVMe-oF 协议。NVMe-oF target 是NVMe协议在不同传输网络 (transport) 上面的延伸。NVMe-oF 协议中的 transport 可以多种多样, 诸如 Ethernet, Fibre Channel,Infiniband等。当前比较流行的transport实现是基于RDMA的Ethernet transport, Linux Kernel 和SPDK的NVMe-oF target 都支持。
名词解释
nvme over fabric
- controller:nvme的字符设备,对应为
/dev/nvmeX
,是我们下发控制命令的设备。 - namespace:nvme的块设备,对应为
/dev/nvmeXnX
,也是我们下发IO的设备。 - host:client端。
- target:处理client请求,连接实际存储设备。
- transport:Transport是连接Host和Target的桥梁,可以是PCIE/RDMA/FC/TCP
- subNQN:用于识别远程NVMe存储目标controller. 保存在identify controller
- EUI64/UUID/NGUID: 用于识别远程NVMe namespace. 保存在NVMe Namespace Descriptor List,EUI64/NGUID同时保存在identify namespace
- 注意:spdk使用uuid作为identifier连接kernel nvme initiator,在重连的时候有bug,这个bug在kernel5.13上才被修复掉。
spdk nvmf
subsystem:spdk创建的nvme controller。相当于nvme controller,拥有了subsystem就可以被nvme host识别到并挂载了,就算他名下没有namespace。
nvmf initiator 和 target
主要介绍 linux kernel nvme initiator + spdk nvmf target。spdk的nvmf initiator使用方法和访问pcie盘类似,不再详述。
spdk nvmf target
nvmf和vhost一样都是spdk的一个模块。启动nvmf模块就相当于启动了一个nvme over fabrics target。启动后可以通过rpc创建nvmf subsystem,并把bdev挂载到namespace上。最后通过监听端口,实现远端nvme initiator的访问。
spdk nvmf target 创建示例:
# 创建相应的transport,可以使TCP或者RDMA
python scripts/rpc.py nvmf_create_transport -t RDMA -u 8192 -p 2 -c 4096
# 创建一个 bdev
python scripts/rpc.py construct_malloc_bdev bdev_test
# 创建一个NVM subsystem
python scripts/rpc.py nvmf_create_subsystem nqn.2020-05.io.spdk:bdev_test -a -m 10 # -a = allow all
# 给NVM subsystem 增加一个namespace,使用malloc bdev。
python scripts/rpc.py nvmf_subsystem_add_ns nqn.2020-05.io.spdk:bdev_test bdev_test -g 9EF1D3DAB2044ABA8F83B0427E58AEB0
# 让nvmf subsystem监听对应的端口,至此一块nvmf 盘已经建立成功,可以成功的被远端host discover到。
python scripts/rpc.py nvmf_subsystem_add_listener nqn.2020-05.io.spdk:bdev_test -t rdma -a 172.0.0.1 -s 4420
linux kernel NVMeOF initiator
- nvme over fabrics驱动默认不会被加载,我们一般看到的nvme驱动是pcie驱动。我们使用
modprobe nvme-rdma
启动 nvmf rdma驱动 - 使用命令工具nvme让nvme host挂载对应target上的盘,下面是一个示例:
# Discovery 列出spdk nvmf target所有的subsystem
nvme discover -t rdma -a 172.0.0.1 -s 4420
# 连接一块nvmf盘,使用-n参数指定subnqn,只连接对应subnqn的盘。
nvme connect -t rdma -n "nqn.2020-05.io.spdk:bdev_test" -a 172.0.0.1 -s 4420
# 连接对应spdk nvmf target下所有的盘。
nvme connect-all -t rdma -a 172.0.0.1 -s 4420
# 两种disconnect的方式,一种是指定盘符,一种是指定subnqn
nvme disconnect -d /dev/nvme0
nvme disconnect -n "nqn.2020-05.io.spdk:bdev_test"
multipath
同一个subsystem在initiator端挂载两次(例如从两个IP连过来),initiator端能识别到两次挂载实际上是同一块盘,这就是multipath功能,开启multipath有如下好处:;
- 保护同一个subsystem不会再同一个host上挂载多次
- 多次挂载冗余保护,例如:一个IP上的网卡宕机
linux kernel 4.15可以配置CONFIG_NVME_MULTIPATH
启动multipath功能。启动之后,假设我们对用一个subsystem挂载两次,nvme0和nvme1,/dev
目录会显示如下
$ ll /dev/nvme*
/dev/nvme0
/dev/nvme0n1
/dev/nvme1
如果nvme0因为某种原因断开,只要nvme1不断开,那么nvme0n1就会可用。
与之对应,如果不启动multipath,/dev
目录会显示两个controller和两个namespace
实践注意事项
- spdk会以roundrobin的形式分配IO queue到spdk core,因此仅增加io queue而不增加spdk core,可能性能并不会有很好的提升。
- 如果spdk重启,需要依赖另一端initiator重连,kernel intiator默认的重连频率是10秒。
- 如果性能不达标,可以尝试修改nvmf上的网络参数,比如包大小之类。
- 对于bdev的异步事件:扩容和bdev关闭,spdk-nvmf已经实现了通知机制,通知initiator。
- 使用kernel initiator要注意内核驱动的操作是否有幂等性、超时等保证,否则极其容易造成kernel D住。建议在可以允许的范围内选择高版本的kernel。当然实践过程中或许不可避免的要backport。
参考链接
- NVMe over Fabrics 技术特征
- 深入理解 SPDK NVMeTCP transport的设计
- 基于SPDK的高效NVMe-oF target
- 20.01 SPDK NVMe-oF RDMA Performance Report官方详细的性能测试结果,可作为后续性能优化的依据
- NVMe over Fabrics Target官方例子,如何起spdk nvmf target
- SPDK NVMe-oF target 多路功能介绍
- 搭建远端存储,深度解读SPDK NVMe-oF target
- SPDK线程模型解析
- NVMe Over Fabrics video from the 2016 OpenFabrics Workshop
更多推荐
所有评论(0)