|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
И при [pm = static] , и при [pm = dynamic] наблюдается следующая картина: после отработки скрипта память, занимаемая этим скриптом не освобождается. То, что процесс после отработки не удаляется - это нормально и соответствует логике работы php-fpm в указанных режимах. Но смущает то, что этот простаивающий (ожидающий) процесс после отработки занимает столько же памяти, сколько занимал в процессе работы. На рядовых запросах проблем не наблюдается, поскольку режим работы и параметры создания/уничтожения процессов задаются таким образом, чтобы у сервера хватало памяти на одновременную работу максимально допустимого числа процессов. Но если выполняется "тяжёлый" скрипт, потребляющий много памяти (это может быть тяжёлый рядовой запрос в режиме генерации кэша или некоторый сервисный скрипт), то после его отработки php-процесс, его обслуживший, сохраняет такое же большое потребление памяти. Далее запускается аналогичный тяжёлый скрипт, выполнение которого поручается другому простаивающему (ожидающему) процессу. После отработки скрипта этот процесс также сохраняет большое потребление памяти. Мы уже получили два простаивающих процесса, каждый из которых выполнил тяжёлый скрипт и каждый из которых потребляет много памяти. Если далее снова запускается тяжёлый скрипт и обслуживается третьим процессом, то память сервера заканчивается, начинает работать своп или генерируется ошибка 502 bad gateway . Можно ли решить проблему неосвобождения памяти процессом, который завершил выполнение скрипта и остаётся в памяти в качестве ожидающего ? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 17:43 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторНо если выполняется "тяжёлый" скрипт, потребляющий много памяти ..., то после его отработки php-процесс, его обслуживший, сохраняет такое же большое потребление памяти. Далее запускается аналогичный тяжёлый скрипт, выполнение которого поручается другому простаивающему (ожидающему) процессу При выполнении вторым рабочим процессом некоторого тяжёлого скрипта потребление памяти первым процессом (который уже выполнил свой тяжёлый скрипт и ожидает следующих запросов) либо не уменьшается, либо уменьшается не намного. В итоге при последовательном запуске тяжёлых скриптов потребление памяти системой только растёт - дело доходит до свопа и 502 ошибки. Если в htop удалять (kill) php-процессы, то большой объём памяти, ими занимаемой, освобождается. Если установить режим [pm = omdemand] (процессы создаются только при необходимости, простаивающих процессов нет), проблем с памятью, естественно, не наблюдается, т.к. простаивающие процессы отсутствуют. Т.е. проблема именно в том, что выполнившие скрипт ожидающие процессы не освобождают память, которая использовалась скриптом в момент выполнения. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 17:50 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторПри выполнении вторым рабочим процессом некоторого тяжёлого скрипта потребление памяти первым процессом (который уже выполнил свой тяжёлый скрипт и ожидает следующих запросов) либо не уменьшается, либо уменьшается не намного И если далее такому процессу (который выполнил тяжёлый скрипт и занимает много памяти) "скормить" лёгкий скрипт, требующий мало памяти, то память, потребляемая этим процессом не уменьшается. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 18:07 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
Столько текста даже читать лень. Конфиг fpm в студию. Интересует блок pm_ ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 18:11 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
А если вызвать принудительно сборщик мусора? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 18:12 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторСтолько текста даже читать лень.Для понимания проблемы вполне достаточно прочитать заголовок темы. Почему память, выделяемая в процессе работы скрипта, не освобождается после отработки скрипта. Т.е. после отработки скрипта процесс, выполнивший скрипт, занимает тот же самый объём памяти. И не виртуальной, а физической, которую при необходимости/нехватке не могут использовать другие процессы (о чём свидетельствует активный swop и в конце концов 502 ошибка). авторКонфиг fpm в студию. Интересует блок pm_ Памяти всего 512 Мб (и своп на 2 Гб), поэтому процессов всего 4 (проблема наблюдается при любом числе процессов - с любым простаивающим процессом, выполнившим некоторый скрипт). Конфигурация следующая: Код: php 1. 2. 3. 4. 5. 6.
Как я написал выше, при [pm = static] наблюдается та же проблема: после выполнения процессом скрипта этот процесс память не освобождает. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 22:00 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторА если вызвать принудительно сборщик мусора? PHP не предоставляет возможности принудительного вызова сборщика мусора. Процесс сборки мусора можно лишь косвенно инициировать освобождением (очисткой) переменной/массива оператором unset (либо вызовом деструктора для объектов). Но такие действия не всегда приводят к немедленному вызову сборщика мусора (к немедленному физическому освобождению памяти). Проверил - выполнил unset на большом массиве, который использует скрипт. Эффекта никакого. Более того, как я написал выше, если такой процесс (который выполнил тяжёлый скрипт и продолжает занимать много памяти) далее выполнит лёгкий скрипт, то объём памяти, занимаемый этим процессом, не уменьшается. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 22:14 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
Для всех, кто заглянул в эту тему: 1) в настройках php-fpm прописываем [pm = static] или [pm = dynamic] + [pm.min_spare_servers > 1] (т.е. 2 или более простаивающих (запасных) процесса) 2) перезапускаем php-fpm , запускаем htop и смотрим на рабочие процессы (воркеры) php-fpm - они все занимают 0 Мб (столбец MEM ) 3) запускаем любой скрипт и снова смотрим на тот процесс, который обрабатывает этот скрипт (у этого процесса CPU > 0) 4) после завершения работы скрипта смотрим, сколько потребляет процесс, выполнивший скрипт - 0 Мб или нет ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 22:20 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
http://php.net/manual/ru/function.gc-collect-cycles.php Еще какой-нибудь опкешер может свой кеш держать, подозреваю. ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 22:59 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
Сколько процесс занимает? ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 23:00 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторЕще какой-нибудь опкешер может свой кеш держать, подозреваю.Используется opcache , но его отключение проблему не решает. Проверял дважды - перед созданием темы и сейчас ещё раз. авторА если вызвать принудительно сборщик мусора? http://php.net/manual/ru/function.gc-collect-cycles.php Добавил вызов функции gc_collect_cycles() в конце скрипта (на внешнем уровне, где никакие переменные и массивы не используются - только вызовы методов). В итоге никакого эффекта. Процессы, выполнившие скрипт, по-прежнему занимают тот же объём памяти, что и во время выполнения скрипта (функция всё время возвращает 0, впрочем, согласно справке, это не число освобождённых фрагментов памяти, а число циклических ссылок, отсутствие которых не говорит о том, был ли освобождён какой ли объём памяти или нет). Дополнительно к вызову функции gc_collect_cycles() в конце скрипта отключил opcache . Не помогает... ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 23:48 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторСколько процесс занимает? Ровно столько же, сколько памяти расходует скрипт в процессе выполнения (пиковый объём памяти, потребляемый скриптом и фиксируемый функцией memory_get_peak_usage(true) ). ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 23:52 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторЕще какой-нибудь опкешер может свой кеш держать, подозреваю. Даже если предположить, что та память, которую занимает рабочий процесс (воркер) после отработки скрипта, - это память opcache , то при повторном запуске того же тяжёлого скрипта и выполнения его вторым свободным процессом этот самый второй процесс (после выполнения скрипта) уже не должен занимать тот же объём памяти, что и первый. А занимает... ... |
|||
:
Нравится:
Не нравится:
|
|||
30.05.2018, 23:57 |
|
php-fpm: простаивающие (запасные) процессы после отработки не освобождают память
|
|||
---|---|---|---|
#18+
авторА если вызвать принудительно сборщик мусора? http://php.net/manual/ru/function.gc-collect-cycles.php Функция gc_collect_cycles() выполняет только одну функцию - ищет циклические ссылки и помечает их как "мусор". Но физическим освобождением памяти не занимается. Т.е. если ранее в коде был выполнен оператор unset() или вызван деструктор объекта или был выполнен выход из функции/метода (с освобождением локальных переменных) и при этом память, соответствующая освобождённым (уничтоженным) переменным/массивам/объектам физически сразу не была освобождена, то вызов этой функции к физическому освобождению памяти не приведёт. ... |
|||
:
Нравится:
Не нравится:
|
|||
31.05.2018, 15:06 |
|
|
start [/forum/topic.php?fid=23&msg=39652855&tid=1460281]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
1ms |
others: | 325ms |
total: | 463ms |
0 / 0 |