linux中最大文件描述符数


原文链接: linux中最大文件描述符数

前言

关于Linux下系统,进程能最大能打开的文件描述符数看过好多文章,但大都没有完整,详细说明每个值表示什么意思,在实践中该怎么设置.今天刚好有时间就通过Google来整理了如下的内容.如有错误请指出,谢谢.

系统级别

Linux系统级别限制所有用户进程能打开的文件描述符总数可以通过如下的命令查看

$ cat /proc/sys/fs/file-max
2259544

有2中方法修改系统级别的限制:

通过命令动态修改(重启后失效)

sysctl -w fs.file-max=102400

2.通过配置文件修改

vi /etc/sysctl.conf
在文件末尾添加
fs.file-max=102400
保存退出后使用sysctl -p 命令使其生效

和fs.file-max有关的一个参数是file-nr, 该参数是只读的

$ cat /proc/sys/fs/file-nr
3296 0 2259544

file-nr的值由3部分组成:1,已经分配的文件描述符数;2,已经分配但未使用的文件描述符数;
3,内核最大能分配的文件描述符数

注意: 只要你的内存足够大,file-max的值可以非常大。
用户级别

用户级别的限制是通过可以通过命令ulimit命令和文件/etc/security/limits.conf

$ ulimit -n
655350
//查看硬件资源限制
$ ulimit -Hn
655350
//软件资源限制
$ ulimit -Sn
655350
//设置软/硬件资源限制
ulimit -Sn 655350 或 ulimit -Hn 655350

查看limits.conf文件

cat /etc/security/limits.conf
//输出

  • hard nofile 655350
  • soft nofile 655350

limits.conf 文件的格式是:

每个域的取值可以参考

如果domain的值是一个用户名,则可以限制该用户下的所有进程能打开的文件描述符总数,如果是*则表示针对每个用户都起作用

注意 针对同一个item取值, soft的值不能大于hard
nr_open

This denotes the maximum number of file-handles a process can
allocate. Default value is 1024*1024 (1048576) which should be
enough for most machines. Actual limit depends on RLIMIT_NOFILE
resource limit.

就是说nr_open表示一个进程做多能分配的文件句柄数,默认值是1048576。针对大多数的情况该值是足够的。
NR_FILE

NR_FILE is the limit on total number of files in the system at any given point in time

NR_FILE 是系统在某一给定时刻,限制的文件总数

While initializing the kernel we setup the vfs cache with start_kernel
vfs_caches_init(num_physpages);
files_init(mempages);
fs/file_table.c says
/* One file with associated inode and dcache is very roughly 1K.

    Per default don’t use more than 10% of our memory for files.
    n = (mempages * (PAGE_SIZE / 1024)) / 10;
    this n can never be greater than NR_FILE

ulimit 命令

1.只对当前tty(终端有效),若要每次都生效的话,可以把ulimit参数放到对应用户的.bash_profile里面;
2.ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软;
3.默认显示的是软限制,如果运行ulimit命令修改的时候没有加上的话,就是两个参数一起改变.生效;

命令参数
-H 设置硬件资源限制.
-S 设置软件资源限制.
-a 显示当前所有的资源限制.
-c size:设置core文件的最大值.单位:blocks
-d size:设置数据段的最大值.单位:kbytes
-f size:设置创建文件的最大值.单位:blocks
-l size:设置在内存中锁定进程的最大值.单位:kbytes
-m size:设置可以使用的常驻内存的最大值.单位:kbytes
-n size:设置内核可以同时打开的文件描述符的最大值.单位:n
-p size:设置管道缓冲区的最大值.单位:kbytes
-s size:设置堆栈的最大值.单位:kbytes
-t size:设置CPU使用时间的最大上限.单位:seconds
-v size:设置虚拟内存的最大值.单位:kbytes
unlimited 是一个特殊值,用于表示不限制
总结 file-max, nr_open, nofile之间的关系

针对用户打开最大文件数的限制,可以通过修改文件limits.conf来实现
nofile中soft的值小于hard, 最大值由nr_open来决定
file-max表示内核针对整个系统,限制能所有进程能打开的文件描述符数
nofile < nr_open < file-max

参考

https://linux.die.net/man/5/limits.conf
https://www.kernel.org/doc/Documentation/sysctl/fs.txt
http://blog.chinaunix.net/uid-24807808-id-3077199.html
http://blog.csdn.net/gatieme/article/details/51058797
http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/

怎样增大 Linux 系统的 open file(s) 上限
tags: linux | ulimit

最近在工作中遇到一个问题,尝试直接将服务运行在高配(40core, 192GB;相比虚拟机来说) 的物理机上,但是发现服务打开的文件句柄达到 80 万左右就不能再开更多了。

80 万已经是一个不小的值了,通常情况下,Linux 默认的值都很小,例如:Debian 8(jessie) 给普通用户设置的 open file(s) 限制为 65536, 可以通过下面的命令查看当前限制。

$ ulimit -n
$ ulimit -Sn
$ ulimit -Hn

ulimit 是一个 shell(这里使用的是 bash) 内置命令,可以通过 type ulimit 验证。

-n 即表示查看或者设置 open file(s) 的限制,在 ulimit 中,每个限制都有两种类型:

-S, soft limit, 软限制,用户可以上调软限制到硬限制
-H, hard limit, 硬限制,非 root 用户不能修改

如果没有指明,则同时修改软限制和硬限制。
修改 ulimit

修改分为临时修改和永久修改,临时修改只对当前 session 有效,登出和重启后都恢复系统设置。

临时修改使用 ulimit 命令,以修改 open file(s) 为例。

ulimit -n 1024000

ulimit -n

1024000

永久修改需要修改 /etc/security/limits.conf 或者在 /etc/security/limits.d/ 目录下添加一个文件。具体格式参考 /etc/security/limits.conf,里面有详细说明。
open file(s) 上限

回到遇到的问题中来:服务打开 80 万个左右的文件句柄就不能再打开了。所以, 尝试将 ulimit 设置为 1000 万,结果提示出错:

ulimit -n 10000000

-bash: ulimit: open files: cannot modify limit: Operation not permitted

注意,使用的可以 root 用户,居然没有权限,然后尝试降低到:

500 万,依然错误
300 万,依然错误
200 万,依然错误
100 万,成功了

显然,这里有一个上限,大概在 100-200 万之间。

所以,解决问题的办法,在于怎样提高这个上限!

通过一番搜索,发现 open file(s) kernel 级别有 2 个配置,分别是:

fs.nr_open,进程级别
fs.file-max,系统级别

fs.nr_open 默认设置的上限是 1048576,所以用户的 open file(s) 不可能超过这个上限。

sysctl -w fs.nr_open=10000000

ulimit -n 10000000

ulimit -n

10000000

修改后即可设置更大的 open file(s) 了。

同样,对于 kernel 参数的修改,sysctl 命令修改的是当前运行时,如果需要永久修改, 则将配置添加到 /etc/sysctl.conf 中,例如:

echo "fs.nr_open = 10000000" >> /etc/sysctl.conf

echo "fs.file-max = 11000000" >> /etc/sysctl.conf

注意:fs.nr_open 总是应该小于等于 fs.file-max。

如果要查看当前打开的文件数,使用下面的命令:

sysctl fs.file-nr

fs.file-nr = 1760 0 11000000

不过,增大这些值意味着能够打开更多的文件(在 Linux 中,everything is file,包括 socket),但是同时也意味着消耗更多的资源,所以基本上在物理机上才会遇到这种问题。

`