Preference:
问题1 单个小包最小bytes数是多少?
问题2 1Gb(1G bits)带宽理论上f/s(frame/s)的范围是多少?
问题3 1Gb的网卡如何发小包接近其理论最大pps?
解答:
问题1 :
数据包的字节数:dmac(6 bytes) + smac(6 bytes) + vlan_header(4 bytes, options) + proto_type(2 bytes) + Playload (46 – 1500 bytes) + FCS(4 bytes) + 包前置字节(8 bytes) + 包间隙(12 bytes) ,所以一个不带vlan的数据包长度范围:64 bytes – 1518 bytes(不包括包前置字节和包间隙)。单个最小数据帧长度为: 84 bytes – 1538 bytes。
问题2:
带宽的基本单位通常为 bit/s
1Gb = 1024 Mb = 1024 * 1024 Kb = 1024 * 1024 * 1024 bytes = 1073741824 bytes。 f/s 范围: 1Gbits/ 84 * 8 bits = 1Gbits/672 bits = 1597830 f/s , 1Gbits/ 1538 * 8 bits = 1Gbits/12304 bits = 87267 f/s 。即1Gb的带宽PPS 范围为:87267 – 1597830 pps。0.087267 Mpps - 1.59783Mpps。
问题3:
实验环境拓扑:
通过ethtool eth1 查看两个节点上eth1 网卡的speed均为1000Mb/s,即1Gb/s的网卡。在node1 和node2上关闭iptalbes,或执行:
iptables -I INPUT 1 -p udp --dport 4321 -j ACCEPT
iptables -t raw -I PREROUTING 1 -p udp --dport 4321 -j NOTRACK
- 将node1 作为udp包接收节点,node2作为udp包发送节点。
在node1 上eth1上配置2.2.2.101 IP地址,node2 上eth1 配置IP地址 2.2.2.100
Node1 执行:./udpreceiver 2.2.2.101:4321
Node2 执行: ./udpsender 2.2.2.101:4321
Node1上执行结果:
此时能达到的最大pps为580K pps左右。此时pps的抖动比较大。由于kenel schedule 将程序调度到不同core上,导致上下文在不同core上切换,从而造成较大抖动。可以将程序绑定core来减少抖动。
- 程序绑定core
Node1 上执行: taskset -c 5 ./udpreceiver 2.2.2.101:4321
Node2 上执行: taskset -c 19 ./udpsender 2.2.2.101:4321
Node1 receiver结果:
此时pps抖动就变小比较平稳。但此时pps还是没上去,离理论值还有较大差距。
Node2 发送更多的包,执行:taskset -c 19 ./udpsender 2.2.2.101:4321 2.2.2.101:4321
此时receiver节点Node1上结果:
结果显示此时pps并没有提高。此时通过ethtool 插卡网卡有没有node1 receiver节点上网卡有没有丢包,执行watch -n 1 -d 'sudo ethtool -S eth1 |grep rx |grep drop' 查看结果变化。
查看结果显示drops的数字并没有不断增加。可能是由于node2发送节点上的core19 已经达到极限。可以通过增加core的数量进行测试。
Node2 执行:taskset -c 19,20 ./udpsender 2.2.2.101:4321 2.2.2.101:4321
通过htop查看sender节点node2上cpu消耗情况:
发送节点node2上通过两个core给node1发送数据包,并都已经打满。在node1 上查看结果如下:
此时在node1 上执行watch -n 1 -d 'sudo ethtool -S eth1 |grep rx |grep drop' 查看结果:
网卡上rx队列出现对包。说明sender node 发送数据包不是瓶颈,receiver成瓶颈达到最大接收值。PPS 能达到700K pps。但此时离理论值还是有一定差距。经过测试,即使提高receiver的core数量结果也是一样的。测试网卡的接收队列已经达到瓶颈。可以通过增加网卡的接收队列数量来提高pps。
【todo】 通过网卡多队列提高pps