前段时间线上环境遇到一个问题,在 POST
数据通过 LVS
的时候,会特别慢,100K 的数据每每超过 5 秒,后来研究发现 LVS
在 Centos6(2.6.29-2.6.39)
下,若是开启 GRO
,会大量丢包。后端
线上服务器采用 LVS
做为负载均衡和高可用,LVS
用的是 DR
模式。新建 LVS
使用后发现,在上传数据时,小数据会很快,大数据会很慢。若是绕过 LVS
直接到后端,就没有这个问题,因此问题定位在 LVS
所在的服务器。服务器
如今测试环境重现以下,上传两个文件,一个 10k,一个 100k,10k 的只须要 0.009
秒,100k 居然要接近 10
秒:网络
[root@chengqm test_upload]# ll -h total 112K -rw-r--r--. 1 root root 100K Mar 31 21:26 100k_file -rw-r--r--. 1 root root 10K Mar 31 21:25 10k_file [root@chengqm test_upload]# time curl 10.0.1.188:22333/upload -F "myfile=@./10k_file" ok real 0m0.009s user 0m0.001s sys 0m0.003s [root@chengqm test_upload]# time curl 10.0.1.188:22333/upload -F "myfile=@./100k_file" ok real 0m9.785s user 0m0.000s sys 0m0.006s
在 LVS
服务器上执行 tcpdump host 10.0.1.188 -w lvs.pcap
捉包,并用 Wireshark
打开,发现有大量的重传现象和 Fragmentation needed
要求分片的控制报文。负载均衡
接着使用 netstat -i
检查 Client
和 LVS
网卡的 MTU
是否一致,发现相关服务器的 MTU
值均为 1500
,网络工程师告知网络设备 MTU
没有改动,排除机器 MTU
不一致引发的问题。curl
搜索关键词 lvs fragmentation needed
发现一个叫 GRO
的功能可能会引发 LVS
机器丢包tcp
使用 ethtool -k 网卡名
查看网卡配置,对比正常 LVS
的网卡,发现有问题的网卡确实开启了 GRO
功能性能
[root@chengqm-lvs ~]# ethtool -k eth0| grep 'generic-receive-offload' generic-receive-offload: on
手动关闭 GRO
功能测试
[root@chengqm-lvs ~]# ethtool -K eth0 gro off
再次上传数据大数据
[root@chengqm test_upload]# time curl 10.0.1.188:22333/upload -F "myfile=@./100k_file" ok real 0m0.031s user 0m0.001s sys 0m0.009s
问题解决,恢复正常url
MTU 通常都是 1500 字节,若是一个包超过了 MTU ,就会被分片,对于当前网卡性能来讲,这个数值过小了,如今 10Gbps 的网卡都广泛使用了,若是 10Gbps 的网卡满载地来跑,一个完整的数据包会被分片 800w 片。咱们能够经过修改 MTU 来减小分片,可是修改 MTU 涉及的设备就多了,不可控。因而有了经过网卡来间接实现提升 MTU 的方案,这就是 GRO
。
若是开启 GRO
,在网卡中将知足必定的条件的包,将分片的包组装合并了,才一次性交给上面的协议栈。在 2.6.29
后 若是网卡和驱动都支持,那么会默认开启 GRO
功能。
听说在 2.6.29-2.6.39
版本中, LVS 内核模块在处理>MTU
的数据包时,会丢弃,因此才能看到一堆重发的包和fragmentation needed
。
MTU
值。LVS
所在机器的系统内核。听从先恢复正常使用的原则,咱们直接关闭了 GRO
,上述两个方案可做为后续调整的方向。方案 1 涉及的设备比较多,难以评估风险和影响,因此暂不考虑。方案 2 可做为后期调整方向。
须要注意的一个地方是,若是使用的是云服务器,须要同时关闭宿主机的 GRO
,若是网卡有作 bond
,须要在真实网卡中关闭 GRO
。