运维遇坑记录(1)-GRO功能造成LVS慢

前段时间线上环境遇到一个问题,在 POST 数据经过 LVS 的时候,会特别慢,100K 的数据往往超过 5 秒,后来研究发现 LVSCentos6(2.6.29-2.6.39) 下,如果开启 GRO,会大量丢包。

1 问题现象

线上服务器采用 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

2 定位原因

LVS 服务器上执行 tcpdump host 10.0.1.188 -w lvs.pcap 捉包,并用 Wireshark 打开,发现有大量的重传现象和 Fragmentation needed 要求分片的控制报文。

image

接着使用 netstat -i 检查 ClientLVS 网卡的 MTU 是否一致,发现相关服务器的 MTU 值均为 1500,网络工程师告知网络设备 MTU 没有改动,排除机器 MTU 不一致引起的问题。

搜索关键词 lvs fragmentation needed 发现一个叫 GRO 的功能可能会引起 LVS 机器丢包

使用 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

问题解决,恢复正常

3 问题产生原因

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

4 有没有其他解决方案

  1. 调整相关设备的 MTU 值。
  2. 升级 LVS 所在机器的系统内核。

遵从先恢复正常使用的原则,我们直接关闭了 GRO,上述两个方案可作为后续调整的方向。方案 1 涉及的设备比较多,难以评估风险和影响,所以暂不考虑。方案 2 可作为后期调整方向。

需要注意的一个地方是,如果使用的是云服务器,需要同时关闭宿主机的 GRO,如果网卡有做 bond,需要在真实网卡中关闭 GRO

  1. Generic receive offload
  2. lvs: issues with GRO / icmp fragmentation needed

你可能感兴趣的:(lvs,linux,运维)