ARP Cache 导致网络丢包异常
问题现象:
网络出现异常,ping 掉包严重,即使ping 127.0.0.1 可能丢包率也高,而且 ping 命令还出现 ping: sendmsg: Invalid argument 错误:
64 bytes from 127.0.0.1: icmp_seq=150 ttl=64 time=0.050 ms
64 bytes from 127.0.0.1: icmp_seq=151 ttl=64 time=0.062 ms
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
ping: sendmsg: Invalid argument
64 bytes from 127.0.0.1: icmp_seq=158 ttl=64 time=0.962 ms
64 bytes from 127.0.0.1: icmp_seq=159 ttl=64 time=0.033 ms
查看dmesg -H,有可能有类似 net_ratelimit: 478 callbacks suppressed 的记录:
[ +6.555833] net_ratelimit: 478 callbacks suppressed
[Oct19 11:08] net_ratelimit: 57 callbacks suppressed
问题处理方法:
修改ARP Cache
通过 arp -an|wc -l 查看当前记录的 ARP 记录的数量:
$ arp -an|wc -l
1108
或者通过 ip -4 neigh show nud all | wc -l 查看当前 IPv4 的 ARP 记录的数量
$ ip -4 neigh show nud all | wc -l
1112
可以看到上面的值比 net.ipv4.neigh.default.gc_thresh3 的默认值 1024 要大,此时就会进行 gc 操作,如果 gc 操作持续时间太久就会导致新的 ARP 记录无法被创建,进而导致 ARP 通信无法正常完成,TCP 之类的操作更加就无法完成了(有空的时候再仔细求证这个理解...),所以我们要修改为更大的值。
修改:
# 修改/etc/sysctl.conf,添加或修改下列参数
net.ipv4.neigh.default.gc_thresh1=1024
net.ipv4.neigh.default.gc_thresh2=2048
net.ipv4.neigh.default.gc_thresh3=4096# 保存退出后,执行sysctl -p 生效
# 执行sysctl -a 查询
sysctl -a |grep net.ipv4.neigh.default.gc_thresh
# 或执行下列命令
$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh1=1024
$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh2=2048
$ sudo sysctl -w net.ipv4.neigh.default.gc_thresh3=4096
$ sudo sysctl -p
$ sudo sysctl -a |grep net.ipv4.neigh.default.gc_thresh
如果当前 IPv4 的 ARP 记录的数量本来就比较大,可以考虑配置再大一点的值,比如:
net.ipv4.neigh.default.gc_thresh1 = 8192
net.ipv4.neigh.default.gc_thresh2 = 32768
net.ipv4.neigh.default.gc_thresh3 = 65536
注:上面修改的都是 IPv4 相关的配置,如果有用到 IPv6 网络的话可以把对应的配置项也修改一下。
注:如果机器性能特别好或者比较介意 gc,可以考虑把值调到非常非常大,然后禁用gc:net.ipv4.neigh.default.gc_interval,net.ipv4.neigh.default.gc_stale_time
为什么要修改为上面的值
这几个配置项的含义(摘自 https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt):
- net.ipv4.neigh.default.gc_thresh1: min IPV4 entries to keep in ARP cache - garbage collection never runs if this many or less entries are in cache
- net.ipv4.neigh.default.gc_thresh2: IPV4 entries allowed in ARP cache before garbage collection will be scheduled in 5 seconds
- net.ipv4.neigh.default.gc_thresh3: maximum IPV4 entries allowed in ARP cache; garbage collection runs when this many entries reached
另:
更多情况下可能是nf_conntrack导致网络异常,在检查修改ARP Cache 时,可以先检查修改 nf_conntrack 。
nf_conntrack 连接数满了 message或dmesg 会打印 nf_conntrack 的信息。
查看nf_conntrack表当前连接数:
[root@node-3 ~]# cat /proc/sys/net/netfilter/nf_conntrack_count
1612
查看nf_conntrack表最大连接数:
[root@node-3 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
262144
[root@node-3 ~]# sysctl -a |grep nf_conntrack
文档参考:
一种解决 HAProxy 节点网络异常(sendmsg: Invalid argument, Connection timed out )的办法