前言

为了解决 LVS ksoftirqd CPU 使用率 100% 软中断导致网卡丢包的问题,我们使用 netperf 来测试网络性能,目的是尽可能复现问题,在研究的过程中顺便记录自己使用 netperf 的过程,除了 netperf 之外还可以使用 iperf 作为 TCP/UDP 压力测试工具。

netperf 和 iperf 网络性能测试小结

更新历史

2019 年 06 月 27 日 - 初稿

阅读原文 - https://wsgzao.github.io/post/netperf/

扩展阅读

netperf - https://github.com/HewlettPackard/netperf
iperf - https://github.com/esnet/iperf


网络性能测量的五项指标

可用性(availability)
响应时间(response time)
网络利用率(network utilization)
网络吞吐量(network throughput)
网络带宽容量(network bandwidth capacity)

可用性

测试网络性能的第一步是确定网络是否正常工作,最简单的方法是使用 ping 命令。通过向远端的机器发送 icmp echo request,并等待接收 icmp echo reply 来判断远端的机器是否连通,网络是否正常工作。

Ping 命令有非常丰富的命令选项,比如 -c 可以指定发送 echo request 的个数,-s 可以指定每次发送的 ping 包大小。

网络设备内部一般有多个缓冲池,不同的缓冲池使用不同的缓冲区大小,分别用来处理不同大小的分组(packet)。例如交换机中通常具有三种类型的包缓冲:一类针对小的分组,一类针对中等大小的分组,还有一类针对大的分组。为了测试这样的网络设备,测试工具必须要具有发送不同大小分组的能力。Ping 命令的 -s 就可以使用在这种场合。

响应时间

Ping 命令的 echo request/reply 一次往返所花费时间就是响应时间。有很多因素会影响到响应时间,如网段的负荷,网络主机的负荷,广播风暴,工作不正常的网络设备等等。

在网络工作正常时,记录下正常的响应时间。当用户抱怨网络的反应时间慢时,就可以将现在的响应时间与正常的响应时间对比,如果两者差值的波动很大,就能说明网络设备存在故障。

网络利用率

网络利用率是指网络被使用的时间占总时间(即被使用的时间 + 空闲的时间)的比例。比如,Ethernet 虽然是共享的,但同时却只能有一个报文在传输。因此在任一时刻,Ethernet 或者是 100% 的利用率,或者是 0% 的利用率。

计算一个网段的网络利用率相对比较容易,但是确定一个网络的利用率就比较复杂。因此,网络测试工具一般使用网络吞吐量和网络带宽容量来确定网络中两个节点之间的性能。

网络吞吐量

网络吞吐量是指在某个时刻,在网络中的两个节点之间,提供给网络应用的剩余带宽。

网络吞吐量可以帮助寻找网络路径中的瓶颈。比如,即使 client 和 server 都被分别连接到各自的 100M Ethernet 上,但是如果这两个 100M 的 Ethernet 被 10M 的 Ethernet 连接起来,那么 10M 的 Ethernet 就是网络的瓶颈。

网络吞吐量非常依赖于当前的网络负载情况。因此,为了得到正确的网络吞吐量,最好在不同时间(一天中的不同时刻,或者一周中不同的天)分别进行测试,只有这样才能得到对网络吞吐量的全面认识。

有些网络应用程序在开发过程的测试中能够正常运行,但是到实际的网络环境中却无法正常工作(由于没有足够的网络吞吐量)。这是因为测试只是在空闲的网络环境中,没有考虑到实际的网络环境中还存在着其它的各种网络流量。所以,网络吞吐量定义为剩余带宽是有实际意义的。

网络带宽容量

与网络吞吐量不同,网络带宽容量指的是在网络的两个节点之间的最大可用带宽。这是由组成网络的设备的能力所决定的。

测试网络带宽容量有两个困难之处:在网络存在其它网络流量的时候,如何得知网络的最大可用带宽;在测试过程中,如何对现有的网络流量不造成影响。网络测试工具一般采用 packet pairs 和 packet trains 技术来克服这样的困难。

收集网络性能数据的方式

当确定了网络性能的测试指标以后,就需要使用网络测试工具收集相应的性能数据,分别有三种从网络获取数据的方式:

  1. 通过 snmp 协议直接到网络设备中获取,如 net-snmp 工具
  2. 侦听相关的网络性能数据,典型的工具是 tcpdump
  3. 自行产生相应的测试数据,即本文中介绍的 iperf、netperf 等工具

Netperf

