Ubuntu server 最大打开文件数目优化

如何查看系统打开文件数量的限制

如何在 Linux 系统下增加打开文件的最大数量? 如何在Linux下打开更多文件描述符?我们要根据系统原先的设定来决定是否要调整设置

可以使用以下命令显示系统允许的最大打开文件描述符数:

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

我在 Ubuntu 18.04 上得到的最大打开文件描述符数量是 97898,也就是正常用户可以在单个登录会话中打开97898个文件

先查看一下当前用户会话的打开文件数的软限制和硬限制,可以使用下面命令:

$ ulmit -Sn
1024
$ ulimit -Hn
1048576

命令选项中 S 即 soft, H 即 hard

如何调整系统范围的文件描述符(FD)限制

可以通过Linux操作系统下的/etc/sysctl.conf文件更改整个系统中同时打开的文件描述符的数量

有时系统可能发生达到最大文件数的错误,如何解决此问题?

许多应用程序(如Oracle数据库或Apache Web服务器)需要此范围相当高。因此,您可以通过在内核变量 /proc/sys/fs/file-max 中设置新值来增加打开文件的最大数量

前面上面我们查看过,系统打开文件数限制是 97898,这个数字一般来说够大了,如果需要修改,可以如下设置

如下所示(以root身份登录):

#sysctl -w fs.file-max = 51200

以上命令强制限制为 51200 个文件,并即时生效

您需要编辑/etc/sysctl.conf文件并放入以下行,以便重新启动后设置仍然生效:

# vi /etc/sysctl.conf
fs.file-max = 51200

需要注意的是,直接修改 /etc/sysctl.conf 给管理带来了不便,最好是把所有的自定义设置放在单独文件中,这样我们备份系统或测试时就很安全、方便了

因此,我们应该在 /etc/sysctl.d/ 目录下创建一个 98-file-max.conf 文件,把自定义设置写在那里

# vi /etc/sysctl.d/98-file-max.conf
fs.file-max = 51200

保存并关闭文件。用户需要注销并重新登录才能使更改生效,或者只需键入以下命令:

# sysctl --system

使用命令验证您的设置:

# cat /proc/sys/fs/file-max
51200

或者这样:

# sysctl fs.file-max
51200

如何设置用户级别打开文件描述符 FD 限制

上述过程设置了系统范围的文件描述符(FD)限制。 但是,您可以通过编辑 /etc/security/limits.conf 文件 设置任意用户打开文件的限制

  • 不同用户有单独的限制,因此请确保以您的进程使用的用户身份运行此限制
  • 有一个硬限制(hard),一个软限制(soft)。 soft是您的进程必须遵守的实际限制,hard设置了软限制可以设置的最大数量

从上面查看可知,硬限制已经设置得比较大了,我们需要修改的是软限制

请记住,ulimit 查看得到的数值不能保证你的进程实际拥有的限制! 在初始化shell之后(或之前),有98种情况可以修改进程的限制数值

下面我们就来查看一下 shadowsocks-liev 进程的限制数值

先查找一下 ss-server的进程 ID,即PID

$ ps ax | grep ss-server
6543 ?        Ss     0:02 /usr/bin/ss-server -c /etc/shadowsocks-libev/config.json -u

得到进程ID后,就可以这样查看 ss-server 的限制数值了

$ cat /proc/6543/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3841                 3841                 processes
Max open files            32768                32768                files
Max locked memory         16777216             16777216             bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3841                 3841                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

可见, ss-server 最大可以打开32768个文件,这个数字不算小吧,那么ss-server现在打开了多少个文件呢

/proc/{process_id}/fd 是一个目录,它为进程拥有的每个打开文件保存一个文件,因此很容易计算我们达到限制的接近程度:

$ sudo ls /proc/6543/fd | wc -l
54

哇,ss-server 远没有达到打开文件数目的上限,但是我们还是需要修改一下系统设置的,因为系统中有多个用户,有许多进程,我们也要照顾到她们的需求是不是:

$ sudo vi /etc/security/limits.d/98-nofile.conf
# add lines to it
*     soft     nofile     512000
root  soft     nofile     512000

如果你的系统原来的硬限制值也较小,那么可以这样设置:

$ sudo vi /etc/security/limits.d/98-nofile.conf
# add lines to it
*     soft     nofile     512000
*     hard     nofile     512000
root  soft     nofile     512000
root  hard     nofile     512000

开头的星号表示“将此规则应用于除root之外的所有用户”,您可以猜测到root开头的规则 仅为root用户设置限制。最后的数字当然是您设置的新限制

网上的优化教程一般是直接修改 /etc/security/limits.conf 文件,这样的做法并不好

重启系统,检查是否生效:

$ ulimit -Sn
512000
$ ulimit -Sn
1048576

原来通过 shadowsocks-libev 上传文件比较慢,原因可能在于BBR TCP加速需要打开更多的文件,当打开文件数超过系统设置的上限时就会出错,经设置98-nofile.conf后,文件上传速度就很快了

RHEL,CentOS,Fedora,Scientific Linux用户还需要编辑 /etc/pam.d/login 文件并添加/修改以下行(确保获得pam_limts.so):

$ sudo vi /etc/pam.d/common-session

# add this line to it
session required pam_limits.so

相关资源: