网卡对TCP重传的影响
今天运维反应有两个相似节点的tcp重传率差距较大,让我们去看一下什么情况造成的,简单描述一下。
2个节点,比如说a、b是是一个地区一个运营商的,但是a节点重传2%,b节点却是7-8%。
节点的实时流量a是b的2倍,理论上讲应该网络情况都是一致的。
通过tsar查看机器流量的历史记录,a节点是b节点的2倍,符合预期
a节点网卡流量:
Time bytin bytout pktin pktout
12/12/12-16:10 156.3M 295.8M 193.4K 237.8K
12/12/12-16:15 149.6M 283.6M 184.9K 228.0K
12/12/12-16:20 160.4M 304.9M 198.6K 245.2K
b节点网卡流量:
Time bytin bytout pktin pktout
12/12/12-14:35 80.1M 167.1M 62.5K 48.7K
12/12/12-14:40 80.1M 157.2M 61.0K 47.5K
12/12/12-14:45 82.0M 156.8M 62.2K 48.3K
但是a节点的tcp包数目是b节点的5-6倍左右,而不是2倍左右,怀疑a节点小包较多。
a节点tcp信息
Time active pasive iseg outseg retran
12/12/12-16:10 151.28 1.7K 195.9K 234.8K 2.46
12/12/12-16:15 148.75 1.7K 187.6K 225.1K 2.43
12/12/12-16:20 153.36 1.8K 201.3K 242.0K 2.46
b节点tcp信息
Time ——————-tcp——————
Time active pasive iseg outseg retran
12/12/12-16:10 60.61 1.0K 58.3K 42.6K 6.54
12/12/12-16:15 61.72 1.0K 59.3K 43.5K 6.37
12/12/12-16:20 61.71 1.0K 58.1K 42.5K 6.57
怀疑是2个节点的网卡参数导致,查看ethtool
a节点:
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: off
udp-fragmentation-offload: off
generic-segmentation-offload: off
generic-receive-offload: off
large-receive-offload: off
b节点:
Offload parameters for eth1:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on
看到区别了,原来b节点的tso,gso,gro,lro都是默认打开的,这样在接受和发送包时,
对于大包不会在协议栈做拆分,如果网卡支持,则直接交给网卡,由网卡做进拆包和组包。
尝试关闭这几个参数,发现tcp重传立马降低到2%的水平:
google了一下这几个参数的具体含义如下:
TSO
TSO(TCP Segmentation Offload),是一种利用网卡对TCP数据包分片,减轻CPU负荷的一种技术,有时也被叫做 LSO (Large segment offload) ,TSO是针对TCP的,UFO是针对UDP的。如果硬件支持 TSO功能,同时也需要硬件支持的TCP校验计算和分散/聚集 (Scatter Gather) 功能。
GSO
GSO(Generic Segmentation Offload),它比TSO更通用,基本思想就是尽可能的推迟数据分片直至发送到网卡驱动之前,此时会检查网卡是否支持分片功能(如TSO、UFO),如果支持直接发送到网卡,如果不支持就进行分片后再发往网卡。这样大数据包只需走一次协议栈,而不是被分割成几个数据包分别走,这就提高了效率。
LRO
LRO(Large Receive Offload),通过将接收到的多个TCP数据聚合成一个大的数据包,然后传递给网络协议栈处理,以减少上层协议栈处理开销,提高系统接收TCP数据包的能力。
GRO
GRO(Generic Receive Offload),基本思想跟LRO类似,克服了LRO的一些缺点,更通用。后续的驱动都使用GRO的接口,而不是LRO。
关于gro的内核代码分析参见:http://www.pagefault.info/?p=159
tsar工具参见:http://code.taobao.org/p/tsar/wiki/index/
没说明为什么这几个参数开了就会导致重传啊?
重传率=在单位时间内重传的报文段/单位时间内已经传送出去的报文段
这个计算是内核层面进行计算的,tso是在网卡层面进行分段,相当于分母变小了,自然tso计算出来的会将重传率变大。