Netperf 是一种网络性能的测量工具,主要针对基于 TCP 或 UDP 的传输。Netperf 根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求 / 应答(request/reponse)模式。

参数 说明
-H host 指定远端运行 netserver 的 server IP 地址
-l testlen 指定测试的时间长度 (秒)
-t testname 指定进行的测试类型 (TCP_STREAM,UDP_STREAM,TCP_RR,TCP_CRR,UDP_RR)

可选参数有如下几个:

参数 说明
-s size 设置本地系统的 socket 发送与接收缓冲大小
-S size 设置远端系统的 socket 发送与接收缓冲大小
-m size 设置本地系统发送测试分组的大小
-M size 设置远端系统接收测试分组的大小
-D 对本地与远端系统的 socket 设置 TCP_NODELAY 选项
-r req,resp 设置 request 和 reponse 分组的大小

实例:

服务器端:

1
#./netserver

客户端:

1、批量 (bulk) 网络流量的性能

1)TCP_STREAM

Netperf 缺省情况下进行 TCP 批量传输,即 - t TCP_STREAM。测试过程中,netperf 向 netserver 发送批量的 TCP 数据分组,以确定数据传输过程中的吞吐量:

1
2
3
4
5
6
7
#./netperf -H 192.168.0.28 -l 60
TCP STREAM TEST to 192.168.0.28
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 16384 60.00 88.00

从 netperf 的结果输出中,我们可以知道以下的一些信息:

  1. 远端系统(即 server)使用大小为 87380 字节的 socket 接收缓冲
  2. 本地系统(即 client)使用大小为 16384 字节的 socket 发送缓冲
  3. 向远端系统发送的测试分组大小为 16384 字节
  4. 测试经历的时间为 60 秒
  5. 吞吐量的测试结果表明,TCP 带宽为 88Mbits / 秒

通过修改可选参数,并观察结果的变化,我们可以确定是什么因素影响了连接的吞吐量。例如,如果怀疑路由器由于缺乏足够的缓冲区空间,使得转发大的分组时存在问题,就可以增加测试分组(-m)的大小,以观察吞吐量的变化:

1
2
3
4
5
6
7
#./netperf -H 192.168.0.28 -l 60 -- -m 2048
TCP STREAM TEST to 192.168.0.28
Recv Send Send
Socket Socket Message Elapsed
Size Size Size Time Throughput
bytes bytes bytes secs. 10^6bits/sec
87380 16384 2048 60.00 87.62

在这里,测试分组的大小减少到 2048 字节,而吞吐量却没有很大的变化(与前面例子中测试分组大小为 16K 字节相比)。相反,如果吞吐量有了较大的提升,则说明在网络中间的路由器确实存在缓冲区的问题。

2)UDP_STREAM

UDP_STREAM 用来测试进行 UDP 批量传输时的网络性能。需要特别注意的是,此时测试分组的大小不得大于 socket 的发送与接收缓冲大小,否则 netperf 会报出错提示:

1
2
3
#./netperf -t UDP_STREAM -H 192.168.0.28 -l 60
UDP UNIDIRECTIONAL SEND TEST to 192.168.0.28
udp_send: data send error: Message too long

为了避免这样的情况,可以通过命令行参数限定测试分组的大小,或者增加 socket 的发送 / 接收缓冲大小。UDP_STREAM 方式使用与 TCP_STREAM 方式相同的局部命令行参数,因此,这里可以使用 - m 来修改测试中使用分组的大小:

1
2
3
4
5
6
7
#./netperf -t UDP_STREAM -H 192.168.0.28 -- -m 1024
UDP UNIDIRECTIONAL SEND TEST to 192.168.0.28
Socket Message Elapsed Messages
Size Size Time Okay Errors Throughput
bytes bytes secs # # 10^6bits/sec
65535 1024 9.99 114127 0 93.55
65535 9.99 114122 93.54

UDP_STREAM 方式的结果中有两行测试数据
第一行显示的是本地系统的发送统计,这里的吞吐量表示 netperf 向本地 socket 发送分组的能力。但是,我们知道,UDP 是不可靠的传输协议,发送出去的分组数量不一定等于接收到的分组数量。

第二行显示的就是远端系统接收的情况,由于 client 与 server 直接连接在一起,而且网络中没有其它的流量,所以本地系统发送过去的分组几乎都被远端系统正确的接收了,远端系统的吞吐量也几乎等于本地系统的发送吞吐量。但是,在实际环境中,一般远端系统的 socket 缓冲大小不同于本地系统的 socket 缓冲区大小,而且由于 UDP 协议的不可靠性,远端系统的接收吞吐量要远远小于发送出去的吞吐量。

