排查分布式文件系统 TFS( Taobao FileSystem )存入文件超时,报 com.taobao.common. tfs.exception. ConnectTimeoutException 的问题

往 TFS 上传文件的这端报:

2018-08-23 00:12:34,846 [http--80-67$2127620240] (ClientManager.java:115) ERROR com.taobao.common.tfs.impl.ClientManager - send packet [5057468] timeout error. timeout: 5000, used: 5003 (ms)
2018-08-23 00:12:34,848 [http--80-67$2127620240] (DefaultTfsManager.java:952) ERROR com.taobao.common.tfs.DefaultTfsManager - save file fail: => null , .jpg
com.taobao.common.tfs.exception.ConnectTimeoutException: Connect server:/192.168.xxx.xxx:10002 error. call message timeout
        at com.taobao.common.tfs.impl.ClientManager.sendPacket(ClientManager.java:117)
        at com.taobao.common.tfs.impl.ClientManager.sendPacketNoReturn(ClientManager.java:127)
        at com.taobao.common.tfs.impl.TfsSession.writeData(TfsSession.java:396)
        at com.taobao.common.tfs.impl.TfsSmallFile.writeOneTime(TfsSmallFile.java:106)
        at com.taobao.common.tfs.impl.TfsSmallFile.write(TfsSmallFile.java:134)
        at com.taobao.common.tfs.DefaultTfsManager.saveFile(DefaultTfsManager.java:945)
        at com.taobao.common.tfs.DefaultTfsManager.saveFile(DefaultTfsManager.java:964)
        ......

经过一系列排查后发现,是其中两个问题造成的:

第一个问题:open files ulimit 值是默认的 1024

最近新增了两台 DataServer 节点,其中一台新增的 DataServer 节点 open files ulimit 值是默认的 1024 ,具体如下所示:

