GBase 8a运维案例:操作系统大量TIME_WAIT导致集群连接失败出现状态异常

GBase 8a运维案例,GBase 8a 数据库某些操作时,节点服务内部会临时创建连接,操作完成后关闭,如果在某个阶段时操作系统没有可用的本地端口,将会造成连接失败,涉及的表也将无法确保状态正确,于是设置了event标记。

故障现象

节点服务出现event标记,且有可能多个节点同时出现。

分析排查

查看调度节点gcluster的express.log发现每过一段时间,就出现如下的报错信息

2022-08-24 11:31:45.887 [CPOOL2][WARN ][S:509107171][Q:1954774766]:Abnormal, failed in creating a connection to some node.
2022-08-24 11:31:45.890 [CPOOL2][WARN ][S:509107171][Q:1954774766]:Abnormal, can't create a connection. host:192.168.1.10,db:. Cause: Can't connect to GBase server on '192.168.1.10(cur_time:2022-08-24 11:31:45.890 used_time:0s)' (99)

看错误,是无法创建连接。

手工运行gccli,能正确登录,确认不是长时间处于问题状态。

查看操作系统当前TIME_WAIT连接数,发现有2万多个

[root@dsgbase1 gcluster]# netstat -anp|grep TIME_WAIT | wc -l
22036

查看操作系统sysctl参数,发现本地端口可用范围是2万个。

[root@dsgbase1 gcluster]# sysctl  -a | grep port
net.ipv4.ip_local_port_range = 30100    50000
.....

问题定位了。

原因

操作系统存在大量的tcp连接,每个连接都要一个本地端口,而当本地端口都被占用后,就会出现无法连接的报错。

而操作系统本身,对连接是有内部的淘汰机制的。

解决建议

提高操作系统对连接的淘汰程度,一般包含如下几个sysctl的参数

连接重用

允许将TIME_WAIT状态的socket重新用于新的TCP连接

net.ipv4.tcp_tw_reuse = 1 #默认为0,表示关闭

快速回收TIME_WAIT状态的socket

net.ipv4.tcp_tw_recycle = 1#默认为0,表示关闭

将MSL值缩减

linux中MSL的值默认为60s,我们可以通过缩减MSL值来使得主动关闭连接一端由TIME_WAIT状态到关闭状态的时间减少

但是这样做会导致延迟报文无法清除以及主动关闭连接一端不能收到重传来的FIN请求,也会影响很多基于TCP的应用的连接复用和调优所以在实际生产环境中,需要谨慎操作。

net.ipv4.tcp_fin_timeout = 30

参考

https://www.modb.pro/db/166108