fs.file-max 是什么
fs.file-max 限定整个系统同时能打开的文件描述符总数,socket、管道、设备文件、普通文件都计入其中。这是系统级总量,与单个进程能打开多少句柄是两层概念:单进程的上限来自 fs.nr_open 以及进程的 RLIMIT_NOFILE 限制(由 ulimit、systemd 或 limits.conf 设定)。两者报错也不同:触及单进程上限报 EMFILE,触及系统上限报 ENFILE。排查句柄问题时第一步就是分清是哪一层触顶。
基本信息
| 参数 | fs.file-max |
|---|---|
| 默认值 | 内核按内存规模自动计算初值,以本机回读为准 |
| 当前占用视图 | /proc/sys/fs/file-nr 三个数:已分配、未使用(新内核恒为 0)、系统上限 |
| 单进程上限 | fs.nr_open 与进程的 RLIMIT_NOFILE,二者取先到者 |
| 报错区分 | EMFILE 表示单进程超限,ENFILE 表示系统总量超限 |
| 适用平台 | Linux 全平台;容器内看到的是宿主或命名空间内的值 |
典型使用场景
- 高并发网络服务:连接数多的时候句柄消耗快,先确认系统总量是否够用
- 排查 Too many open files:区分是单进程限制还是系统总量限制,避免改错层级
- 容量规划:按峰值连接数、文件数估算所需的系统句柄配额
- 交付检查:给新节点设定基线并记录,便于后续对比异常增长
- 定位句柄泄漏:观察已分配数量是否随时间持续上升而不回落
查看与调整
查看与调整
sysctl fs.file-max # 读系统上限
awk '{print "已分配:",$1," 系统上限:",$3}' /proc/sys/fs/file-nr # 占用与上限
cat /proc/sys/fs/nr_open # 单进程硬上限
ulimit -n # 当前 shell 的软限制
systemctl show -p LimitNOFILE sshd 2>/dev/null # 服务级限制示例
sysctl -w fs.file-max=2097152 # 临时调整系统上限落盘与回读
落盘与回读
# /etc/sysctl.d/99-fs-tuning.conf
fs.file-max = 2097152 # 系统级文件句柄上限
fs.nr_open = 2097152 # 单进程硬上限,需不小于进程限制
# 回读命令:sysctl fs.file-max fs.nr_open三层限制对照
| 层级 | 参数或设置 | 超限表现 |
|---|---|---|
| 系统总量 | fs.file-max | 新建连接或打开文件失败,报 ENFILE |
| 单进程硬上限 | fs.nr_open | 设置更大的 ulimit 时直接报不允许 |
| 进程限制 | RLIMIT_NOFILE(ulimit、systemd、limits.conf) | 报 EMFILE,同一台机器上只有某个服务异常 |
服务进程的限制通常在启动时读取,改完配置必须重启进程或重新登录才生效。systemd 管理的服务要改的是单元文件里的 LimitNOFILE,改 shell 的 ulimit 对已有服务没有影响。
已分配数量持续攀升而不回落,通常意味着应用存在句柄泄漏或连接未正确关闭。这种情形下单纯抬高上限只是推迟故障,应当结合进程级的句柄统计定位泄漏来源。