[root@host ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62487
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62487
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

只需执行以下两条命令,再重启服务器即可(如果不打算重启,那么您断开当前 ssh 连接,再重新通过 ssh 命令连接上服务器,再执行 ulimit -a 命令后您会发现生效了,这个时候我并不清楚 TFS 的进程打开文件的限制是否被修改为 65536 了,此时您可以尝试关掉 TFS 的进程再重新打开看看;但我建议您最好是重启一次服务器):

[root@host ~]# echo "* soft    nofile  65536" >> /etc/security/limits.conf
[root@host ~]# echo "* hard    nofile  65536" >> /etc/security/limits.conf

[root@host ~]# reboot

再来检查一下:

[root@host ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62487
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62487
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

至此该问题得到了一定程度的改善,但问题依旧。

这里需要注意的是,如果使用下列命令也是可以直接修改的,但是修改的只是当前 ssh 会话的 open files(如果重新通过 ssh 命令连接上服务器后,再 ulimit -a 您会发现根本没修改):

[root@host ~]# ulimit -SHn 65536

ulimit 命令参数解释:

  • -H :设置硬件资源限制,是管理员所设下的限制;
  • -S :设置软件资源限制,是管理员所设下的限制;
  • -a :显示当前所有的资源限制;
  • -c size :设置 core 文件的最大值,单位是 blocks ;
  • -d size :设置进程数据段的最大值,单位是 kbytes ;
  • -f size :设置 shell 创建文件的最大值,单位是 blocks ;
  • -i size :设置待处理的信号的最大个数;
  • -l size :设置一个任务锁住的物理内存的最大值,单位是 kbytes ;
  • -m size :设置一个任务的常驻物理内存的最大值,单位是 kbytes ;
  • -n size :设置内核可以同时打开的文件的最大个数;
  • -p size :设置管道缓冲区的最大值,单位是 bytes ;
  • -q size :设置 POSIX 的消息队列的最大值,单位是 bytes ;
  • -s size :设置进程堆栈的最大值,单位是 kbytes ;
  • -t size :设置 CPU 使用时间的最大上限,单位是 seconds ;
  • -u size :设置当前用户同时打开的进程(包括线程)的最大个数;
  • -v size :设置虚拟内存的最大值,单位是 kbytes ;
  • -x size :设置所能锁住的文件的最大个数。

第二个问题:原有的 DataServer 节点的防火墙设置存在问题

在新增的两台 DataServer 节点上发现,新增的两台 DataServer 节点会创建 TCP 连接来连接原有的 DataServer 节点,但部分 TCP 连接卡在 SYN_SENT 状态,具体如下所示:

[root@host ~]# netstat -anp | grep SYN_SENT
tcp        0      1 192.168.2.13:24055       192.168.1.4:10012      SYN_SENT    2695/dataserver     
tcp        0      1 192.168.2.13:38663       192.168.1.6:10000      SYN_SENT    2791/dataserver     
tcp        0      1 192.168.2.13:63954       192.168.1.4:10010      SYN_SENT    2839/dataserver     
tcp        0      1 192.168.2.13:48870       192.168.1.2:10008      SYN_SENT    2887/dataserver     
tcp        0      1 192.168.2.13:47234       192.168.1.2:10012      SYN_SENT    11718/dataserver
......

192.168.2.13 即为本机,也是新增的 DataServer 节点;192.168.1.2 、192.168.1.4 和 192.168.1.6 均为原有的 DataServer 节点。

在 192.168.2.13 上使用 telnet 192.168.1.4 10012 、telnet 192.168.1.6 10000 和 telnet 192.168.1.4 10010 等 telnet 命令均无法打开对端的 TCP 端口。

原有的 DataServer 节点安装的操作系统是:

[root@host ~]# cat /etc/redhat-release 
CentOS release 5.8 (Final)
[root@host ~]#

新增的两台 DataServer 节点安装的操作系统是:

[root@host ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@host ~]#

在 192.168.1.2 、192.168.1.4 和 192.168.1.6 这三台原有的 DataServer 节点上查看它们的 iptables 防火墙,均发现了两个问题:

[root@host ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
DROP       all  --  192.168.2.0/24       anywhere            
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  192.168.10.136       anywhere            tcp dpt:distinct 
ACCEPT     tcp  --  192.168.10.136       anywhere            tcp dpt:distinct 
ACCEPT     tcp  --  192.168.10.136       anywhere            tcp dpt:distinct 
ACCEPT     tcp  --  192.168.0.0/16       anywhere            
ACCEPT     udp  --  192.168.0.0/16       anywhere  
......

192.168.2.0/24 网段竟然被 drop 掉了!而且出现了重复的防火墙条目,于是重新修改防火墙:

[root@host ~]# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  192.168.10.136       anywhere            tcp dpt:distinct 
ACCEPT     tcp  --  192.168.0.0/16       anywhere            
ACCEPT     udp  --  192.168.0.0/16       anywhere
......

至此网络正常了!不会卡在 SYN_SENT 状态了!往 TFS 写入文件的时候也不会再报超时了!

而且在 NameServer 上看,原有的 DataServer 节点上的文件正源源不断地转移到新增的两台 DataServer 节点(即平滑扩容,目的是为了让每台 DataServer 节点的读写更均衡):

[root@host ~]# /usr/local/tfs/bin/ssm -s 192.168.1.182:8108 -i 'server'
    SERVER_ADDR        UCAP  / TCAP =  UR  BLKCNT LOAD  TOTAL_WRITE  TOTAL_READ   LAST_WRITE   LAST_READ   STARTUP_TIME
192.168.1.2:10000  743.91G 833.05G 89%   9522     38   1.2K     0  47.9K     0   1.3K     0  42.9K     0 2018-08-11 17:18:55
192.168.1.4:10000  743.91G 833.05G 89%   9522     68   1.2K     0  50.1K     0   1.4K     0  42.9K     0 2018-08-11 17:13:40
192.168.2.13:10000 191.17G 832.11G 22%   2447    225    529     0   1.4K     0    450     0   1.4K     0 2018-08-13 16:45:20
192.168.2.14:10000 191.56G 832.11G 23%   2452    190  20.2M   179 116.4M  1019   -676     0  -1509     0 2018-08-26 15:44:55
......

注:22 % 和 23 % 这两个百分比是在不断增长的;相应地,原有的 DataServer 节点的这个百分比在不断降低。

至此问题得到彻底解决。

在该问题解决之后,又遇到了一个新的超时问题,详情请看《排查分布式文件系统 TFS( Taobao FileSystem )存入文件超时,报 (ClientManager.java:115) ERROR com.taobao.common.tfs.impl.ClientManager – send packet [14415809] timeout error. timeout: 5000, used: 5001 (ms) 的问题》。

 

其他相关文章:

这篇文章对你有帮助吗?

相关文章

发表评论?

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据