Ошибка «Too many open files» в Linux

.
Время чтения — 3 мин.
linux pam kernel

Ошибка «Too many open files» означает, что процесс исчерпал доступные для него ресурсы по максимальному количеству открытых файлов. Простыми словами — процессу было разрешено открыть максимум 100 файлов, а он попытался открыть 101-й.

Далее — разберёмся как работает это ограничение в операционных системах Linux. Все пути будут указаны для CentOS\RHEL-образных систем.

Ограничения ядра Linux

Прежде всего ограничение на количество открытых файлов устанавливает ядро операционной системы. Посмотреть его можно вот так:

[root@dracula ~]# sysctl fs.file-max
fs.file-max = 3000000

Это суммарное значение на всю операционную систему. Чтобы посмотреть сколько сейчас открыто файлов достаточно прочитать файл /proc/sys/fs/file-nr:

$ cat /proc/sys/fs/file-nr
1154    133     3000000

PAM

PAM (Pluggable Authentication Modules for Linux) — это набор динамически-подключаемых библиотек для аутентификации пользователей.

Конфигурация для PAM хранится в следующих каталогах и файлах:

Формат записи такой:

nginx           soft   nofile 50000
nginx           hard   nofile 50000

Существует два вида ограничений: soft (мягкий) и hard (жесткий). Soft-ограничения носят рекомендательный характер, в отличие от hard-ограничений. Процесс пользователя который превысил допустимое количество открытых файлов (nofile) по hard-ограничению не сможет открывать новые файлы, до тех пор пока не закроет как минимум один из ранее открытых.

Процесс, ядро и PAM

Все что описано выше показано на схеме:

alt text

Стартует процесс, при каждой попытке открыть файл ядро операционной системы проверяет не исчерпан ли общий лимит. Далее — если процесс поддерживает PAM, делается вызов через библиотеку, не исчерпались ли лимиты.

Если процесс не поддерживает PAM, какие бы лимиты ему не установили в конфигурационных файлах, он будет их игнорировать.

Ошибка «Too many open files»

Например, мы получили такую ошибку для nginx. Nginx поддерживает PAM, поэтому на него влияют настройки в /etc/security/limits.conf и упомянутых выше файлах.

Смотрим сколько пользователю nginx разрешено:

$ sudo -u nginx bash -c 'ulimit -n'

1024

Видимо что всего лишь 1024, для нагруженного сервера это может быть недостаточным. Добавляем в /etc/security/limits.conf строчки:

nginx           soft   nofile 10000
nginx           hard   nofile 10000

Тем самым разрешая лимит до 10000 файлов.

В старых ядрах Linux значение fs.file-max может быть равно 10000. Если требуется дать nginx больше 10000 файлов, то необходимо добавить в /etc/sysctl.conf значение с запасом:

fs.file-max = 100000

Операционная система перечитает пераметр при следующей загрузке. Чтобы не ждать ближайшей перезагрузки и применить его «на лету», делаем вот так:

$ sysctl -w fs.file-max=100000

В отличие от первого способа, эта настройка будет актуальна до первой перезагрузки операционной системы.

После изменения настроек в конфигурации ядра и PAM необходимо перезапустить процесс nginx.

Полезные ссылки