Настройка «process manager(dynamic/static/ondemand)» для php-fpm в Unix/Linux

Настройка «process manager(dynamic/static/ondemand)» для php-fpm в Unix/Linux

Покопавшись у себя в черновиках, я нашел довольно интересную тему — настройка процесс менеджера для работы php-fpm и nginx. Я постараюсь рассказать как можно больше информации по этой теме. Расскажу на наглядных примерах что лучше и как считается некоторые важные параметры в php-fpm.

И так, что такое «process manager» в php-fpm? Process manager в php-fpm — это менеджер процессов для PHP-FPM, который создает и использует PHP процессы, чтобы получить максимальную отдачу от вашего сервера.

Разновидности Process manager в php-fpm:

  • dynamic — Имеет динамическое число pm.max_children (дочерние процессы). Которое изменяется и задается на основании: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.
  • static — Имеет фиксированное число pm.max_children (дочерние процессы).
  • ondemand — Дочерние процессы не запускаются с самого начала. Количество процессов, создаются по требованию (по мере появления запросов, в отличии от PM dynamic, когда запускается  заданное количество процессов, равное pm.start_servers, при старте службы.

Это 3 основных процесс менеджера для php-fpm-а.

Настройка process manager как dynamic для php-fpm в Unix/Linux

Стандартный менеджер процессов и он хорош тем, что имеет несколько PHP-FPM мастеров.

И так, редактируем свой пул и выставляем:

pm = dynamic

И так, сейчас можно определить максимальное количество процессов. Для этого имеется формула:

Total Max Processes = (Total Ram - (Used Ram + Buffer)) / (Memory per php process)

Предположим, что на сервере имеется 6Гб RAM, но посмотреть можно следующей утилитой:

# cat /proc/meminfo | grep -E 'MemTotal'
MemTotal:        6291456 kB

Проверяем сколько использует памяти PHP-FPM с помощью следующей команды:

# ps -aylC "php-fpm" | grep -Ev "grep" | sort -n | awk '{sum+=$8; ++n} END {print "Tot="sum"("n")";print "Avg="sum"/"n"="sum/n/1024"MB"}'
Tot=3126148(46)
Avg=3126148/46=66.3669MB

Чтобы вывести все php-fpm процессы, используйте:

# ps --no-headers -o "rss,cmd" -C php-fpm | sort -n | awk '{print $1/1024 " Mb"}'

Самый «жирный» процесс:

# ps --no-headers -o "rss,cmd" -C php-fpm | sort -n | awk '{print $1/1024,"Mb"}' | tail -n1

Еще один способ:

В 1-й вкладке запускаем:

# while true; do curl http://linux-notes.org &> /dev/null; sleep 1; done

Во 2-й вкладке запускаем проверку:

# ps aux | grep -E 'php-fpm'| grep -Ev "grep" | awk '{print $6/1024, "Mb"}'

Снова таки, я показал список всех процессов. Как правильно поступить и взять среднее значение или самое больше — решать вам. Нужно все тестировать! Количество памяти занятой процессами, можно проверить через утилиту ps_mem:

Установка ps_mem для проверки занятой памяти процессами в Unix/Linux

Тогда максимальное количество процессов можно посчитать (Я решил отдать под использование PHP всю RAM):

(1024*6) / 66 = 93.0909

Видим что можно использовать 93 max servers для php-fpm:

pm = dynamic
pm.max_children = 93 
pm.start_servers = 30
pm.min_spare_servers = 30
pm.max_spare_servers = 45 
pm.process_idle_timeout = 10s;

Главные параметры:

  • pm = dynamic — Как уже говорилось, это менеджер процессов.
    pm = dynamic
  • pm.max_children — Задается максимальное количество дочерних процессов (процессы-потомки), которые создаются PM.
    pm.max_children= (Общее количество виртуальной памяти)/(память выделенная 1 php процессу) = 93
  • pm.start_servers — Задается количество процессов-потомков, которые будут созданы PM при запуске PHP-FMP.
    pm.start_servers = ~(pm.max_children/3) = 31
  • pm.min_spare_servers — Задается количество процессов, которые должны оставаться в idle, как “запасные”, ожидая задач на выполнение, если количество меньше – будут созданы новые;
    pm.min_spare_servers = ( устанавливаю в 1 ядро) ИЛИ ~(pm.max_children/3) = 31
  • pm.max_spare_servers — наоборот, максимальное количество процессов, которые должны оставаться в idle,если количество больше – некоторые потомки будут уничтожены:
    pm.max_spare_servers = (общему количеству ядер) ИЛИ ~(pm.max_children/2) = 45
  • pm.max_requests – количество запросов процесса, после которого он будет пересоздан, полезно для предотвращения утечек памяти (memory-leak);
    pm.max_requests =  100000
  • pm.process_idle_timeout — время в секундах после чего простаивающий процесс будет удалён.
    pm.process_idle_timeout = 10s

Обратите внимание, что я не принял во внимание (Used Ram + Buffer). Это было бы нужно, если на сервере имелись базы данных:

# cat /proc/meminfo | grep -E '(MemTotal|MemFree|Cached)'
MemTotal:        6291456 kB
MemFree:         1678704 kB
Cached:          2205940 kB

Проверить использование буфера  и памяти, можно следующей командой:

# free -m
              total        used        free      shared  buff/cache   available
Mem:           6144        1521        1622         641        3000        3716
Swap:             0           0           0

Тогда, можно было бы пересчитать:

Total Max Processes = (6144 - (1521 + 3000)) / 66 = 24

Перезапускаем php-fpm службу:

$ sudo service php5-fpm restart

или

# service php-fpm restart

PS: Используйте команду в зависимости типа ОС.

Теперь будем использовать htop/top и ab чтобы проверить что и как работает.

Выполняем стрестест:

ab -n 10000 -c 500 http://localhost/index.php

Как-то так.

Имеется скрипт для рекомендаций:

# cd /usr/local/src && wget http://linux-notes.org/wp-content/uploads/scripts/php-fpm/php-fpmpal.sh -q -O - | bash

Дает вполне годные указания:

 (        )  (         (     (       *                      
 )\ )  ( /(  )\ )      )\ )  )\ )  (  `                 (   
(()/(  )\())(()/(     (()/( (()/(  )\))(             )  )\  
 /(_))((_)\  /(_))     /(_)) /(_))((_)()\  `  )   ( /( ((_) 
(_))   _((_)(_))      (_))_|(_))  (_()((_) /(/(   )(_)) _   
| _ \ | || || _ \ ___ | |_  | _ \ |  \/  |((_)_\ ((_)_ | |  
|  _/ | __ ||  _/|___|| __| |  _/ | |\/| || '_ \)/ _` || |  
|_|   |_||_||_|       |_|   |_|   |_|  |_|| .__/ \__,_||_|  
========================================= |_| =============


AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 31.187.70.238. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 31.187.70.238. Set the 'ServerName' directive globally to suppress this message
===== List of PHP-FPM pools =====
--- nagios ---
Configuration file: /etc/php-fpm.d/nagios.conf
List of processes: 53028 53029 53030 53031 53032
Number of processes: 5
Current max_children value: 50
Total memory usage for pool in KB: 54440
Average memory usage per process in KB: 10888
Total potential memory usage for pool (based on average process) (KB): 544400
Largest process in this pool is (KB): 10888
Total potential memory usage for pool (based on largest process) (KB): 544400

--- www ---
Configuration file: /etc/php-fpm.d/www.conf
List of processes: 53033 53034 53035 53036 53037 53038 53039 53040 53041 53042 53043 53044 53045 53046 53047 53048 53049 53050 53051 53052 53053 53054 53055 53056 53057 53058 53059 53060 53061 53062 53083 53119 53434 53491 61608 73379
Number of processes: 36
Current max_children value: 50
Total memory usage for pool in KB: 2295440
Average memory usage per process in KB: 63762
Total potential memory usage for pool (based on average process) (KB): 3188100
Largest process in this pool is (KB): 67792
Total potential memory usage for pool (based on largest process) (KB): 3389600

===== Server memory usage statistics =====
Total server memory in KB: 6291456
  =Total Apache memory usage in KB: 0
  =Total nginx memory usage in KB: 55868
  =Total Varnish memory usage in KB: 0 0
  =Total MySQL memory usage in KB: 201324.8
  =Total PHP-FPM memory usage in KB: 2349880

Memory available to assign to PHP-FPM pools in KB: 6099670 (total free memory + PHP-FPM's current memory usage)

Total potential PHP-FPM memory usage based on largest processes (KB): 3934000 (64.49%) ...GOOD :-)
Total potential PHP-FPM memory usage based on average process size (KB): 3732500 (61.19%) ...GOOD :-)

===== Recommendations per pool =====
-- nagios -- currently uses 54440 KB memory (2.31% of all PHP-FPM memory usage). It should be allowed to use about 140902 KB of all available memory. Its average process size is 10888 KB so this means max_children should be set to ~12. It is currently set to 50 (this can be changed in /etc/php-fpm.d/nagios.conf).
-- www -- currently uses 2295440 KB memory (97.68% of all PHP-FPM memory usage). It should be allowed to use about 5958157 KB of all available memory. Its average process size is 63762 KB so this means max_children should be set to ~93. It is currently set to 50 (this can be changed in /etc/php-fpm.d/www.conf).

===== Other considerations to take into account =====
From the PHP-FPM error logfiles (/var/log/php-fpm/error.log):
 - pool www had reached its max_children value of 50 on 2 occasion(s)

For these pools you may want to compare the recommended max_children value to this information, and decide whether the recommended value would be high enough to prevent max_children from being hit in future.

Note: It is not ideal to run PHP-FPMpal shortly after restarting PHP-FPM or your webservices. This is because PHP-FPMpal makes recommendations based on the average pool process size, and if PHP-FPM was restarted a short while ago then the likelihood is high that there won't have been many requests made to the sites since the restart, and metrics will be skewed and not show a normalised average.
It is also worth noting that if you've recently restarted any services that normally use up a large amount of memory then you probably want to wait a while before running PHP-FPMpal (e.g. if MySQL normally uses 50% of memory, but you've just restarted it then it may only use 10% of memory right now, thus the recommendations will be very skewed).

============================================================

Идем далее…

Настройка process manager как static для php-fpm в Unix/Linux

Статический менеджер процессов почти не используется, из-за того, что имеется 1 PHP-FPM master.

Открываем свой пул из php-fpm-а и меняем параметры:

pm = static
pm.max_children = 5

Перезапускаем php-fpm службу:

$ sudo service php5-fpm restart

или

# service php-fpm restart

PS: Используйте команду в зависимости типа ОС.

Выполняем стрестест:

# ab -n 1000 -c 10 http://localhost/index.php
# ab -n 5000 -c 20 http://localhost/index.php

Больше об утилите «ab» можно узнать в статье:

Проверка нагрузки на web-сервер с ab для Linux и Unix

Открываем конфигурационный файл для php-fpm пула. Его можно найти поискам ( если кто-то не знает где лежит он).

Раскомментируем строчку с  «pm.max_requests» опцией:

pm.max_requests = 500

Снова перезапускаем php-fpm и проверяем нагрузку:

# ab -n 5000 -c 20 http://localhost/index.php

Можно видеть,  что некоторые процессы — умерли, а затем некоторые процессы были убиты, а затем они сново породились!

Настройка process manager как ondemand для php-fpm в Unix/Linux

Самый продвинутый ( на мой взгляд) менеджер процессов. С названия очевидно, что он не оставляет процессы, но создает их, по мере необходимы.

Пример пула выглядит следующим образом:

[linux-notes.og]
user = www-data
group = www-data
listen = /var/run/php5-fpm/linux-notes.og/sock
listen.owner = www-data
listen.group = www-data
listen.mode = 770
chdir = /srv/www/wp-content/linux-notes.og/
pm = ondemand
pm.max_children = 5
pm.max_requests = 500

Главные параметры:

  • pm = ondemand — Как уже говорилось, это менеджер процессов.
    pm = ondemand
  • pm.max_children — Задаем максимальное число дочерних-процессов.
    pm.max_children= (Общее количество виртуальной памяти)/(память выделенная 1 php процессу) = 93
  • pm.process_idle_timeout — Задаем время в секундах после чего простаивающий процесс будет удалён.
    pm.process_idle_timeout = 10s
  • pm.max_requests — Задаем количество обработаных запросов, после которых процессы php-fpm будут перезагружены.
    pm.max_requests =  100000

Если вам нужна большая производительность, то менеджер процессов — «OnDemand» не подойдет вам. Тем не менее, на 90% случаев, конфигурация PHP-FPM в режиме OnDemand лучше, чем static или dynamic.

One thought on “Настройка «process manager(dynamic/static/ondemand)» для php-fpm в Unix/Linux

  1. Спасибо! Хорошая, полная статья, нашел то, что искал и познакомился с тюнером для php-fpm.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.