2、请求 / 应答 (request/response) 网络流量的性能

另一类常见的网络流量类型是应用在 client/server 结构中的 request/response 模式。在每次交易(transaction)中,client 向 server 发出小的查询分组,server 接收到请求,经处理后返回大的结果数据。

1) TCP_RR

TCP_RR 方式的测试对象是多次 TCP request 和 response 的交易过程,但是它们发生在同一个 TCP 连接中,这种模式常常出现在数据库应用中。数据库的 client 程序与 server 程序建立一个 TCP 连接以后,就在这个连接中传送数据库的多次交易过程。 用户可以通过 - r 参数来改变 request 和 response 分组的大小,进行更有实际意义的测试:

1
2
3
4
5
6
7
8
#./netperf -t TCP_RR -H 192.168.0.28 -- -r 32,1024
TCP REQUEST/RESPONSE TEST to 192.168.0.28
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
16384 87380 32 1024 10.00 4945.97
16384 87380

从结果中可以看出,增加 request/reponse 分组的大小,会导致交易率明显的下降。
注:相对于实际的系统,这里交易率的计算没有充分考虑到交易过程中的应用程序处理时延,因此结果往往会高于实际情况

2) TCP_CRR

与 TCP_RR 不同,TCP_CRR 为每次交易建立一个新的 TCP 连接。最典型的应用就是 HTTP,每次 HTTP 交易是在一条单独的 TCP 连接中进行的。因此,由于需要不停地建立新的 TCP 连接,并且在交易结束后拆除 TCP 连接,交易率一定会受到很大的影响。

1
2
3
4
5
6
7
8
#./netperf -t TCP_CRR -H 192.168.0.28
TCP Connect/Request/Response TEST to 192.168.0.28
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
131070 131070 1 1 9.99 2662.20
16384 87380

即使是使用一个字节的 request/response 分组,交易率也明显的降低了,只有 2662.20 次 / 秒。

3) UDP_RR

UDP_RR 方式使用 UDP 分组进行 request/response 的交易过程。由于没有 TCP 连接所带来的负担,所以我们推测交易率一定会有相应的提升。

1
2
3
4
5
6
7
8
#./netperf -t UDP_RR -H 192.168.0.28
UDP REQUEST/RESPONSE TEST to 192.168.0.28
Local /Remote
Socket Size Request Resp. Elapsed Trans.
Send Recv Size Size Time Rate
bytes Bytes bytes bytes secs. per sec
65535 65535 1 1 9.99 10141.16
65535 65535

结果证实了我们的推测,交易率为 10141.16 次 / 秒,高过 TCP_RR 的数值。不过,如果出现了相反的结果,即交易率反而降低了,也不需要担心,因为这说明了在网络中,路由器或其它的网络设备对 UDP 采用了与 TCP 不同的缓冲区空间和处理技术。

iperf

iperf 是一个网络性能测试工具。iperf 可以测试最大 TCP 和 UDP 带宽性能,具有多种参数和 UDP 特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。
0
客户端与服务器共用选项

命令行选项 描述
-u –udp:使用 UDP 方式而不是 TCP 方式。需要客户端与服务器端同时使用此参数。
-p –port : 设置端口,与服务器端的监听端口一致。默认是 5001 端口。
-l –len : 设置读写缓冲区的长度。TCP 方式默认为 8KB,UDP 方式默认为 1470 字节。
-w –window : 设置套接字缓冲区为指定大小。对于 TCP 方式,此设置为 TCP 窗口大小。对于 UDP 方式,此设置为接受 UDP 数据包的缓冲区大小,限制可以接受数据包的最大值。
-m –print_mss : 输出 TCP MSS 值(通过 TCP_MAXSEG 支持)。MSS 值一般比 MTU 值小 40 字节。通常情况

服务器端专用选项

命令行选项 描述
-s –server : iperf 服务器模式
-c –client host : 如果 iperf 运行在服务器模式,并且用 - c 参数指定一个主机,那么 iperf 将只接受指定主机的连接。此参数不能工作于 UDP 模式。
-P –parallel: 服务器关闭之前保持的连接数。默认是 0,这意味着永远接受连接。

客户端端专用选项

