У нас есть мощный сайт на Drupal, который выполняет финансовое моделирование. Похоже, что мы сталкиваемся с какой-то утечкой памяти, учитывая тот факт, что со временем объем памяти, используемый apache, увеличивается, в то время как количество процессов apache остается стабильным:
Мы знаем, что проблема с памятью исходит от apache / PHP, потому что всякий раз, когда мы выдаем /etc/init.d/httpd reload
использование памяти падает (см. снимок экрана выше и ниже выходы интерфейса командной строки):
Перед перезагрузкой httpd
$ free total used free shared buffers cached Mem: 49447692 45926468 3521224 0 191100 22609728 -/+ buffers/cache: 23125640 26322052 Swap: 2097144 536552 1560592
После перезагрузки httpd
$ free total used free shared buffers cached Mem: 49447692 28905752 20541940 0 191360 22598428 -/+ buffers/cache: 6115964 43331728 Swap: 2097144 536552 1560592
Каждому потоку apache назначается PHP memory_limit
512 МБ, что объясняет высокое использование памяти при низком объеме запросов, и max_execution_time
120 секунд, что должно завершать потоки, выполнение которых занимает больше времени, и, следовательно, должно предотвращать постоянный рост использования памяти, который мы наблюдаем.
В: Как мы можем выяснить, что вызывает эту утечку памяти?
В идеале я ищу шаги по устранению неполадок, которые я могу выполнить в системе, не беспокоя команду разработчиков.
Дополнительная информация:
OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6
К вашему сведению, нам известно о проблеме подкачки, которую мы исследуем отдельно, и не имеет ничего общего с утечкой памяти, которую мы наблюдали до того, как подкачка начала происходить.
Мы знаем, что проблема с памятью исходит от apache / PHP, потому что всякий раз, когда мы запускаем /etc/init.d/httpd перезагрузку, использование памяти падает.
Нет - это просто означает, что это связано с веб-трафиком. Вы также упомянули, что запускаете mysql в ящике - предположительно, управляете данными для веб-сервера - с таким же успехом он может быть виновником. Как и другие службы, которые использует ваш веб-стек, о которых вы не упомянули.
Каждому потоку apache назначается PHP memory_limit 512 МБ, что объясняет
Нет, это не так. Вы сообщаете в среднем о 7 и максимум о 25 загруженных серверах, но график вашей памяти показывает дельту около 25 ГБ.
На самом деле вам следует начать снова с базовой настройки HTTP - похоже, вы используете постоянный 256 httpds, но ваше пиковое использование составляет 25 - это просто глупо.
и max_execution_time в 120 секунд, который должен завершать потоки, выполнение которых занимает больше времени
Нет - только если поток выполнения находится в интерпретаторе PHP - не если PHP заблокирован.
который выполняет финансовое моделирование
(вздох)
Было бы полезно, если бы вы предоставили подробную информацию о том, как вы настроили Apache, многопоточную или предварительную версию, какую версию, как вызывается PHP (модуль, cgi, fastcgi), используете ли вы постоянные соединения, используете ли вы хранимые процедуры.
Я бы посоветовал вам начать с перемещения mysql на отдельную машину и прекратить использование постоянных соединений (если вы в настоящее время их используете). Установите предел памяти много понизьте и переопределите это для каждого сценария. Убедитесь, что у вас установлен и настроен сборщик мусора с циклическими ссылками.
Вы, наверное, уже решили свою проблему. В качестве промежутка времени, чтобы сервер не менял местами / сбивал, я каждый час запускаю следующую команду из cron:
#!/bin/sh
sync; echo 3 > /proc/sys/vm/drop_caches
Я не говорю, что это решение, просто способ сохранить работу и свести к минимуму замедление работы по мере выяснения фактической причины утечки памяти.
Более подробную информацию можно найти здесь.
http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/
По-видимому, именно так работает PHP - и если вы выполняете длинные циклы, в которых вы выделяете объекты и кто знает, передаете ли вы их также через ссылку, поэтому единственный способ справиться с этим - это после N запросов для каждого процесса PHP чтобы остановить это. Если вы запускаете PHP как CGI, каждый запрос вызывает его возрождение - поэтому утечки памяти нет, и падение производительности может быть не таким большим. Вы также можете запустить fast-cgi, где, например, каждые 1000 запросов процесс php-fcgi завершается, и его память высвобождается - снова нет утечки памяти. Если вы запускаете PHP как модуль mod_php, вы можете попытаться настроить maxrequests в httpd.conf, чтобы узнать, поможет ли это. Я бы попытался настроить, например, 10 - если это сработает, падение производительности не будет высоким, но утечек памяти быть не должно, даже при сильном скачке, когда используются все 250 httpd (10 * 250 = 2500 - на каждые 10 МБ памяти приходится 25 ГБ - так что, возможно, если у вас нет 128 ГБ ОЗУ, попробуйте также снизить количество процессов httpd, например, до 50).
Проверьте память в глобальном файле php.ini. не делайте это просто так, как 1 G и т. д. Я очень рекомендую, чтобы в эту учетную запись был добавлен локальный php.ini, чтобы не повлиять на весь сервер. Я бы порекомендовал установить глобальный лимит php.ini примерно на 64 МБ, поскольку этого обычно достаточно для большинства учетных записей.
тоже проверьте настройки apache