Очень часто при работе на высоконагруженных Linux серверах могут возникать ошибки “ too many open file s”. Это означает, что процесс открыл слишком много файлов (читай файловых дескрипторов) и не может открыть новые. В Linux ограничения “max open file limit“ установлены по умолчанию для каждого процесса и пользователя, и они не слишком высокие.
В данной статье мы рассмотрим, как проверить текущие ограничения на количество открытых файлов в Linux, как изменить этот параметр для всего сервера, для отдельных сервисов и для сеанса. Статья применима для большинства современных дистрибутивов Linux (Debian, Ubuntu, CentOS, RHEL, Oracle Linux, Rocky и т.д.)
Чаще всего ошибку “too many open files“. Чаще всего эта ошибка встречается на серверах с установленным веб-сервером NGINX/httpd, сервером БД (MySQL/ MariaDB / PostgreSQL ), при чтении большого количества логов. Например, когда веб-серверу Nginx не хватает лимита для открытия файлов, вы получите ошибку:
socket () failed (24: Too many open files) while connecting to upstream
Или:
HTTP: Accept error: accept tcp [::]:<port_number>: accept4: too many open files.
В Python:
OSError: [Errno 24] Too many open files.
Максимально количество файловых дескрипторов, которые могут быть открыты в вашей файловой системе всеми процессами можно узнать так:
# cat /proc/sys/fs/file-max
Чтобы узнать, сколько файлов открыто сейчас, выполните:
$ cat /proc/sys/fs/file-nr
7744 521 92233720
В Linux ограничение на максимальное количество открытых файлов можно натсроить на нескольких уровнях:
Чтобы вывести текущее ограничение на количество открытых файлов в ядре Linux, выполните:
# sysctl fs.file-max
fs.file-max = 92233720
Выведем ограничение на количество открытых файлов для одного процесса текущего пользователя:
# ulimit -n
По умолчанию количество файлов для одного процесса этого ограничено числом 1024.
Выведем максимальное количество для одного пользователя (max user processes):
# ulimit –u
5041
Умножаем 1024 * 5041 дает нам 5161984 – это максимально количество открытых файлов всеми процессами пользователя.
В Linux есть два типа ограничений на количество открытых файлов: Hard и Soft . Soft ограничения носят рекомендательный характер, при превышении значения пользователь будет получать предупреждения. Если количество открытых файлов превысило hard лимит, пользователь не сможет открыть новые файлы пока не будет закрыты ранее открытые.
Для просмотра текущих лимитов используется команда ulimit с опцией -S
(soft) или -H
(hard) и параметром -n
(the maximum number of open file descriptors).
Для вывода Soft-ограничения:
# ulimit -Sn
Для вывода Hard-ограничения:
# ulimit -Hn
Чтобы разрешить всем сервисам открывать большее количество файлов, можно изменить лимиты на уровне всей ОС Linux. Чтобы новые настройки работали постоянно и не сбрасывались при перезапуске сервера или сессии, нужно поправить файл /etc/security/limits.conf. Строки с разрешениями выглядит так:
Имя_пользователя тип_огрничение название_ограничения значение
Например:
apache hard nofile 978160_x000D_apache soft nofile 978160
Вместо имени пользователя можно указать *
. Это означает, что это ограничение будет применяться для всех пользователей Linux:
* hard nofile 97816_x000D_* soft nofile 97816
Например, вы получили ошибку too many open files для nginx. Проверьте, сколько файлов разрешено открывать процессу этому пользователю:
$ sudo -u nginx bash -c 'ulimit -n'
1024
Для нагруженного сервера этого недостаточно. Добавьте в /etc/security/limits.conf строки
nginx hard nofile 50000_x000D_nginx soft nofile 50000
В старых ядрах Linux значение fs.file-max может быть равно 10000. Поэтому проверьте это значение и увеличьте его, чтобы оно было больше чем ограничение в limits.conf:
# sysctl -w fs.file-max=500000
fs.file-max = 500000
Проверьте, что в файле /etc/pam.d/common-session (Debian/Ubuntu или /etc/pam.d/login для CentOS/RedHat/Fedora) есть строчка:
session required pam_limits.so
Если нет, добавьте ее в конец. Она нужна, чтобы ограничения загружались при авторизации пользователя.
После изменений, перезапустите терминал и проверьте значение лимита max_open_files:
# ulimit -n
97816
Вы можете изменить лимит на количество открытых файловых дескрипторов для конкретного сервиса, а не для всей системы. Рассмотрим на примере apache. Чтобы изменить значения, откройте настройки службы через systemctl :
# systemctl edit httpd.service
Добавьте необходимые лимиты, например:
[Service]_x000D_LimitNOFILE=16000_x000D_LimitNOFILESoft=16000
После изменения, нужно обновить конфигурацию сервиса и перезапустить его:
# systemctl daemon-reload
# systemctl restart httpd.service
Чтобы проверить, изменились ли значения, нужно получить PID сервиса:
# systemctl status httpd.service
Например, вы определил PID сервиса 32724:
# cat /proc/32724/limits | grep "Max open files”
Значение должно быть 16000.
Так вы изменили значения Max open files для конкретного сервиса.
После того, как вы увеличил ограничения на количество открытых файлов для сервера, нужно также поправить конфигурационный файл службы. Например, для веб-сервера Nginx в файле конфигурации /etc/nginx/nginx.conf нужно задать значение в директиве:
worker_rlimit_nofile 16000
RLIMIT_NOFILE
). В Nginx файловые дескрипторы нужны для возврата статического файла из кэша для каждого подключения клиента. Чем больше пользователей использует ваш сервер и чем больше статических файлов отдает nginx, тем большее количество дескрипторов используется. Сверху максимальное количество дескрипторов ограничивается на уровне ОС и/или сервиса. При превышении количеств открытых файлов nginx появится ошибка socket() failed (24: Too many open files) while connecting to upstream
. После чего выполнить рестарт Nginx:
# nginx -t && service nginx -s reload
# su nginx
# ulimit –Hn
# for pid in `pidof nginx`; do echo "$(< /proc/$pid/cmdline)"; egrep 'files|Limit' /proc/$pid/limits; echo "Currently open files: $(ls -1 /proc/$pid/fd | wc -l)"; echo; done
Для apache, нужно создать директорию:
# mkdir /lib/systemd/system/httpd.service.d/
После этого создайте файл limit_nofile.conf:
# nano /lib/systemd/system/httpd.service.d/limit_nofile.conf
И добавьте в него:
[Service]_x000D_LimitNOFILE=16000
Не забудьте перезапустить сервис httpd.
Чтобы изменить лимиты на открытые файлы в рамках текущей сессии пользователя, выполните команду:
# ulimit -n 3000
Если указать здесь значение большее, чем заданное в hard limit, появится ошибка:
-bash: ulimit: open files: cannot modify limit: Operation not permitted
Когда вы завершите текущую сессию терминала и откроете новую, лимиты вернутся к начальным значениям, указанным в файле /etc/security/limits.conf .
В данной статье мы разобрались, как решить проблему с недостаточным лимитом для открытых файловых дескрипторов в Linux и рассмотрели несколько вариантов изменения лимитов на сервере.
Некоторые пользователи, экспериментируя с конфигурацией системы в окне msconfig могут столкнуться с ситуацией, когда после…
На сайте не раз публиковались обзоры программ, предназначенных для очистки или настройки последних версий Windows.…
При установке некоторых обновлений Windows 11, имеющих в названии «Предварительный просмотр накопительного обновления», многие пользователи…
Некоторые пользователи Windows 11, 10 и предыдущих версий системы могут столкнуться с ситуацией, когда исполняемые…
При установке обновлений Windows 11/10 некоторые пользователи могут столкнуться с ошибкой с кодом 0x800705b4 и…
Пользователи Windows 11 могут столкнуться с сообщением «Обслуживание вашей версии Windows окончено» (Your version of…