inotify 配额是什么
inotify 是 Linux 的文件系统事件通知机制:应用调用 inotify_init 创建实例,再对具体路径添加 watch 来接收变更事件,构建工具、IDE、日志采集与容器运行时都在用。内核为每个用户设了两道独立配额:fs.inotify.max_user_instances 限制同一 uid 能创建的实例数(默认 128),fs.inotify.max_user_watches 限制该用户能注册的 watch 总数。配额耗尽时报错不同:实例耗尽返回 EMFILE,watch 耗尽返回 ENOSPC。
基本信息
| 实例配额 | fs.inotify.max_user_instances,默认 128 |
|---|---|
| watch 配额 | fs.inotify.max_user_watches,随内核与内存规模变化 |
| 事件队列 | fs.inotify.max_queued_events,默认 16384 |
| 实例含义 | 一次 inotify_init 对应一个实例 |
| 生效方式 | 写入立即生效,重启丢失 |
典型使用场景
- 容器或构建平台在同一主机跑大量监听进程
- 前端构建工具、文件同步工具报 inotify 相关错误
- 日志采集组件对大量目录注册 watch
- 排查「Too many open files」与 inotify 配额的关系
- 多个服务共用同一 uid,配额被合计占用
查看与调整
查看与调整
sysctl fs.inotify.max_user_instances fs.inotify.max_user_watches
sysctl fs.inotify.max_queued_events
sysctl -w fs.inotify.max_user_instances=1024
sysctl -w fs.inotify.max_user_watches=524288
sysctl fs.file-max; ulimit -n # 文件描述符是另一层限制,别混
lsof -u www-data 2>/dev/null | grep -c inotify # 某用户当前占用的 inotify 句柄
printf 'fs.inotify.max_user_instances=1024\n' | sudo tee /etc/sysctl.d/99-inotify.conf # 持久化配额与报错对照
| 参数 | 默认 | 超限表现 |
|---|---|---|
| max_user_instances | 128 | 创建实例失败,返回 EMFILE(Too many open files) |
| max_user_watches | 随内核与内存规模 | 添加 watch 失败,返回 ENOSPC(No space left on device) |
| max_queued_events | 16384 | 队列溢出,事件被丢弃且不报错 |
| fs.file-max 与 ulimit -n | 按系统与用户 | 另一层文件描述符限制,同样报 EMFILE |
实例数与 watch 数是两个独立配额,报错信息也不一样:EMFILE 指向实例耗尽,ENOSPC 指向 watch 耗尽,按错误对准参数。
事件队列溢出不会报错,只会丢事件;依赖 inotify 做同步的应用会表现为「漏了一部分改动」,需要一并核算队列容量。
调大前的核算方法
- 统计同一 uid 下各进程实际打开的 inotify 句柄数,得到真实峰值
- 按服务或容器数量乘以每个实例需要的 watch 数估算总量
- 留出余量后再设定上限,并写入 /etc/sysctl.d 持久化
内核在每次创建实例或添加 watch 时对照当前配额检查,因此调整后无需重启进程即可生效;但容器内的限制还受宿主与运行时约束。