
转载自DPDK与SPDK开源社区公众号
一概述
英特尔®最新推出的E810系列网络适配器,通过创新通用功能提高应用程序效率和网络性能,这些功能可优化高性能服务器工作负载,例如NFV,存储,HPC-AI和混合云。本文通过介绍如何利用英特尔®E810网卡的ADQ特性来加速其在存储上的应用。
二ADQ特性简介以及在SPDK中的应用
E810网卡简介
E810[1]系列网卡具有以下重要特性,这里我们讲重点介绍ADQ[2]在应用程序的使用:
单端口和双端口QSFP28 应用程序队列(ADQ) PCI Express(PCIe)4.0 * 16 动态设备个性化(DDP) 以太网端口配置工具(EPCT) 同时支持RDMA iWARP和RoCEv2
...
ADQ概览
随着现代数据中心的扩展,关键的挑战是提供可扩展,可预测的应用程序级性能。ADQ技术通过将队列专用于关键工作负载来提高性能可伸缩性和可预测性,并通过显着降低抖动来提供可预测的高性能。通过降低抖动来提高应用程序响应时间的可预测性,可以为任务分配更多的计算服务器,并可以允许更多的用户访问系统,从而提供更好的终端用户体验。甚至非大型应用程序也可以从更高的一致性中受益,从而使它们更容易满足服务级别协议(SLA)。图1部分给出了使用ADQ以及不使用ADQ特性的例子。不同颜色的汽车类似不同的应用,不同的车道类似不同的网卡队列。使用ADQ之后,某些网卡队列可以直接分配给某些专有应用,从而这些应用的网络包可以在特定的队列上处理,和其他应用隔离开来。
...
图1 ADQ特性的开启以及关闭
ADQ其工作机制主要包含以下三个方面:1.将应用程序流量过滤到一组专用队列;2. 执行的应用程序线程连接到ADQ队列集中的特定队列;3.速率限制应用出口(Tx)网络流量。以上机制可以多方面提高系统的性能,主要体现在三个方面:1.提高应用的可预测性;2.减少应用程序延迟;3.提高应用程序吞吐量。ADQ特性的优势体现在图2
...
图2 ADQ特性的优势
ADQ在SPDK中的应用简介[4,5]
SPDK[2]使用ADQ[3]的以下功能:
1. 根据硬件队列对套接字进行分组
每个硬件队列都与唯一的NAPI_ID相关联。使用SO_INCOMING_NAPI_ID套接字选项将与给定的HW队列关联的所有套接字分组。 从SPDK版本20.10开始,NVMe-oF target全部改为Transport的调度算法。如果要使用ADQ, 需要通过RPC打开 enable_placement_id的选项,用于开启基于placement_id (即NAPI_ID)的调度算法。2. 交通导向
硬件队列分为流量类别,并被分配来处理应用程序流量。这是使用tc命令完成的。过滤器是根据NVMF目标地址和端口号配置的。它配置硬件文件管理器,并将数据包引导到适当的硬件队列。 Tx数据包根据套接字优先级进行控制。3. 对称排队
连接的Rx和Tx数据包都流经相同的HW队列4. 增强了对硬件队列的繁忙轮询
ADQ配置相关工具
1. 了解tc命令
通过以下命令来介绍tc命令的配置
# tc qdisc add dev eth4 root mqprio num_tc 3 map 2 2 1 0 2 2 2 2 2 2 2 2 2 2 2 2 queues 4@0 6@4 2@10 hw 1
上面的命令配置3种流量类别。HW队列根据命令末尾的配置映射到每个流量类。
a) tc0从队列0(q0-q3)开始有4个队列
b) tc1有6个从队列4(q4-q9)开始的队列
c) tc2有2个从队列10开始的队列(q10,q11)
关键字“ map”后的字符串是流量类别map的优先级(从0 到15)。它将每个优先级0-15映射到指定的流量类别。映射中的索引(从零开始)是优先级,给定索引处的值指定流量类别编号。
a) 优先级3映射到tc0,并且tc0包含硬件队列0-3。
b) 优先级2映射到tc1,tc1包含硬件队列4-9。
c) 优先级0,1,4-15映射到tc2,其中包含硬件队列10和11。
2. 交通导向
#tc qdisc add dev $iface root mqprio num_tc 2 map 0 1 queues 2@0 $queues@2 hw 1 mode channel
#tc qdisc add dev $iface ingress
以上命令中配置了两个流量类别。tc0有两个队列0,1。tc1中的队列数是根据用户的输入进行配置的。优先级0映射到tc0,优先级1映射到tc1。
# tc filter add dev $iface protocol ip parent ffff: prio 1 flower \
dst_ip $traddr/32 ip_proto tcp dst_port $trsvcid skip_sw hw_tc 1配置流量类别后,将使用目标地址(traddr)和端口号(trsvcid)配置tc过滤器来控制数据包。在target机器上,传入的数据包将在目标ip字段中具有目标的地址,而在目标端口字段中将具有trsvcid(即nvmf_tgt侦听端口)。该过滤器与tc1相关联。在启动器端,将过滤器配置为使用nvmf_tgt应用程序使用源地址和源端口进入的数据包。
tc配置仅影响Rx流量。Tx流量是根据流量类别映射配置的优先级由套接字优先级配置的。在上面的示例中,tc1用于nvmf_tgt应用程序流量,优先级1映射到tc1。因此,SPDK配置中的套接字优先级应设置为1。
3. 对称排队
spdk使用非阻塞套接字(O_NONBLOCK),并且在轮询组轮询期间,将调用epoll_wait(在POSIX实现中使用),且超时为0。由于此net.core.busy_poll无效。由于套接字是非阻塞的,因此net.core.busy_read取非零值就足够了。
sysctl -w net.core.busy_poll=0
sysctl -w net.core.busy_read=1ADQ驱动程序根据哪个状态机确定何时从繁忙轮询模式转换到中断模式来启用channel-pkt-inspect-optimize选项。当选项为“开”时,从忙碌轮询模式到中断模式的转换要比“关”时更快。如果关闭此选项,则使用spdk的性能最佳。
ethtool --set-priv-flags $iface channel-pkt-inspect-optimize off
为了在繁忙的轮询期间优化吞吐量,驱动程序提供了附加选项。这些设置是128k io最佳性能所必需的。
ethtool --set-priv-flags enp59s0f0 channel-pkt-clean-bp-stop on
ethtool --set-priv-flags enp59s0f0 channel-pkt-clean-bp-stop-cfg on
4. 繁忙轮询
配置对称队列,该对称队列使套接字的Tx和Rx数据包都使用相同的硬件队列。
三软硬件系统先决条件
硬件要求
Target端服务器
Intel® Xeon® Scalable处理器
Intel® Ethernet 800系列网卡
40+ GB内存
1+ PCIe Gen3 NVME SSD
Host端服务器
Intel® Xeon® Scalable处理器
Intel® Ethernet 800系列网卡
40+ GB内存
硬件拓扑结构
两台物理机器背靠背连接100G电缆。拓扑结构如下图3所示:
图3 在两台物理机器上部署NVMe-oF的拓扑结构示意图
软件要求
在配置系统之前有一些先决条件需要满足,包括操作系统,内核以及相应的软件包及系统工具。
操作系统:英特尔®以太网800系列支持带有软件开发包的基于Linux的操作系统。本文档假定使用RHEL 8.1+,但也可以使用其他版本。请参阅https://cdrdv2.intel.com/v1/dl/getContent/630155(文档编号:630155)中支持的操作系统 Linux内核V5.8.16或者更新版本 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-5.8.16.tar.gz 编译内核时需要把Device Drivers->NVME Support->NVM Express over Fabrics TCP host driver (NEW)以及NVMe over Fabrics TCP target support (NEW)选项选中 网卡驱动以及NVM文件 a.E810 ice-1.0.4或者更新的版本 https://sourceforge.net/projects/e1000/files/ice%20stable/ b.E810 NVM 2.20或者更新的版本 https://downloadcenter.intel.com/download/29738/Non-Volatile-Memory-NVM-Update-Utility-for-Intel-Ethernet-Adapters-E810-Series-Linux- ethtool版本5.0或更高版本 https://mirrors.edge.kernel.org/pub/software/network/ethtool/ethtool-5.1.tar.gz iproute2软件包(带有最新选项的tc实用程序) https://mirrors.edge.kernel.org/pub/linux/utils/net/iproute2/iproute2-5.1.0.tar.gz SPDK v20.07或者更新版本:https://github.com/spdk/spdk nvme-cli:https://github.com/linux-nvme/nvme-cli/releases fio版本3.3或者更高版本(仅需要安装在initiator端) https://github.com/axboe/fio/archive/fio-3.14.tar.gz四系统安装(包括target端和host端)
安装操作系统
建议安装英特尔®E800[4]系列网卡支持的Linux操作系统以及相应的开发工具包。这里安装的是fedora29,kernel是5.4.5,建议使用最新版本
更新内核
这里使用最新的Linux 5.8.16内核作为实例介绍更新内核的步骤
1.下载最新的内核
#wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.8.16.tar.gz
2.解压内核压缩包
#tar -xvf linux-5.8.16.tar.gz
3.切换到内核源代码目录
#cd linux-5.8.16
4.安装编译内核所需的工具包
#yum install -y make jq gcc ncurses-devel flex bison kernel-devel kernel-headers openssl-devel elfutils-libelf-devel vim perl rdma-core patch rpm-build cmake libudev-devel ninja-build pandoc perl-generators python systemd-devel valgrind-devel libnl3-devel python3-docutils
5.编译以及安装内核
# cp /boot/config-4.18.16-300.fc29.x86_64 .config
#make menuconfig
Device Drivers->NVME Support->NVM Express over Fabrics TCP host driver (NEW)设置为M
Device Drivers->NVMe over Fabrics TCP target support (NEW)设置为M
修改.config文件中下列选项配置如下
CONFIG_NET_SCH_MQPRIO=m
CONFIG_NET_ACT_MIRRED=m
CONFIG_NET_CLS_FLOWER=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_SMP=y
CONFIG_ICE=n
CONFIG_NR_CPUS_DEFAULT=8192
CONFIG_NVME_CORE=m
CONFIG_UIO=m
CONFIG_UIO_PCI_GENERIC=m
CONFIG_BLK_DEV_NVME=m
CONFIG_BLK_DEV_NVME_SCSI=y
CONFIG_NVME_FABRICS=m
CONFIG_NVME_TARGET=m
CONFIG_NVME_TARGET_TCP=m
CONFIG_NVME_TCP=m
CONFIG_NVME_TARGET_LOOP=m
编译内核以及安装
#make
#make modules_install
#make install
6.切换到最新的内核版本
# cat /boot/grub2/grub.cfg |grep Fedora
# grub2-set-default "Fedora (5.8.16) 29 (Server Edition)"
# grub2-editenv list
# grub2-mkconfig -o /boot/grub2/grub.cfg
#vim /etc/grub2.cfg
set default=”0”
7. 重启系统
#reboot
安装网卡驱动ice(使能ADQ)
1.下载ice网卡驱动
从以下链接下载你所需要的驱动版本
https://sourceforge.net/projects/e1000/files/ice%20stable/
2.解压缩ice驱动
#tar zxvf ice-${driverversion}.tar.gz
3.换到ice驱动源代码目录
#cd ice-${driverversion}/src
4.编译并安装ice驱动
# make CFLAGS_EXTRA='-DADQ_PERF -DADQ_PERF_COUNTERS' install
5.加载ice驱动
#modprobe ice
安装iproute2
1.加载所需的内核模块
#modprobe sch_mqprio
#modprobe act_mirred
#modprobe cls_flower
2.下载iproute2源代码
# git clone https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
3.安装iproute2所需的依赖工具包
#yum -y install libdb-devel
4.切换到iproute2目录
#cd iproute2
5.安装iproute2
#./configure
#make DESTDIR=/opt/iproute2 install
安装cgroup
# yum -y install libcgroup libcgroup-tools
安装nvme-cli
1.下载nvme-cli源代码
# wget https://github.com/linux-nvme/nvme-cli/archive/${nvmecliversion}.tar.gz
2.解压缩nvme-cli
#tar zvxf ${nvmecliversion}.tar.gz
3.安装nvme-cli
#cd nvme-cli-${nvmecliversion}
#make
#make install
安装spdk
1.下载spdk源代码
#git clone https://github.com/spdk/spdk.git
2.安装相应的依赖包
#cd spdk
#git submodule update --init
# ./scripts/pkgdep.sh
3.编译并安装spdk
#./configure –with-fio=<path_to_fio> --enable-lto
#make
#make install
安装nvmetcli
1.下载nvmetcli
从链接下载最新的nvmetcli压缩包,ftp://ftp.infradead.org/pub/nvmetcli/
2.安装nvmetcli
#tar zxvf nvmetcli-${nvmetcli_version}.tar.gz
#cd <path_to_nvmetcli>
#python setup.py install
安装fio
1.下载fio源代码
#git clone https://github.com/axboe/fio.git
2.编译并安装fio
#cd <path_to_fio>
#./configure
#make
#make install