命令行选项 描述
-c –client host : 运行 iperf 的客户端模式,连接到指定的 iperf 服务器端。
-b –bandwidth :UDP 模式使用的带宽,必须配合 - u 参数,默认值是 1 Mbit/sec。
-d –dualtest : 运行双测试模式。这将使服务器端反向连接到客户端,使用 - L 参数中指定的端口(或默认使用客户端连接到服务器端的端口)。这些在操作的同时就立即完成了。如果你想要一个交互的测试,请尝试 - r 参数。
-r –tradeoff : 往复测试模式。当客户端到服务器端的测试结束时,服务器端通过 - l 选项指定的端口(或默认为客户端连接到服务器端的端口),反向连接至客户端。当客户端连接终止时,反向连接随即开始。如果需要同时进行双向测试,请尝试 - d 参数。
-L –listenport : 指指定服务端反向连接到客户端时使用的端口。默认使用客户端连接至服务端的端口。
-t –time : 设置传输的总时间。iperf 在指定的时间内,重复的发送指定长度的数据包。默认是 10 秒钟。
-P –parallel: 线程数。指定客户端与服务端之间使用的线程数。默认是 1 线程。需要客户端与服务器端同时使用此参数。

实例

带宽测试通常采用 UDP 模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为 100Mbps,先用 - b 100M 进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。

UDP 模式

服务器端:

1
iperf -u -s

客户端:

1
2
3
4
5
6
7
8
/* 在 udp 模式下,以 100Mbps 为数据发送速率,客户端到服务器 192.168.1.1 上传带宽测试,测试时间为 60 秒 */
iperf -u -c 192.168.1.1 -b 100M -t 60

/* 客户端以 5Mbps 为数据发送速率, 同时向服务器端发起 30 个连接线程 */
iperf -u -c 192.168.1.1 -b 5M -P 30 -t 60

/* 以 100M 为数据发送速率,进行上下行带宽测试,-L 参数指定本端双测试监听的端口 */
iperf -u -c 192.168.1.1 -b 100M -d -t 60 -L 30000

TCP 模式

服务器端:

1
iperf -s

客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* 在 tcp 模式下,客户端到服务器 192.168.1.1 上传带宽测试,测试时间为 60 秒 */
iperf -c 192.168.1.1 -t 60

/* 进行上下行带宽测试 */
iperf -c 192.168.1.1 -d -t 60

/* 测试单线程 TCP*/
iperf –c 192.168.1.1 –p 12345 –i 1 –t 10 –w 20K

-c:客户端模式,后接服务器 ip
-p:后接服务端监听的端口
-i:设置带宽报告的时间间隔,单位为秒
-t:设置测试的时长,单位为秒
-w:设置 tcp 窗口大小,一般可以不用设置,默认即可

对应服务器端:
iperf –s –p 12345 –i 1 –t 10 –m -y

/* 测试多线程 TCP: 客户端同时向服务器端发起 30 个连接线程 */
iperf -c 192.168.1.1 -P 30 -t 60

发包完成后,可以通过 ifconfig ethx 和 ethtool -S ethx 查看对应收发包情况,确定发包数、包长、是否丢包等。

Netperf 测试实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# install netperf
wget -c "https://codeload.github.com/HewlettPackard/netperf/tar.gz/netperf-2.7.0" -O netperf-2.7.0.tar.gz
tar -zxvf netperf-2.7.0.tar.gz
cd netperf-netperf-2.7.0
./configure && make && make install

# add path
vim ~/.bash_profile
PATH=$PATH:/usr/local/bin/

source ~/.bash_profile

# test
cd src
netperf -h
netserver -h

# server
netserver -4 -p 7777
ps -ef | grep netserver

# client
netperf -H 10.71.14.122 -p 7777 -l 60

netperf -t TCP_RR -H 10.71.14.122 -p 7777 -c -C -l 60
netperf -t TCP_RR -H 10.71.14.122 -p 7777 -c -C -l 60 -- -r256,256

# check result
bmon
mpstat -P ALL 2

参考文章

netperf 与网络性能测量
网络性能测试方法

文章目录
  1. 1. 前言
  2. 2. 更新历史
  3. 3. 网络性能测量的五项指标
    1. 3.1. 可用性
    2. 3.2. 响应时间
    3. 3.3. 网络利用率
    4. 3.4. 网络吞吐量
    5. 3.5. 网络带宽容量
    6. 3.6. 收集网络性能数据的方式
  4. 4. Netperf
  5. 5. iperf
    1. 5.1. 实例
  6. 6. Netperf 测试实践
  7. 7. 参考文章