Linux 文件打开数(fd)总结

来源:互联网 发布:涉密网络分级保护 编辑:程序博客网 时间:2024/05/29 07:26

昨天有个应用要求我给他改一个参数,当时只是按照文档修改,等结束之后发现后面竟是个大问题。下面是我找到的一篇不错的文章。文章来源:http://www.ahlinux.com/start/base/20312.html


在修改linux文件打开数限制一般会涉及三个方面:

    ulimit命令
    /etc/security/limits.conf文件
    /proc/sys/fs/file-nr, /proc/sys/fs/file-max

下面就每一个方面作出说明
1. ulimit命令


这个命令是bash shell内建命令, 也就是说这个命令依赖于特定的shell, bash shell支持这个命令.

这个命令的作用可以查看官方man文档(man ulimit)

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在系统允许的情况下, 提供对特定shell可利用的资源的控制. -H和-S选项设定指定资源的硬限制和软限制. 硬限制设定之后不能再增加, 而软限制则可以增加到硬限制规定的值.如果-H和-S选项都没有指定, 则软限制和硬限制同时设定. 限制值可以是指定资源的数值或者hard,soft,unlimited这些特殊值, 其中hard代表当前硬限制, soft代表当前软件限制, unlimited代表不限制. 如果不指定限制值, 则打印指定资源的软限制值, 除非指定了-H选项.如果指定了不只一种资源, 则限制名和单位都会在限制值前显示出来.


其中第一句非常重要,那就是ulimit提供的是对特定shell可利用的资源的控制, 而shell是与具体用户相关的. 因此ulimit提供的是对单个用户的限制. 其中包括以下项: (ulimit -a输出结果)


core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 4096
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


其中就有个”open files  “的限制, 默认是1024, 也就是这个用户最大可以打开1024个文件


如果使用ulimit -n修改最大文件打开数, 那么只对当前shell用户有用, 同时也只对当前shell和这个shell fork出来的子shell生效, 重启之后会重新恢复为默认值.


修改这个值如果要在重启后也生效, 一般在启动过程时运行的文件(/etc/rc.local, /etc/profile, /etc/bash_profile等等)中加上ulimit命令
2. /etc/security/limits.conf文件


这个文件是在/etc/security/目录下, 因此这个文件其实是出于安全考虑的,请看:


http://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap5sec44.html 所提:


The limits.conf file located under the /etc/securitydirectory can be used to control and limit resources for the users on your system. It is important to set resource limits on all your users so they can't perform denial of service attacks number of processes, amount of memory, etc). These limits will have to be set up for the user when he or she logs in. For example, limits for all users on your system might look like this.
               * hardcore0
               * hardrss5000
               * hardnproc       20


(注意这段话在Securing and Optimizing Linux: RedHat Edition -A Hands on Guide一书中的Chapter 5. General System Security中的5.15. Put limits on resource)


意思是位于 /etc/security目录下的 limits.conf文件是用于提供对系统中的用户所使用的资源进行控制和限制. 对所有用户的资源设定限制是非常重要的, 这可以防止用户发起针对处理器和内存数量等的拒绝服务攻击. 这些限制必须在用户登录时限制. 举例来说, 针对所有用户的限制可以像这样:


* hard core 0
               * hardrss5000
               * hardnproc       20


其中含义如下:


    第一列表示域(domain),可以使用用户名(root等),组名(以@开头,如@administrator),通配置*和%,%可以用于%group参数
    第二列表示类型(type),值可以是soft或者hard
    第三列表示项目(item),值可以是 core,data,fsize,memlock,nofile,rss,stack,cpu,nproc,as,maxlogins,maxsyslogins,priority,locks,msgqueue,nie,rtprio.
    第四列表示值.


其中nofile(Number of Open File)就是文件打开数.


limits.conf与ulimit的区别就在于前者是针对所有用户的, 而且在任何shell都是生效的, 即与shell无关,而后者只是针对特定用户的当前shell的设定. 因此定义资源限制,而文件打开数只是其中一种资源,最好在limits.conf中定义.
3./proc/sys/fs/file-nr, /proc/sys/fs/file-max


file-nr和file-max文件可以使用cat命令查看, file-nr有三个值, 每个值的说明见:


    http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/proc.html


其中有一段内容如下(指file-nr):


The three values in file-nr denote the number of allocated file handles, the number of used file handles, and the maximum number of file handles.
When the allocated file handles come close to the maximum, but the number of actually used handles is far behind, you've encountered a peak in your usage of file handles and you don't need to increase the maximum.


意思是指:


    第一个值代表已分配的文件句柄
    第二个值代表已使用的文件句柄
    第三个值代表文件句柄的最大值.


当分配的文件句柄接近于最大值时,也就是第一个值逼近第三个值时,而实际使用的文件句柄则远远落后于最大值, 那么你只是遇到一个文件句柄的使用高峰, 此时并不需要增大文件句柄的最大值。


关于这三个值的更详细说明没有找到, 如果哪位高人能通过分析代码得到进一步的信息, 恳请发个邮件给我.


首先来关注file-max这个值, 我在内存为2560M(虚拟机)时,这个值显示为251544, 将内存改为1280M时,这个值显示为123851, 而我并没用任何其它系统参数.这说明这个值是个运行时值, 是与某些参数相关的, 其中一个就是内存.


下面这些内容只是猜测:


file-max是定义系统全局的文件数, 也就是所有用户所能使用的一个最大值.file-max具体是如何计算出来的,暂且不知.


有的文章说通来统计lsof命令输出的行数来作为当前打开文件数, 这个是太不正确了,因为lsof的内容包括文件,sockets,设备(device),这种统计根本无太大价值.


而且也可以看到lsof的统计数值与file-nr中的第一个值相差巨大,根本无法比较.


我们再来看一篇文章,是oracle 9i安装文档: http://tldp.org/HOWTO/Oracle-9i-Fedora-3-Install-HOWTO/sect_05.html,内容:


5.1. Edit /etc/sysctl.conf


Add the following lines to the /etc/sysctl.conf file:


kernel.shmmax = 2147483648


kernel.shmmni = 128


kernel.shmall = 2097152


kernel.sem = 250 32000 100 128


fs.file-max = 65536


net.ipv4.ip_local_port_range = 1024 65000


5.2. Edit /etc/security/limits.conf


Additionally the following lines can be added to the /etc/security/limits.conf file:


oracle soft nofile 65536


oracle hard nofile 65536


oracle soft nproc 16384


oracle hard nproc 16384


Adding lines into these files requires a reboot before the new settings take effect.


这里同时修改了file-max的值和limits.conf的值.并且提示修改了limits.conf需要重启才能生效.
linux文件打开数总结


总的来说,在修改最大文件打开数时,最好使用limits.conf文件来修改, 通过这个文件, 可以定义用户, 资源类型, 软硬限制, 且与shell无关, 比ulimit命令要好很多.而针对file-nr和file-max文件, 个人认为不需要修改, 因为如果人为修改, 而修改的值改得太大, 使用过程中内存不够使用, 其实也是没多大作用.

 

0 0