mongo连接数满问题处理
记一次mongo服务端无法建立更多连接造成的客户端无法访问mongo集群的故障分析及解决
一. 问题:
程序无法连接mongo集群
现象:
2017-09-05T01:29:08.765+0000 I NETWORK [thread2] connection refused because too many open connections: 819
二. 排查及解决
1. 本地测试访问mongo主机及端口
telnet 192.168.1.100 20000
正常访问,端口存在
2. 登陆mongo主机查看进程和端口是否存在。
查看进程
ps -ef | grep mongo
查看端口
netstat -ntlp
确认进程和端口都正常运行
3. 查看日志
tail -f /data/mongodb/log/mongos.log
从log文件中可以看出connection refused because too many open connections: 819,不能建立更多的连接造成,mongo服务端主动拒绝,造成客户端无法访问。于是想到系统允许进程打开的的最大文件具柄数的限制。
三. 分析解决
1. 查看系统默认的最大文件句柄数,系统默认是1024
# ulimit -n 1024
参数:
命令参数
-a 显示所有限制
-c core文件大小的上限
-d 进程数据段大小的上限
-f shell所能创建的文件大小的上限
-m 驻留内存大小的上限
-s 堆栈大小的上限
-t 每秒可占用的CPU时间上限
-p 管道大小
-n 打开文件数的上限
-u 进程数的上限
-v 虚拟内存的上限
2. 查看当前进程打开了多少句柄数
# lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more 14505 2684 13937 2781 12992 2492 11616 2361 10486 2583 #其中第一列是打开的句柄数,第二列是进程ID。
# ps -ef | grep 2684 mongodb 2684 1 0 04:19 ? 00:00:38 mongod -f /data/mongodb/config/shard2.conf
3. 什么是ulimit -n
Provides control over the resources available to the shell and to processes started by it, on systems that allow such control. The -H and -S options specify that the hard or soft limit is set for the given resource. A hard limit cannot be increased once it is set;
a soft limit may be increased up to the value of the hard limit. If neither -H nor -S is specified, both the soft and hard limits are set. The value of limit can be a number in the unit specified for the resource or one of the special values hard, soft, or unlimited,
which stand for the current hard limit, the current soft limit, and no limit, respectively.If limit is omitted, the current value of the soft limit of the resource is printed, unless the -H option is given. When more than one resource is specified, the limit name and unit are printed before the value.
还有,很多文章称ulimit -n 只允许设置得越来越小,比如先执行了ulimit -n 1000,在执行ulimit -n 1001,就会报"cannot modify limit: Operation not permitted"错误。这个其实也是不准确的说法。首先要搞清楚,任何用户都可以执行ulimit,但root用户和非root用户是非常不一样的。
4. 到底最大文件数被什么限制了?too many open files错误到底可以通过什么参数控制?
shell级限制
通过ulimit -n修改,如执行命令ulimit -n 1000, 当前session会话生效,则表示将当前shell的当前用户所有进程能打开的最大文件数量设置为1000.
用户级限制
ulimit -n是设置当前shell的当前用户所有进程能打开的最大文件数量,但是一个用户可能会同时通过多个shell连接到系统,所以还有一个针对用户的限制,通过修改 /etc/security/limits.conf实现,例如,往limits.conf输入以下内容:
root soft nofile 1000
root hard nofile 1200
soft nofile表示软限制,hard nofile表示硬限制,软限制要小于等于硬限制。上面两行语句表示,root用户的软限制为1000,硬限制为1200,即表示root用户能打开的最大文件数量为1000,不管它开启多少个shell。
系统级限制
# cat /proc/sys/fs/file-max 1637385
5. 文件/proc/sys/fs/file-max
网上说,ulimit -n 和limits.conf里最大文件数设定不能超过/proc/sys/fs/file-max的值,这也是搞笑了,/proc/sys/fs/file-max是系统给出的建议值,系统会计算资源给出一个和合理值,一般跟内存有关系,内存越大,改值越大,但是仅仅是一个建议值,limits.conf的设定完全可以超过/proc/sys/fs/file-max。
6. 修改limit限制
# 在文件末尾添加,永久生效 # vim /etc/security/limits.conf mongodb soft nofile 100000 mongodb hard nofile 100000 # 切换到mongodb用户下查看 # ulimit -n 100000
重启mongo后,故障恢复!
四. 总结
- /proc/sys/fs/file-max限制不了/etc/security/limits.conf
- 只有root用户才有权限修改/etc/security/limits.conf
- 对于非root用户, /etc/security/limits.conf会限制ulimit -n,但是限制不了root用户
- 对于非root用户,ulimit -n只能越设置越小,root用户则无限制
- 任何用户对ulimit -n的修改只在当前环境有效,退出后失效,重新登录新来后,ulimit -n由limits.conf决定
- 如果limits.conf没有做设定,则默认值是1024
- 当前环境的用户所有进程能打开的最大文件数量由ulimit -n决定