关于 Linux 最大文件句柄数量的配置问题,到底最大文件数被什么限制?too many open files 错误到底需要怎么解决?
1、ulimit -n
ulimit -n 是设置当前 shell 的当前用户所有进程能打开的最大文件数量,但是一个用户可能会同时通过多个 shell 连接到系统,所以还有一个针对用户的限制,通过修改 /etc/security/limits.conf 实现,例如,往 limits.conf 输入以下内容:
root soft nofile 110001
root hard nofile 110002
soft nofile 表示软限制,hard nofile 表示硬限制,软限制要小于等于硬限制。上面两行语句表示,root 用户的软限制为 110001,硬限制为 110002,即表示 root 用户能打开的最大文件数量为 110001,不管它开启多少个 shell。
有人认为 ulimit -n,限制用户单个进程的文件最大打开数量,严格来说这个说法是错误的。ulimit -n 其实是限制当前 shell 以及该 shell 启动的进程的文件打开数量。因为在很多情况下,同一个 shell 环境里,虽然会有很多个进程,但是非常耗费文件句柄的进程并不多,所以通常情况下大家会觉得 ulimit -n 的值和当前系统中最耗费文件句柄的进程近乎相等,所以会给人一种 ulimit -n 限制单个进程的文件最大打开数量的错觉。
还有的人说 ulimit -n 只允许设置的越来越小,如下所示:
[benar.chen@idreamsky_study ~]$ ulimit -n 90000
[benar.chen@idreamsky_study ~]$ ulimit -n 90001
-bash: ulimit: open files: cannot modify limit: Operation not permitted
先执行了 ulimit -n 90000 再执行 ulimit -n 90001 就会报 “ cannot modify limit: Operation not permitted ” 错误,其实这个说法也只是片面的。对与非 root 用户来说 ulimit -n 只能越设置越小,但是 root 用户则不受此限制。
[root@idreamsky_study /]# ulimit -n 200000
[root@idreamsky_study /]# ulimit -n
200000
[root@idreamsky_study /]# ulimit -n 300000
[root@idreamsky_study /]# ulimit -n
300000
从上面 可以看出,root 用户可以轻易的改变 ulimit -n 为任意值,由此可以见 root 用户是不受限制的。
如果在 limits.conf 文件中没有设置默认值,则系统默认是 1024 ,有设置则以设置为准。
ulimit -n 生效周期: ulimit -n 是修改后立即生效的,但是仅限当前 shell 中,重新登录后会失效为 limits.conf 设置的值。
2、/etc/security/limits.conf
也有人说 ulimit -n 设定的值不能超过 limits.conf 设定的值,其实这里也分两种情况,root 用户可以随意设置,但是非 root 用户是无法超过的。
并且即使是非 root 用户的最大文件数设置不能超过 limits.conf 的设置,这也只是一个表象,实际上是因为,每个用户登录进来,ulimit -n 的默认值是 limits.conf 的 soft nofile 指定的,但是对于非 root 用户,ulimit -n 只能越来越小,不能越来越大,其实这个才是真正的原因,不过最后的结果还是一样的,即非 root 用户无法超过 limits.conf 设置的值。
limits.conf 生效周期: limits.conf 修改后重新登录进来就生效了,这个自己实际操作一下就好了,不过我有同事修改后使用 ulimit -n 查询结果是修改后的,但是做压测的时候却报 too many open files 的错,所以说如果有条件的话,最好修改后退出全部终端重启机器比较稳妥。
3、 /proc/sys/fs/file-max
网上有说法说 ulimit -n 和 limits.conf 里最大文件数设定不能超过 /proc/sys/fs/file-max 的值,这个说法就很不负责了 /proc/sys/fs/file-max 只是系统根据机器资源给出的一个合理值,一般来说内存越大,该值就越大,但也只是建议值,没有任何限制作用。
[root@idreamsky_study /]# ulimit -n
300000
[root@idreamsky_study /]# cat /proc/sys/fs/file-max
98542
4、总结
最大文件句柄数量有两个层面的限制:
1、当前 shell 层面,直接使用 ulimit -n 设定即可(root 无限制,非 root 用户只能越来越小并且初始值小于 limits.conf 中设定的默认值)。
2、用户层面限制,通过修改 /etc/security/limits.conf 配置文件限制,此修改针对的是用户,无论用户打开多少个 shell 终端,加起来的总和都无法超过这个值。
/proc/sys/fs/file-max 只是系统建议的值,不起任何实际限制作用。