背景:某年某月某日,发现es运行不正常。 检查日志发现如下错误
1
java.io.IOException: Too many open files
步骤如下:
1、查看es节点信息结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"cluster_name" : "elasticsearch",
"nodes" : {
"eE4eHSOWTK-j6IO7JJzcXG" : {
"name" : "Hardcore",
"transport_address" : "inet[silence/192.168.1.111:9300]",
"host" : "silence",
"ip" : "192.168.1.111",
"version" : "1.6.0",
"build" : "cdd3ac4",
"http_address" : "inet[/192.168.1.111:9200]",
"process" : {
"refresh_interval_in_millis" : 1000,
"id" : 10598,
"max_file_descriptors" : 32768,
"mlockall" : false
}
}
}
}
问题:明明/etc/init.d/启动脚本中设置了=65535,并且-n $执行成功,但是es节点信息始终是32768
2、检查/etc/init.d/启动脚本内容,启动进程时使用/etc/init.d/下的函数,最后追溯到使用 -s /bin/bash $user -c “$ >/dev /null 2>&1 ; $*” 启动该进程。 自然地,我想在-c 后面加上-n 65535。 结果以失败告终。 启动脚本报错:open files: limit: not。 我在命令行中发现普通用户在修改时出现错误,但是root用户却可以。
3、修改/etc//.conf文件,添加以下内容(es运行用户是)
1
2
elasticsearch hard nofile 65535
elasticsearch soft nofile 65535
修改内容后,重启es。 启动后,es节点信息依然是32768……我此时抓狂了。
4.查了,说imits.so .conf文件需要在/etc/pam.d/login文件里才有效,所以我就添加了,结果……还是32768。
5、再次查看/etc/pam.d/login,发现有这么一句-auth。 看来文件-auth已经导入了,于是发现-auth中已经存在imits.so,然后删除步骤3中添加的内容。
6、这时候我想反编译.so文件,看看做了什么。 当然我首先要查询文件在哪里 find / -name .so
然后使用.so,发现里面有两行:
1
2
3
4
5
/etc/security/limits.conf
.
.
.
/etc/security/limits.d/*.conf
自然,我想检查/etc//.d/下的*.conf结果,发现def.conf,其中包含:
1
2
* hard nofile 32768
* soft nofile 32768
注:*表示对所有用户有效
自然,我不得不尝试修改def.conf文件,这次成功了。
分析一下原因:
1.为什么/etc/init.d/中已经设置了-n,为什么不生效?
命令格式:-s [shell] [uid/gid] -c "", 描述:使用备用用户或组 ID 运行 Shell。 仅运行会话的 PAM 挂钩,并且没有密码提示。 该命令仅适用于 root 用户。 有时有用
根据测试,我们还知道-n仅修改当前会话中打开的文件描述符的数量。 打开新会话或切换到新用户时不起作用。根据描述可知,会话打开后会执行PAM hooks认证模块,因此之前的设置参数无效。
2、出现65535错误时为什么要在-c后面加上-n
查资料后发现,普通用户设置-n时,大小不能超过预设值。 那么预设值是谁呢? 自然地,我想到了.conf。 你可以自己测试一下,在.conf中添加自己的用户信息(就是我),可以发现,再修改一下就正常了。
1
2
silence hard nofile 65535
silence soft nofile 65535
3..conf与.d/*.conf的关系
这时候自然想到的是文件加载顺序和配置内容有关。 当配置相同内容但值不一致时,以后加载的配置文件的值生效。 我们来做一个测试:在.d/def.conf配置文件中添加以下信息,因为在步骤2中已经在limit.conf中设置了该值为65535并且测试成功,那么此时如果我们再次测试-n 50000是正常的,而-n 65535是异常的,我们自然可以验证我们的猜测。
1
silence hard nofile 50000
结果自然和猜测一致
根据反编译结果,.so会先加载.conf,然后加载.d/.conf。 此时是有一定的顺序的,但是.d/.conf中的加载顺序是什么呢? 猜测和系统排序有关,但没有测试过。 一般来说,在这种情况下,一个好的系统管理员应该根据.d文件为不同的用户配置单独的文件,以方便管理。
为什么要在.d/def.conf中设置硬值?可以查看配置文件的规则。 硬设置是允许修改的最大值,而软设置是生成新会话时的默认设置。
4、此时你可能会问这个值可以设置多大呢?
查看文件 /proc/sys/fs/file-max 和 /proc/sys/fs/file-nr 的内容
输入:cat /proc/sys/fs/file-max
输出:
输入:cat /proc/sys/fs/file-nr
输出:1792 0
查看,file-nr文件中的三个数字分别代表:系统已分配的文件句柄数、未使用的句柄数和最大可分配句柄数。 file-max 中的值是可以分配的最大句柄数。 ,所以-n中设置的值不能超过file-max记录的值。
file-nr 文件内容通常是根据系统启动时的系统内存来计算的。 随着系统内存的增加,文件最大值也会增加。
5、如何查看其他进程的当前设置
适用于 Linux 内核版本 2.6.24 及更高版本
输入:cat /proc/34690/ | grep“最大打开文件数”
输出:最大打开
6. 如何检查进程当前打开的文件句柄数:
输入: lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|grep pid
输出:cnt pid