Как исследовать утечку памяти с помощью Apache и PHP?

16

У нас есть тяжелый сайт Drupal, который выполняет финансовое моделирование. Похоже, что мы сталкиваемся с некоторой утечкой памяти, учитывая тот факт, что со временем память, используемая apache, растет, а число процессов apache остается стабильным:

введите описание изображения здесь

введите описание изображения здесь

Мы знаем, что проблема с памятью исходит от apache / PHP, потому что всякий раз, когда мы выдаем использование /etc/init.d/httpd reloadпамяти, падает (см. Скриншот выше и результаты CLI):

Перед перезагрузкой httpd

$ бесплатно
             общее количество использованных свободных общих буферов в кеше
Mem: 49447692 45926468 3521224 0 191100 22609728
- / + буферы / кэш: 23125640 26322052
Своп: 2097144 536552 1560592

После перезагрузки httpd

$ бесплатно
             общее количество использованных свободных общих буферов в кеше
Mem: 49447692 28905752 20541940 0 191360 22598428
- / + буферы / кэш: 6115964 43331728
Своп: 2097144 536552 1560592

Каждому потоку apache назначается PHP memory_limitобъемом 512 МБ, что объясняет высокий уровень использования памяти, что объясняет низкий объем запросов, и значение max_execution_time120 секунд, которое должно завершать потоки, выполнение которых занимает больше времени, и, следовательно, должно предотвращать постоянный рост использования памяти. видя.

В: Как мы можем выяснить, что является причиной этой утечки памяти?

В идеале я ищу шаги по устранению неполадок, которые я могу выполнить в системе, не беспокоя команду разработчиков.

Дополнительная информация:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

К вашему сведению, мы знаем о проблеме подкачки, которую мы исследуем отдельно, и не имеет ничего общего с утечкой памяти, которую мы наблюдали до того, как перестановка начала происходить.

Максимум
источник
В последний раз я столкнулся с серьезной проблемой использования памяти с LAMP + Drupal, когда у меня была PHP-библиотека memcached. После того, как я забрал его, использование памяти резко упало. Просто предположение. Могу набрать правильный ответ для вас чуть позже.
Янне Пиккарайнен
@JannePikkarainen: мы используем memcachedбиблиотеку PHP . Основываясь на странице администратора memcache memcache.php, все, что мы можем видеть, это то, что мы выделили 5GBдля memcache, из которого 3.3GBиспользуется. Было бы здорово, если бы вы могли помочь нам здесь.
Макс
Да, сам memcachedдемон, вероятно, в порядке. Это библиотека memcache PHP, которая может или не может утечь память (и, следовательно, увеличить использование памяти процессами Apache). Моя проблема была примерно 1-2 года назад, поэтому все могло быть исправлено после этого. В любом случае, если memcached не является обязательным для вас, попробуйте отключить его на некоторое время и посмотреть, продолжает ли расти использование памяти Apache.
Янне Пиккарайнен
В чем собственно проблема? Плохая производительность? Вы рассказываете нам симптомы, не объясняя, какую проблему мы должны помочь вам решить. (И о какой проблеме обмена вы говорите? Вы так сильно
David Schwartz
@DavidSchwartz: проблема в том, что, если мы не перезапускаем httpd, использование памяти продолжает расти, и коробка в конечном итоге падает с некоторыми сообщениями ядра из нехватки памяти. Производительность хорошая (пока использование памяти не приближается к пределу памяти). Пожалуйста, игнорируйте проблему обмена.
Макс

Ответы:

11

Мы знаем, что проблема с памятью исходит от 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, Thread или Prefork, какую версию, как вызывается PHP (module, cgi, fastcgi), используете ли вы постоянные соединения, используете ли вы хранимые процедуры.

Я бы посоветовал вам начать с перемещения mysql на отдельную машину и прекратить использовать постоянные соединения (если вы используете их в настоящее время). Установите намного меньший предел памяти и переопределите его для каждого сценария. Убедитесь, что у вас установлен и настроен сборщик мусора с циклической ссылкой.

symcbean
источник
2

Вы, наверное, уже решили свою проблему. В качестве временного интервала, чтобы предотвратить перестановку / перегрузку сервера, я запускаю следующую команду из 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/

Патрик
источник
1

Очевидно, именно так работает PHP - и если вы делаете длинные циклы, когда вы размещаете объекты и кто знает, передаете ли вы их также через ссылку, то единственный способ справиться с этим - это после N запросов для каждого процесса PHP чтобы остановить это. Если вы запускаете PHP как CGI, каждый запрос вызывает его повторное появление - поэтому утечки памяти нет, и падение производительности может быть не таким большим. Вы также можете запустить fast-cgi, где, например, каждые 1000 запросов процесс php-fcgi завершается, и его память освобождается - опять же, нет утечки памяти. Если вы запускаете PHP как модуль mod_php, вы можете попытаться настроить maxrequests в httpd.conf, чтобы посмотреть, поможет ли это. Я бы попытался настроить, например, 10 - если это будет работать, падение производительности не будет высоким, но не должно быть утечек памяти,

Эндрю Смит
источник
-1

Проверьте память в глобальном файле php.ini. не просто decalre valure, как 1 G и т. д. Я очень рекомендую, чтобы локальный php.ini был введен в эту учетную запись, чтобы не влиять на весь сервер. Я бы порекомендовал установить глобальный лимит php.ini около 64M, так как этого обычно достаточно для большинства аккаунтов.

проверьте настройки apache тоже

Нихил Бабу
источник