本文以三代实例使用Pktgen-DPDK、Kernel Pktgen、iPerf3、ping工具测试网络性能的方法为例,向您介绍如何测试实例的网络PPS、网络带宽和网络时延。
不同测试场景下,推荐的实例规格及数量如下表所示。
测试实例的网络PPS( ≤ 600万)、网络带宽、网络时延
说明
测试实例的网络带宽和网络时延对网络PPS大小没有要求,可选择任意实例规格进行测试。详细规格性能请参见实例规格介绍。
测试示例 | 被测试机器(DUT) | 辅助测试机器(Tester) |
---|---|---|
实例规格 | g3i.large | g3i.large |
镜像 | Ubuntu 22.04 | Ubuntu 22.04 |
网卡数量 | 1 | 1 |
实例数量 | 1 | 1 |
测试实例的网络PPS( > 600万)
说明
使用Pktgen-DPDK测试时,每台实例需要准备两张网卡,分别用于登录运行命令和DPDK测试使用,注意要将eth1作为DPDK测试网口,eth0作为管理网口,切换eth0到用户态会导致SSH会话断开。
任何网络PPS > 600万的三代实例均可参考本文测试网络PPS,本文选择g3i.48xlarge(192vCPU)实例是为了测试规格中标称的最佳3600万PPS。
测试示例 | 被测试机器(DUT) | 辅助测试机器(Tester) |
---|---|---|
实例规格 | g3i.48xlarge | g3i.48xlarge |
镜像 | Ubuntu 22.04 | Ubuntu 22.04 |
网卡数量 | 2 | 2 |
实例数量 | 1 | 1 |
远程连接被测试机和辅助测试机,具体操作请参见登录实例。
在辅助测试机上,下载pktgen脚本。
确保Linux kernel中包含了pktgen module,执行modprobe pktgen
命令,加载模块。
在辅助测试机器,切换到pktgen目录,执行如下命令进行发包。
bash pktgen_sample02_multiqueue.sh -i <网卡设备名称> -d <被测试机器的私网IP地址> -s 64 -m <被测试机器的MAC地址> -c 10 -p 40000-40003 -n 0 -t <网卡队列数>
由于脚本中有如下配置,此时产生的flow总数为:(109 - 9 + 1) * (40003 - 40000 + 1) = 101 * 4 = 404。
# Flow variation random source port between min and max UDP_SRC_MIN=9 UDP_SRC_MAX=109
在被测试机器端执行sar -n DEV 1
命令,查看测试结果。
远程连接被测试机和辅助测试机,具体操作请参见登录实例。
在被测试机和辅助测试机上,执行以下命令,安装依赖软件和Pktgen-DPDK。
apt update apt install -y libpcap-dev apt install -y libnuma-dev apt-get install python3-pip -y apt install -y git pip3 install pyelftools -i https://mirrors.ivolces.com/pypi/simple/ pip3 install ninja -i https://mirrors.ivolces.com/pypi/simple/ pip3 install meson -i https://mirrors.ivolces.com/pypi/simple/
创建down-pktgen.sh
脚本,下载DPDK和Pktgen的源代码。
cd /root/;vim down-pktgen.sh
命令,创建down-pktgen.sh文件。i
,进入编辑模式。#!/bin/bash # 使用当前目录下载源代码 cur_dir=$(cd $(dirname $0); pwd) # 若dpdk文件夹不存在则下载 cd $cur_dir if [ ! -e $cur_dir/dpdk ] then git clone https://dpdk.org/git/dpdk dpdk ; echo $? fi # 若Pktgen-DPDK文件夹不存在则下载 cd $cur_dir if [ ! -e $cur_dir/Pktgen-DPDK ] then git clone https://github.com/pktgen/Pktgen-DPDK.git Pktgen-DPDK ; echo $? fi # 切换分支到pktgen-21.11.0配套分支 cd $cur_dir/dpdk ; git checkout v21.11 ; cd $cur_dir/Pktgen-DPDK ; git checkout pktgen-21.11.0 ;
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。chmod +x down-pktgen.sh
指令,赋予down-pktgen.sh
文件执行权限。bash down-pktgen.sh
命令,运行脚本。修改pktgen.c收发包引擎,优化pktgen收发包处理。
vim ./Pktgen-DPDK/app/pktgen.c +341
命令,打开pktgen.c
文件并跳到341行。i
,进入编辑模式。cnt -= ret;
的下一行增加如下代码。修改后的代码如下图所示。if (cnt != 0) { rte_delay_us(8); }
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。vim ./Pktgen-DPDK/app/pktgen.c
命令,打开pktgen.c
文件。/_64
,搜索关键字_64
。i
,进入编辑模式。info->sizes._64++;
替换为如下代码,注释本行代码。修改后的代码如下图所示。{ //info->sizes._64++; ; }
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。将./Pktgen-DPDK/app/pktgen.h
和./Pktgen-DPDK/lib/common/lscpu.c
文件中的3处fclose改为pclose。
vim ./Pktgen-DPDK/app/pktgen.h
vim ./Pktgen-DPDK/lib/common/lscpu.c
i
,进入编辑模式。./Pktgen-DPDK/app/pktgen.h
修改后如下所示。./Pktgen-DPDK/lib/common/lscpu.c
修改后如下所示。Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。修改pktgen支持32 queue。
vim ./Pktgen-DPDK/app/pktgen-constants.h +34
命令,打开./Pktgen-DPDK/app/pktgen-constants.h文件。i
,进入编辑模式。Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。说明
您也可以通过将附录中的patch文件拷贝到/root/Pktgen-DPDK
目录,执行如下命令配置git邮箱并直接打入patch,完成步骤ii、步骤iii、步骤iv的操作。
cd /root/Pktgen-DPDK git config --global user.email "you@example.com" git config --global user.name "Your Name" git am --signoff < ./0001-Optimize-performance.patch
bash /root/build-dpdk-pktgen.sh
命令,编译DPDK和Pktgen的源代码。脚本build-dpdk-pktgen.sh内容如下所示。#!/bin/bash # build-dpdk-pktgen.sh # 使用当前目录下载源代码 cur_dir=$(cd $(dirname $0); pwd) # 编译安装DPDK cd $cur_dir/dpdk ; meson build cd $cur_dir/dpdk/build ; ninja ; ninja install ; ldconfig # 编译安装Pktgen-DPDK cd $cur_dir/Pktgen-DPDK ; meson build ; ninja -C build # 检查编译结果是否生成可执行文件 ls -l $cur_dir/Pktgen-DPDK/build/app/pktgen
执行如下命令,将DPDK动态库加入到系统配置。
echo "/usr/local/lib/x86_64-linux-gnu/" >> /etc/ld.so.conf /sbin/ldconfig -v
创建bind-igbuio.sh脚本,将测试用网口绑定到igb_uio。
ethtool -i eth1
命令,获取用于DPDK测试的网卡的PCI地址。本文以DPDK测试网卡为eth1为例,回显信息如下。cd /root/;vim bind-igbuio.sh
命令,创建bind-igbuio.sh文件。i
,进入编辑模式。nic_bdf
值为步骤a查到的测试网卡PCI地址。#!/bin/bash # 指定DPDK源代码目录 dpdk_dir=/root/dpdk/ # 指定需要绑定igb_uio的网卡PCI地址 nic_bdf=0000:11:00.0 # 使用当前目录下载dpdk-kmods源代码 cur_dir=$(cd $(dirname $0); pwd) net_str=$(ls -l /sys/class/net/ | grep $nic_bdf) eth_str=${net_str##*/} # 若dpdk-kmods文件夹不存在则下载 if [ ! -e $cur_dir/dpdk-kmods/linux/igb_uio ] then git clone https://dpdk.org/git/dpdk-kmods ; echo $? fi # 编译igb_uio.ko cd $cur_dir/dpdk-kmods/linux/igb_uio/ ; make ; modprobe uio ; insmod igb_uio.ko ; echo $? ifconfig $eth_str down ; echo $? # 绑定网卡到igb_uio cd $dpdk_dir ; ./usertools/dpdk-devbind.py --bind=igb_uio $nic_bdf ; echo $?
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。chmod +x bind-igbuio.sh
指令,赋予bind-igbuio.sh文件执行权限。bash bind-igbuio.sh
命令,将测试用网口绑定到igb_uio。执行lscpu | grep 'NUMA node(s)'
命令,查询实例NUMA数;根据实例NUMA数,执行如下命令,配置大页内存。
echo 16384 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages cat /sys/kernel/mm/hugepages/hugepages-2048kB/free_hugepages
echo 16384 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages echo 16384 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages cat /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages cat /sys/devices/system/node/node0/hugepages/hugepages-2048kB/free_hugepages cat /sys/devices/system/node/node1/hugepages/hugepages-2048kB/free_hugepages
在被测试机和辅助测试机上,按如下操作运行Pktgen。
执行cd /root/;vim run.sh
命令,创建run.sh文件。
按i
,进入编辑模式。
在run.sh
文件中,输入如下内容。
#!/bin/bash pktgen_dir=/root/Pktgen-DPDK/ # 修改为您服务器上已经编译的Pktgen-DPDK源代码目录 nic_bdf=11:00.0 # 修改为您服务器上已经绑定igb_uio的网卡PCI地址 $pktgen_dir/build/app/pktgen -c 0x1ffffffff -n 4 -a $nic_bdf,speed=100000 -- -P -m "[1-32:1-32].0"
- 0xffff1:表示进程使用的CPU掩码,其中最低BIT CPU用于shell控制,其他CPU可以用于端口收发包。
- [1-32:1-32].0:表示CPU编号,该CPU编号不能超出掩码中用于收发包的CPU范围。
- 1-32(冒号前):用于收包
- 1-32(冒号后):用于发包
- .0:表示端口为0
按Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。
执行chmod +x run.sh
指令,赋予run.sh文件执行权限。
执行bash run.sh
命令,启动Pktgen。
在辅助测试机的Pktgen中,执行以下命令,启动发包。
- 按注释说明,将命令行中辅助测试机/被测试机的MAC地址、私网IP地址改为实际测试环境的MAC地址、IP地址。
- 执行以下命令前,请删除带#的注释,否则可能导致命令执行失败。
set 0 proto udp range 0 src mac start 00:16:3e:5c:xx:xx #辅助测试机器网络设备MAC地址 range 0 src mac min 00:16:3e:5c:xx:xx #辅助测试机器网络设备MAC地址 range 0 src mac inc 00:00:00:00:00:00 range 0 dst mac start 00:16:3e:3b:xx:xx #被测试机器网络设备MAC地址 range 0 dst mac min 00:16:3e:3b:xx:xx #被测试机器网络设备MAC地址 range 0 dst mac inc 00:00:00:00:00:00 range 0 src port start 10000 range 0 src port min 10000 range 0 src port max 10000 range 0 src port inc 0 range 0 dst port start 2000 range 0 dst port min 2000 range 0 dst port max 2255 range 0 dst port inc 1 range 0 proto udp range 0 src ip start 192.XX.XX.17 #辅助测试机器私网IP range 0 src ip min 192.XX.XX.17 #辅助测试机器私网IP range 0 src ip inc 0.0.0.0 range 0 size start 64 #包大小(最小为64) range 0 size min 64 range 0 size max 64 range 0 size inc 0 range 0 dst ip start 192.XX.XX.143 #被测试机器私网IP range 0 dst ip min 192.XX.XX.143 #被测试机器私网IP range 0 dst ip inc 0.0.0.0 enable all range start 0
在被测试机器Pktgen中观察收包pps和对应的bps。
将端口回绑到virtio-pci。
cd /root/;vim bind-virtio.sh
命令,创建bind-virtio.sh文件。i
,进入编辑模式。#!/bin/bash dpdk_dir=/root/dpdk/ # 修改为您的云服务器的DPDK源代码目录 nic_bdf=11:00.0 # 需改为您需要绑定igb_uio的网卡PCI地址 cd $dpdk_dir ; ./usertools/dpdk-devbind.py --unbind $nic_bdf ; echo $? rmmod igb_uio ; echo $? cd $dpdk_dir ; ./usertools/dpdk-devbind.py --bind=virtio-pci $nic_bdf ; echo $? eth_int=0 while [ "$eth_int" == "0" ] do eth_int=$(ls -l /sys/class/net/ | grep $nic_bdf | wc -l) done net_str=$(ls -l /sys/class/net/ | grep $nic_bdf) eth_str=${net_str##*/} eth_int=0 while [ "$eth_int" == "0" ] do eth_int=$(ifconfig -a | grep $eth_str | wc -l) done ifconfig $eth_str up; echo $?
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。chmod +x bind-virtio.sh
指令,赋予bind-virtio.sh文件执行权限。bash bind-virtio.sh
命令,运行脚本。远程连接被测试机和辅助测试机,具体操作请参见登录实例。
在被测试机和辅助测试机上,执行以下命令安装iperf3。
apt update apt install -y iperf3
在被测试机上创建iperf3-srv.sh文件,并添加可执行权限。
vim iperf3-srv.sh
,创建iperf3-srv.sh
文件。i
,进入编辑模式。iperf3-srv.sh
文件中,输入如下内容。#!/bin/bash # iperf3-srv.sh lcore_num=$(lscpu | grep "^CPU(s):" | awk '{ print $2; }') proc_num=$(($lcore_num < 32 ? $lcore_num : 32)) core_sibling=$(cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list) for ((i = 0; i < $proc_num ; i = i + 1)); do port=$(($i + 5201)) if [[ $lcore_num -gt 96 && $core_sibling == "0-1" ]]; then lcore=$(($i * 2)) else lcore=$(($i % $lcore_num)) fi taskset -c $lcore iperf3 -s -p $port & done
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。chmod +x iperf3-srv.sh
命令,赋予iperf3-srv.sh文件执行权限。在被测试机上,执行./iperf3-srv.sh
命令, 启动iperf3 server进程。
(可选)如果实例的网络带宽是96Gbit/s,即为c3i.48xlarge(邀测)、g3i.48xlarge(邀测)、r3i.48xlarge(邀测)或者三代裸金属实例,还需要在被测试机和辅助测试机上执行如下脚本,中断绑核。
若为其它实例则跳过此步骤。实例网络带宽数据请参见实例规格介绍。
#!/bin/bash # bind-intr.sh #stop cloud-monitor-agent service service cloud-monitor-agent stop > /dev/null 2>&1 #stop irqbalance service service irqbalance stop > /dev/null 2>&1 service irqbalance-ng stop > /dev/null 2>&1 a=$(cat /proc/interrupts | grep virtio | grep put | awk -F ':' '{print $1}') MASK="ffffffff" for irq in $a; do echo $MASK > /proc/irq/$irq/smp_affinity done
(可选)如果为搭载了第四代AMD EPYCTM Genoa处理器的裸金属实例,例如ebmg3ad/ebmc3ad,请在辅助测试机上创建如下脚本,使能xps建立txq与cpu一一映射。若为其它实例则跳过本步骤。
执行命令vim xps_setup.sh
,创建xps_setup.sh文件并添加如下内容。
#!/bin/bash # xps_setup.sh function usage() { echo "Change setting of XPS txq to CPU mapping via files" echo " /sys/class/net/DEV/queues/tx-*/xps_cpus " echo "" echo "Usage: $0 [-h] --dev ethX --txq N --cpu N" echo " -d | --dev : (\$DEV) Interface/device (required)" echo " --default : (\$DEFAULT) Setup 1:1 mapping TXQ-to-CPU" echo " --disable : (\$DISABLE) Disable XPS via mask 0x00" echo " -v | --verbose : (\$VERBOSE) verbose" echo "" } ## -- General shell logging cmds -- function err() { local exitcode=$1 shift echo -e "ERROR: $@" >&2 exit $exitcode } function info() { if [[ -n "$VERBOSE" ]]; then echo "# $@" fi } function sorted_txq_xps_cpus() { local queues=$(ls /sys/class/net/$DEV/queues/tx-*/xps_cpus | sort --field-separator='-' -k2n) echo $queues } function cpu_to_mask() { local cpu=$1 printf "%X" $((1 << $cpu)) } function xps_setup_1to1_mapping() { local cpu=0 local txq=0 for xps_cpus in $(sorted_txq_xps_cpus); do if [[ "$DISABLE" != "yes" ]]; then # Map the TXQ to CPU number 1-to-1 mask=$(cpu_to_mask $cpu) else # Disable XPS on TXQ mask=0 fi echo $mask > $xps_cpus info "NIC=$DEV TXQ:$txq use CPU $cpu (MQ-leaf :$mqleaf)" let cpu++ let txq++ done } ## --- Parse command line arguments / parameters --- while true; do case "$1" in -d | --dev ) # device export DEV=$2 info "Device set to: DEV=$DEV" >&2 shift 2 ;; -v | --verbose) export VERBOSE=yes # info "Verbose mode: VERBOSE=$VERBOSE" >&2 shift ;; --default ) info "Setup default 1-to-1 mapping TXQ-to-CPUs" >&2 export DEFAULT=yes shift 1 ;; --disable ) info "Disable XPS via mask 0x00" >&2 export DISABLE=yes shift 1 ;; -- ) shift break ;; -h | --help ) usage; exit 0 ;; * ) shift break ;; esac done if [ -z "$DEV" ]; then usage err 2 "Please specify device" fi if [[ -n "$DEFAULT" ]]; then xps_setup_1to1_mapping fi if [[ "$DISABLE" == "yes" ]]; then if [[ -z "$DEFAULT" && -z "$TXQ" ]]; then err 5 "Use --disable together with --default" fi fi
按Esc
退出编辑模式,然后输入:wq
并回车。
执行命令chmod +x xps_setup.sh
,赋予xps_setup.sh
文件执行权限。
执行命令./xps_setup.sh -d eth0 --default
,使能xps建立txq与cpu一一映射。
在辅助测试机器上创建iperf3-cli.sh
文件,并添加可执行权限。
vim iperf3-cli.sh
命令,创建iperf3-cli.sh
文件。i
,进入编辑模式。iperf3-cli.sh
文件中,输入如下内容。#!/bin/bash # iperf3-cli.sh if [ $# -ne 2 ]; then echo $0 "<server_ip> <time_secs>" exit 255 fi lcore_num=$(lscpu | grep "^CPU(s):" | awk '{ print $2; }') proc_num=$(($lcore_num < 32 ? $lcore_num : 32)) core_sibling=$(cat /sys/devices/system/cpu/cpu0/topology/thread_siblings_list) for ((i=0 ; i < $proc_num; i = i + 1)); do port=$(($i + 5201)) #check instance is 192C vm if [[ $lcore_num -gt 96 && $core_sibling == "0-1" ]]; then lcore=$(($i * 2)) else lcore=$(($i % $lcore_num)) fi taskset -c $lcore iperf3 -c $1 -p $port -t $2 -P 4 2>&1 & done
Esc
退出编辑模式,输入:wq
并按下Enter
键,保存并退出文件。chmod +x iperf3-cli.sh
命令,赋予iperf3-cli.sh文件执行权限。在辅助测试机器执行如下命令,启动iperf3 client进程。
./iperf3-cli.sh <被测机器私有IP> 300
在被测试机器端执行sar -n DEV 1
,查看结果,下图中rxkB/s
列的数据即为接收带宽。
单位换算: [rxkB/s] * 8 * 1024 / 1000000000=Gbps
在被测试机和辅助测试机上执行以下命令,安装cpupower。
apt update apt install -y linux-intel-iotg-tools-common linux-tools-5.15.0-48-generic
在安装linux-tools-5.15.0-48-generic时,可能会报如下错误信息:
该报错是因为工具/usr/bin/acpidbg
在第1个安装包linux-intel-iotg-tools-common已经安装。可执行如下命令(linux-tools-common版本号使用错误提示中的版本号),强制覆盖安装红框的指定的包解决。
dpkg -i --force-overwrite /var/cache/apt/archives/linux-tools-common_5.15.0-66.73_all.deb
在被测试机和辅助测试机上执行以下命令,设置所有CPU为性能模式。
cpupower -c all frequency-set -g performance
在测试机上,执行以下命令,测试网络时延。
min表示最小时延,avg表示平均时延,max表示最大时延,单位为ms。
ping -f -c 10000 <辅助测试机私网IP地址>