Применимость: Linux
Слова для поиска:
При ограниченных ресурсах получить максимальную производительность (доступность) сайта и устранить причину возникновения ошибки «Cannot allocate memory»
Иногда невозможно зайти в консоль сервера, в системном журнале сообщения
Cannot allocate memory: fork: Unable to fork new process
Проверьте последнюю колонку в выводе команды:
cat /proc/user_beancounters
Если значение не равно «0», то значит лимит превышен. Скорее всего это будет строка «privvmpages»
Если у вас физический сервер или используется виртуализация KVM (XEN), то при нехватке памяти процессы начинают вытесняться в медленную swap-память, это тормозит работу процессов, запросы клиентов становятся в очередь, и так нагрузка снижается сама собой. Наличие swap-памяти снижает необходимость оптимизации сервера, хотя и не избавляет от этого. Но это не работает на виртуализации OpenVZ с ядром 2.6.18-* Более свежее ядро 2.6.32 поддерживает псевдо swap (vswap), но еще недостаточно стабильно. Мы пытались его использовать, но количество сбоев в работе было слишком большим и мы вернулись к использованию стабильной версии 2.6.18.
На OpenVZ swap-память так же используется при нехватке памяти, но это работает на уровне мастер-машины (Hardware Node) при нехватке места для контейнеров.
Интенсивное использование swap-памяти для мастер-машины OpenVZ является аварийным режимом который никогда не должен допускаться. При этом работа контейнеров замедляется настолько, что их невозможно использовать.
Проблема обнаруживается по сообщениям в системном журнале со словами Out of memory или Cannot allocate memory
Иногда недостаток памяти приводит к невозможности зайти в консоль сервера, нет свободной памяти для этого.
Выполните команду vzubc и получите вывод подобный этому:
vzubc
BEANS FOR UID 309 resource held maxheld barrier limit failcnt kmemsize 11.60 mb 311.37 mb 1200.00 mb 1320.00 mb 0 lockedpages 38.01 mb 40.08 mb 49.15 mb 49.15 mb 0 privvmpages 573.53 mb 3395.43 mb 3072.00 mb 3379.20 mb 463849
Если на вашем сервере нет скрипта vzubc можно использовать команду:
cat /proc/user_beancounters
Этот способ менее удобен потому что информация будет смесью представлений из количества страниц памяти и байтов.
Есть несколько вариантов решения этой проблемы. В любом случае нам придется ограничить потребление памяти вебсервером и другими процессами.
Начните с отключения ненужных сервисов.
Довольно часто можно видеть болтающийся без дела демон ftp. Он потребляет немного, но иногда его атакуют и тогда он очень охотно пожирает память. И решите зачем он вам нужен в активном состоянии, можно его включать в случае необходимости, можно использовать sftp.
Отключите ненужные модули apache. Только убедитесь, что они вам не нужны. По крайней мере, надо проверить работоспособность после изменения параметров и перезапуска сервиса.
Скрипты сбора статистики типа Webalizer или AWstats - полезные инструменты, но так ли они нужны вам? Они способны очень сильно тормозить сервер если журналы большие.
Вебсервер должен одновременно обрабатывать большое количество подключений и запросов, что создает отдельные потоки команд и прочие необходимые элементы.
У сервера Apache2 мультипоточность реализована посредством подключаемых модулей многопоточной обработки - MPM. Существует две основных модели MPM модулей - это worker MPM и prefork MPM.
Определить какой модуль использует ваш сервер можно командой httpd -V или apache2 -V (в зависимости от операционной системы).
Но можно обойтись и без этой проверки.
В подавляющем количестве случаев используется prefork MPM
Worker MPM при запуске создает несколько дочерних процессов, по несколько потоков в каждом (сколько именно подразумевается под «несколько» задается в конфигурационном файле Apache.
В качестве преимущества данного модуля указывается пониженное потребление памяти по сравнению с Prefork модулем. Этот модуль рекомендуется для высоко нагруженных веб серверов и практически никогда не используется на виртуальных серверах.
Prefork MPM при запуске создает некоторое количество дочерних процессов, но в отличие от Worker каждый процесс обрабатывает только одно соединение. Cкорость обоих модулей соизмерима, Prefork потребляет больше памяти, но более стабилен, менее критичен к ошибкам вебприложений, не склонен к утечкам памяти.
Prefork MPM рекомендуется использовать там, где отладка мультипоточных приложений не реализована на должном уровне. Отладка мультипоточных приложений очень сложная и дорогая задача.
Решить задачу можно путем настройки лимитов вебсервера на количество соединений. Это ограничит количество запуcкаемых копий процессов (форков / fork).
Например ваша конфигурация (/etc/httpd/conf/httpd.conf) позволяет открытие до 1024 соединений одновременно.
<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 1024 MaxClients 1024 MaxRequestsPerChild 4000 </IfModule>
Каждое соединение требует отдельного процесса вебсервера. Каждый процесс httpd обычно требует 20-50Мб, а у вас всего 3072Мб и свободных 2700Гб Потому я поставил лимит 100.
Это не значит, что ваш сервер сможет обслуживать меньше клиентов. При недостатке памяти клиент получает обрыв связи и недоступность сервера, а при срабатывании MaxClients клиент просто ждет пару секунд когда появится свободный процесс httpd.
При таком варианте вы не теряете клиентов.
На самом деле это значение надо тщательно подбирать опытным путем наблюдая за счетчиком превышений и количеством свободной памяти.
Мой вариант конфигурации:
<IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 100 MaxClients 100 MaxRequestsPerChild 2000 </IfModule>
Я уменьшил значение MaxRequestsPerChild, это предотвратит рост размера процесса в памяти. Этот параметр определяет после какого количества запросов процесс будет перезапущен, что делается для исключения утечек памяти.
Но слишком частый перезапуск тоже требует ресурсов.
Здесь надо искать компромисс методом подбора.
И придется понаблюдать за результатом после каждого изменения.
Можете использовать нагрузочные тесты типа apache benchmark, но они неспособны имитировать реальную работу вашего сайта.
Радикальным методом борьбы с потреблением памяти является использование облегченных серверов NGINX или Lighttpd
Их можно использовать двумя способами:
Первый вариант используется когда вам не нужны особые возможности специфических возможностей модулей apache. Например аналога mod_secure для этих серверов не существует. Пример реализации первого способа вы найдете по ссылке внизу этой статьи.
Если без apache не обойтись, то используется 2-й вариант. Запросы клиентов принимает NGINX и перенаправляет их демону apache для обработки. Несмотря на лишнюю службу этот вариант экономит память, ведь количество подключений к apache ограничено одним NGINX, а NGINX не плодит свои копии.
Следует заметить, что не всегда 2-й способ дает ожидаемый эффект, но попытаться стоит.
На размер процесса вебсервера может влиять размер системного журнала. Иногда журнал вырастает до нескольких десятков гигабайт. Процесс, пытаясь выполнить запись о событии , открывает этот файл, что может потребовать больших системных ресурсов.
Проверьте - как настроен у вас демон logrotate, эффективно ли он обрабатывает ваши файлы логов и обрабатывает ли вообще?
Нужны ли вам журналы вебсервера? Может проще отключить?
Используйте поисковую службу для поиска специализированных услуг ускорения доступа к вашему сайту. Есть достаточно организаций специализирующихся на оптимизации вебсайтов и защите их от перегрузки.
Используйте службы CDN (сети доставки(дистрибуции) контента)
Приведу несколько примеров
Актуальность: 2011/11/03 09:39