iperf可用于测试两个计算机之间的网络带宽和延迟。它是一个开源项目,提供了用于Windows、Linux和其他操作系统的版本。通过在两台计算机之间运行iPerf服务器和客户端,您可以测量它们之间的网络性能。iPerf客户端发送数据流到服务器,并且服务器测量接收到的数据量和速度,支持在TCP和UDP协议上运行。
本文将详细介绍如何使用 iperf3 工具,测试弹性云主机间网络性能。内容主要包括“测试前准备”、“TCP 带宽测试”、“UDP PPS 测试”。
安装使用
[root@ss-daliu1 ~]# sudo yum install iperf3
[root@ss-daliu2 ~]# sudo yum install iperf3
参数说明
iperf常用参数中文说明:
(1)-s,–server:iperf服务器模式,默认启动的监听端口为5201,eg:iperf -s
(2)-c,–client host:iperf客户端模式,host是server端地址,eg:iperf -c 222.35.11.23
(3)-i,–interval:指定每次报告之间的时间间隔,单位为秒,eg:iperf3 -c 192.168.12.168 -i 2
(4)-p,–port:指定服务器端监听的端口或客户端所连接的端口,默认是5001端口。
(5)-u,–udp:表示采用UDP协议发送报文,不带该参数表示采用TCP协议。
(6)-l,–len:设置读写缓冲区的长度,(default 128 KB for TCP, dynamic or 1 for UDP)。通常测试 PPS 的时候该值为16,测试BPS时该值为1400。
(7)-b,–bandwidth [K|M|G]:指定UDP模式使用的带宽,单位bits/sec,默认值是1 Mb/s。
(8)-t,–time:指定数据传输的总时间,即在指定的时间内,重复发送指定长度的数据包。默认10秒。
(9)-A:CPU亲和性,可以将具体的iperf3进程绑定对应编号的逻辑CPU,避免iperf进程在不同的CPU间调度。
通用参数(Server端和Client端共用):
(1)-f,–format [k|m|g|K|M|G]:指定带宽输出单位,“[k|m|g|K|M|G]”分别表示以Kb, Mb, Gb, KBytes, MBytes,GBytes显示输出结果,默认Mb,eg:iperf3 -c 192.168.12.168 -f M
(2)-p,–port:指定服务器端监听的端口或客户端所连接的端口,默认是5001端口。
(3)-i,–interval:指定每次报告之间的时间间隔,单位为秒,eg:iperf3 -c 192.168.12.168 -i 2
(4)-F:指定文件作为数据流进行带宽测试。例如:iperf3 -c 192.168.12.168 -F web-ixdba.tar.gz
Server端专用参数:
(1)-s,–server:iperf服务器模式,默认启动的监听端口为5201,eg:iperf -s
(2)-c,–client host:如果iperf运行在服务器模式,并且用-c参数指定一个主机,那么iperf将只接受指定主机的连接。此参数不能工作于UDP模式。
(3)-D:Unix平台下将Iperf作为后台守护进程运行。在Win32平台下,Iperf将作为服务运行。
(4)-R:卸载Iperf服务(仅用于Windows)。
(5)-o:重定向输出到指定文件(仅用于Windows)。
(6)-P,–parallel:服务器关闭之前保持的连接数。默认是0,这意味着永远接受连接。
Client端专用参数:
(1)-c,–client host:iperf客户端模式,host是server端地址,eg:iperf -c 222.35.11.23
(2)-u,–udp:表示采用UDP协议发送报文,不带该参数表示采用TCP协议。
(3)-b,–bandwidth [K|M|G]:指定UDP模式使用的带宽,单位bits/sec,默认值是1 Mbit/sec。
(4)-t,–time:指定数据传输的总时间,即在指定的时间内,重复发送指定长度的数据包。默认10秒。
(5)-l,–len:设置读写缓冲区的长度,(default 128 KB for TCP, dynamic or 1 for UDP)。通常测试 PPS 的时候该值为16,测试BPS时该值为1400。
(6)-n,–num [K|M|G]:指定传输数据包的字节数,例如:iperf3 -c 192.168.12.168 –n 100M
(7)-P,–parallel:指定客户端与服务端之间使用的线程数。默认是1个线程。需要客户端与服务器端同时使用此参数。
(8)-w,–window:指定套接字缓冲区大小,在TCP方式下,此设置为TCP窗口的大小。在UDP方式下,此设置为接受UDP数据包的缓冲区大小,用来限制可以接收数据包的最大值
(9)-B,–bind:用来绑定一个主机地址或接口,这个参数仅用于具有多个网络接口的主机。在UDP模式下,此参数用于绑定和加入一个多播组。
(10)-M,–mss:设置TCP最大信息段的值
(11)-N,–nodelay:设置TCP无延时
(12)-V:绑定一个IPv6地址。
(13)-d,–dualtest:运行双测试模式。将使服务器端反向连接到客户端,使用-L参数中指定的端口(或默认使用客户端连接到服务器端的端口)。使用参数-r以运行交互模式。
(14)-L,–listenport:指定服务端反向连接到客户端时使用的端口。默认使用客户端连接至服务端的端口。
(15)-r,–tradeoff:往复测试模式。当客户端到服务器端的测试结束时,服务器端反向连接至客户端。当客户端连接终止时,反向连接随即开始。如果需要同时进行双向测试,请尝试-d参数。
一对一场景
测试准备
类型 | 数量 | 镜像 | 规格 |
---|---|---|---|
被测机(被测机:被压力测试网络性能的弹性云服务器,可作为 iperf3 测试中的 client 端(发送端)) | 1台 | CTyunOS 23.01(推荐) | 4C8G(推荐) |
辅助云服务器(作为 iperf3 测试中的 server 端(接收端)) | 1台 | CTyunOS 23.01(推荐) | 4C8G(推荐) |
准备两台处于不同计算节点的弹性云主机,网络可达,分别安装iperf,添加对应的安全组规则、防护墙规则放行。
测试TCP吞吐量
-
TCP发送带宽。
# Server端开启iperf的服务器模式,指定TCP端口:10000,安全组规则入方向放行TCP 10000端口 [root@ss-daliu2 ~]# iperf3 -s -i 1 -p 10000 ----------------------------------------------------------- Server listening on 10000 (test #1) # Client端启动iperf的客户端模式,连接服务端。ip为server端地址 [root@ss-daliu1 ~]# iperf3 -c 192.168.0.15 -i 1 -t 60 -p 10000 Connecting to host 192.168.0.15, port 10000 [ 5] local 192.168.0.8 port 37720 connected to 192.168.0.15 port 10000 [ ID] Interval Transfer Bitrate Retr Cwnd [ 5] 0.00-1.00 sec 332 MBytes 2.78 Gbits/sec 4394 167 KBytes ... ... ... [ 5] 52.00-53.00 sec 180 MBytes 1.51 Gbits/sec 6546 130 KBytes [ 5] 53.00-54.00 sec 166 MBytes 1.39 Gbits/sec 5237 180 KBytes [ 5] 54.00-55.00 sec 166 MBytes 1.40 Gbits/sec 5505 19.8 KBytes [ 5] 55.00-56.00 sec 207 MBytes 1.74 Gbits/sec 7651 12.7 KBytes [ 5] 56.00-57.00 sec 167 MBytes 1.40 Gbits/sec 5822 314 KBytes [ 5] 57.00-58.00 sec 168 MBytes 1.41 Gbits/sec 5952 58.0 KBytes [ 5] 58.00-59.00 sec 178 MBytes 1.49 Gbits/sec 6940 372 KBytes [ 5] 59.00-60.00 sec 205 MBytes 1.72 Gbits/sec 6756 2.83 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec 343419 sender [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec receiver
结果说明:
Interval表示时间间隔。
Transfer表示时间间隔里面转输的数据量。
Bitrate是时间间隔里的传输速率。 -
TCP接收带宽。
# Server端开启iperf的服务器模式,指定TCP端口:10000,安全组规则入方向放行TCP 10000端口 [root@ss-daliu2 ~]# iperf3 -s -i 1 -p 10000 ----------------------------------------------------------- Server listening on 10000 (test #1) # Client端启动iperf的客户端模式,连接服务端。ip为server端地址 [root@ss-daliu1 ~]# iperf3 -c 192.168.0.15 -i 1 -t 60 -p 10000 -R Connecting to host 192.168.0.15, port 10000 Reverse mode, remote host 192.168.0.15 is sending [ 5] local 192.168.0.8 port 38316 connected to 192.168.0.15 port 10000 [ ID] Interval Transfer Bitrate [ 5] 0.00-1.00 sec 336 MBytes 2.81 Gbits/sec [ 5] 1.00-2.00 sec 172 MBytes 1.45 Gbits/sec ... ... ... [ 5] 59.00-60.00 sec 179 MBytes 1.50 Gbits/sec - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec 360910 sender [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec receiver
结果说明:
Interval表示时间间隔。
Transfer表示时间间隔里面转输的数据量。
Bitrate是时间间隔里的传输速率。 -
TCP上下行带宽测试(双向传输)。
# Server端开启iperf的服务器模式,指定TCP端口:10000,安全组规则入方向放行TCP 10000端口 [root@ss-daliu2 ~]# iperf3 -s -i 1 -p 10000 ----------------------------------------------------------- Server listening on 10000 (test #1) # Client端启动iperf的客户端模式,连接服务端。ip为server端地址 [root@ss-daliu1 ~]# iperf3 -c 192.168.0.15 -i 1 -d -t 60 -p 10000 ... Thread FD 5 stopped Sender threads stopped tcpi_snd_cwnd 335 tcpi_snd_mss 1448 tcpi_rtt 1054 send_results { "cpu_util_total": 4.7314293702543742, "cpu_util_user": 0.0694572749595791, "cpu_util_system": 4.6619720952947947, "sender_has_retransmits": 1, "congestion_used": "cubic", "streams": [{ "id": 1, "bytes": 11446517760, "retransmits": 354575, "jitter": 0, "errors": 0, "omitted_errors": 0, "packets": 0, "omitted_packets": 0, "start_time": 0, "end_time": 60.00129 }] } get_results { "cpu_util_total": 3.3835424728514676, "cpu_util_user": 0.14802798323701713, "cpu_util_system": 3.2355161562396457, "sender_has_retransmits": -1, "congestion_used": "cubic", "streams": [{ "id": 1, "bytes": 11442323456, "retransmits": -1, "jitter": 0, "errors": 0, "omitted_errors": 0, "packets": 0, "omitted_packets": 0, "start_time": 0, "end_time": 60.00149 }] } interval_len 1.000265 bytes_transferred 176291840 interval forces keep [ 5] 59.00-60.00 sec 168 MBytes 1.41 Gbits/sec 5895 474 KBytes - - - - - - - - - - - - - - - - - - - - - - - - - [ ID] Interval Transfer Bitrate Retr [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec 354575 sender [ 5] 0.00-60.00 sec 10.7 GBytes 1.53 Gbits/sec receiver Receiver threads stopped iperf Done. # 测试4线程TCP吞吐量,如果没有指定发送方式,iperf客户端只会使用单线程。 $ iperf3 -c 172.16.0.9 -i 1 -P 4 -t 60 -p 10000
结果说明:
Interval表示时间间隔。
Transfer表示时间间隔里面转输的数据量。
Bitrate是时间间隔里的传输速率。
测试UDP吞吐量
带宽测试通常采用UDP模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为100Mbps,先用-b 100M进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。
# Server端开启iperf的服务器模式,指定UDP端口:
[root@ss-daliu2 ~]# iperf3 -s -i 1 -p 10001
-----------------------------------------------------------
Server listening on 10001
-----------------------------------------------------------
# Client端启动iperf的客户端模式,连接服务端
[root@ss-daliu1 ~]# iperf3 -u -c 192.168.0.15 -b 100m -t 60 -p 10001
Connecting to host 172.16.0.9, port 10001
[ 4] local 172.16.0.2 port 46011 connected to 172.16.0.9 port 10001
[ ID] Interval Transfer Bandwidth Total Datagrams
[ 4] 0.00-1.00 sec 10.8 MBytes 90.3 Mbits/sec 7799
...
[ 4] 58.00-59.00 sec 11.9 MBytes 100 Mbits/sec 8640
[ 4] 59.00-60.00 sec 11.9 MBytes 99.9 Mbits/sec 8625
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Jitter Lost/Total Datagrams
[ 4] 0.00-60.00 sec 714 MBytes 99.8 Mbits/sec 0.001 ms 133914/517118 (26%)
[ 4] Sent 517118 datagrams
iperf Done.
# 测试多线程UDP吞吐量
$ iperf3 -u -c 192.168.0.15 -b 5m -P 4 -t 60 -p 10001
# 进行上下行带宽测试(双向传输)
$ iperf3 -u -c 192.168.0.15 -b 100M -d -t 60 -p 10001
结果说明:
jitter为抖动,在连续传输中的平滑平均值差。
Lost为丢包数量。
Total Datagrams为包数量。
iperf测试udp丢包严重:可以尝试增大收发包缓冲区。
echo 16777216 > /proc/sys/net/core/rmem_max
echo 16777216 > /proc/sys/net/core/rmem_default
echo 16777216 > /proc/sys/net/core/wmem_max
echo 16777216 > /proc/sys/net/core/wmem_default
多流打流测试方案(针对大规格云主机)
针对大规格云主机,单进程打流可能无法发挥出云主机的性能,可以参考下述多流打流测试方案。
虚机网络性能说明
虚机从同⼀个队列发出的报文,在底层只能被⼀个cpu转发。即虚机⼀个队列的发包性能 <= 虚拟交换机单核转发性能。
性能测试步骤
-
确定两个⽤于性能测试的计算节点: A, B.
-
.在每个计算节点上分别创建2个虚机,虚机规格尽量大,虚机内核版本4.19及以上(建议使用CTyunOS 23.01)。
-
4个测试虚机内安装iperf3包
yum install iperf3
-
B计算节点上的两个虚机(B1, B2)分别起iperf服务端:
for i in {0..63}; do iperf3 -s -D -p $((5200 + $i)) ; done
-
A计算节点上两个虚机(A1, A2)起iperf客户端(A1给B1发包, A2给B2发包):
创建发包脚本:#!/usr/bin/env bash flow_per_thread=2 max_thread=64 run_time=60 udp_opts="-u" # 默认用全力(100G)发送udp报文, 但可能存在丢包. udp_band_Mb=100000 tcp_opts="" use_tcp=1 usage() { echo ' usage: $0 -s <server-ip> [--pps] [-n <nprocess>] [-t <time>] [--tcp] -s Iperf server ip address. --pps Send small pkts for pps benchmark. By default send large pkts for bandwidth benckmark. -n Set max process number. If not set, tx queue number is used. -t time in seconds to transmit for, default 60 seconds. --udp Send udp instead of tcp(default). Udp is good for some special scenarios. -b Bandwidth to send for udp mode. i.e. 1M, 2G, ' } while [ $# -gt 0 ]; do case $1 in -s | --server) server="$2" shift ;; -n | --nprocess) max_thread="$2" shift ;; -t | --time) run_time="$2" shift ;; --pps) # 144 bytes tcp_opts="$tcp_opts -M 90" # 18(eth) + 28(ip) + 18(udp) = 64 udp_opts="$udp_opts -l 18" ;; --udp) use_tcp=0 ;; -b) udp_band="$2" _unit=$(echo $udp_band | grep -oiP '\d+\K[mg]') _num=$(echo $udp_band | grep -oP '\d+') if [ -z "$_unit" ] || [ -z "$_num" ];then echo "bad bandwidth" exit 1 fi if [ ${_unit,,} == 'g' ];then _num=$((_num*1024)) fi udp_band_Mb=$_num ;; -h | --help) usage exit 0 ;; *) usage exit 1 ;; esac shift done interface=$(ip route get $server |grep -oP "(?<=dev )\S+") n_txq=$(ls /sys/class/net/$interface/queues/tx-*/xps_cpus | wc -l) band_per_flow=$((udp_band_Mb/flow_per_thread/max_thread)) i=0 for fxps in `ls /sys/class/net/$interface/queues/tx-*/xps_cpus | sort` do aff=$(cat $fxps) if ((i >= max_thread));then break fi no_zero_aff=$(echo "$aff" | tr -d '0xX') if [ -z "$no_zero_aff" ];then _aff=$((1 << $i)) aff=$(printf "%x" $_aff) echo $aff > $fxps fi # Affinity on only one core suffix="" for (( j=${#aff}-1; j>=0; j-- )); do if [ "${aff:$j:1}" == "," ];then continue fi if [ "${aff:$j:1}" != "0" ];then aff_one="${aff:$j:1}${suffix}" break fi suffix+="0" done if [ -z "$aff_one" ];then echo "Failed to find txq affinity core" exit 1 fi aff_one=`echo $aff_one | tr '13579bdf' '1' | tr '26ae' '2' | tr '4c' '4'` if ((use_tcp > 0)) ;then taskset $aff_one iperf3 -c $server $tcp_opts -P 2 -p $((5200+$i)) -t $run_time & else taskset $aff_one iperf3 -c $server $udp_opts -b ${udp_band_Mb}M -P 2 -p $((5200+$i)) -t $run_time & fi ((i++)) done wait
测试pps(144B/64B小包)
bash iperf-client.sh -s <B1-ip> --pps -t 300
测试带宽(1500B大包)
bash iperf-client.sh -s <B1-ip> -t 300
- 打流的过程中虚拟交换机会根据流量做balance,所以我们流量测试应持续5分钟。等待底层balance到最佳状态,以得到较好的性能结果。