解决系统too many open files
.背景
-
nofile不足引起的too many open files故障报警频繁出现
2.文件描述符的定义与功能
-
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。
当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。
-
简单来说,在Linux 系统中,一切都看做是文件,当进程打开现有文件或创建新文件时,内核向进程返回一个文件描述符,
文件描述符就是内核为了高效管理已被打开的文件所创建的索引,用来指向被打开的文件,所有执行I/O操作的系统调用都会通过文件描述符。
3.file-max nr_open nofile 参数之间关系
配置参数
|
级别
|
配置含义
|
配置路径
|
fs.file-max
|
系统级别
|
当前系统可打开最大文件描述符的数量
|
/etc/sysctl.conf
|
fs.nr_open
|
进程级别(不可按用户细化配置)
|
单个进程可打开最大文件描述符的数量
|
/etc/sysctl.conf
|
hard nofile
|
进程级别(可以按照用户细化配置)
|
单个进程可打开最大文件描述符的数量,
强限制,该值需要始终保持大于等于soft。
|
/etc/security/limits.conf
|
soft nofile
|
进程级别(可以按照用户细化配置)
|
单个进程可打开最大文件描述符的数量,
软限制,该值需要始终保持小于等于hard。
|
/etc/security/limits.conf
|
结论:
1、file-max ≥ nr_open ≥ hart nofile ≥ sofe nofile,如果是root用户不受限于file-max,但是
2、nofile 和 fs.nr_open 都是限制的单个进程的最大文件数量。二者区别是/etc/security/limits.conf 中的nofile可以继续按照用户维度进行细化配置,而 fs.nr_open 则只能针对所有用户。
3、nofile soft 需要小于等于nofile hard,
4、内存和nofile存在一定的线性关系,早期内存很小,所以nofile配置1024,现在内存配置都很高,完全足够支持很大量级的打开文件数,倘若系统真的出现瓶颈,首当其冲的也会是其他资源类型,所以为了方便管理,可以将file-max 、nr_open、hard nofile 、soft nofile都配置成一个较高的值,如需调整,也均一起保持相同数值统一调整。
⚠️注意:修改完所有配置之后,只对新启动的进程生效,修改配置之前的进程不生效,需要重启进程才能使用新的配置!!
4.常用命令
4.1.查看nofile
# 查看当前系统的最大打开文件数
$ cat /proc/sys/fs/file-max
1024000
# 查看一个进程最大打开文件数,该文件是只读权限,此值实际来源于/etc/sysctl.conf,如果未定义,则该值默认为1048576, 如果在sysctl.conf重新定义该值并通过sysctl -p生效后,可以通过cat /proc/sys/fs/nr_open查看最新值。
$ cat /proc/sys/fs/nr_open
1048576
# 查看当前系统已经打开的句柄
# 输出三列信息,第一列代表全局已经分配的文件描述符数量,第二列代表已分配未使用的文件描述符,第三列代表系统总的文件描述符的数量。
$ cat /proc/sys/fs/file-nr
2176 0 1024000
#统计进程pid与文件句柄数的关系
$ lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr
# 统计各用户打开句柄数
$ lsof -n|awk '{print $3}'|sort|uniq -c|sort -nr
# 统计各命令打开句柄数
$ lsof -n|awk '{print $1}'|sort|uniq -c|sort -nr
4.2.修改nofile
# 永久设置file-max和nr_open,sysctl.conf需要root权限才能修改。
$ sudo -i
$ vim /etc/sysctl.conf
fs.file-max = 1024000
fs.nr_open= 1024000
$ sysctl -p
# 永久设置soft ,hard nofile
# *代表所有用户,也可以针对其他普通用户做配置
$ vim /etc/security/limits.conf
* soft nofile 1024000
* hard nofile 1024000
# 临时设置soft ,hard nofile
$ ulimit -S 1024000