TrumanWong

如何解决"inotify cannot be used, reverting to polling: Too many open files"问题

TrumanWong
12/27/2023

简介

今天在服务器用tail查看日志的时候,提示tail: inotify cannot be used, reverting to polling: Too many open files。通过查资料得知这个问题与Linux内核中的inotify机制有关。

inotifyLinux 内核提供的一种机制,可以让应用程序监控文件或目录的变化,例如创建、删除、修改、重命名等。inotify 在很多场景下都很有用,比如文件同步、备份、日志分析等。但是,inotify 也有一些限制,如果不注意,可能会导致资源耗尽的错误,影响应用程序的正常运行。本文将介绍 inotify 的原理、限制和解决方案。

inotify 的原理和限制

inotify 的使用方法是通过调用 inotify_init 函数创建一个inotify 实例,然后调用 inotify_add_watch 函数为该实例添加一个或多个监控对象,也就是文件或目录的路径。每个监控对象都可以指定一组感兴趣的事件,比如 IN_CREATEIN_DELETEIN_MODIFY 等。当这些事件发生时,内核会将相关的信息写入到 inotify 实例对应的文件描述符中,应用程序可以通过读取该文件描述符来获取事件通知。

inotify 有三个参数,分别是 max_user_instancesmax_user_watchesmax_queued_events,它们都可以在 /proc/sys/fs/inotify 目录下找到,也可以通过 sysctl 命令来查看或修改。它们的含义如下:

  • max_user_instances:指定每个用户可以创建的 inotify 实例的上限。通常每个进程(比如 tail)只需要创建一个 inotify 实例。如果超过这个限制,会报错 Too many open files。通过以下命令可以查看max_user_instances当前值:

    $ cat /proc/sys/fs/inotify/max_user_instances
    128
    
  • max_user_watches:指定每个用户可以创建的监控对象的上限。每个监控对象都占用一定的内核内存,如果超过这个限制,会报错 inotify resources exhausted。通过以下命令可以查看max_user_watches当前值:

    $ cat /proc/sys/fs/inotify/max_user_watches
    29635
    
  • max_queued_events:指定每个 inotify 实例的事件队列的上限。由于应用程序可能无法及时处理所有的事件通知,内核会将它们缓存在一个事件队列中,如果超过这个限制,事件会被丢弃,但不会报错。通过以下命令可以查看max_queued_events当前值:

    $ cat /proc/sys/fs/inotify/max_queued_events
    16384
    

inotify 的解决方案

inotify 的限制是为了防止内核内存被过度消耗,但是在某些情况下,可能需要增加这些限制,以满足应用程序的需求。这时,可以通过修改 /proc/sys/fs/inotify 目录下的文件或使用 sysctl 命令来临时或永久地调整这些限制。例如,如果要将 max_user_instances 调整为 10000,可以执行以下命令:

sudo sysctl -w fs.inotify.max_user_instances=10000

如果要将这个修改永久生效,可以将以下内容追加到 /etc/sysctl.conf 文件中:

fs.inotify.max_user_instances=10000

然后重新加载该文件:

sudo sysctl -p

同理,可以对 max_user_watchesmax_queued_events 进行类似的操作。需要注意的是,这些限制的调整应该根据实际的应用场景和系统资源来进行,不要盲目地增加,以免造成内存浪费或其他问题。

总结

本文介绍了 inotify 的原理、限制和解决方案,总之,尽管 inotify 在许多方面非常强大,但在使用时需要注意这些限制,以确保应用程序正常运行。