среда, 19 сентября 2012 г.

Рассчитываем параметры prefork.c для Apache в Linux

English: Logo for the Apache HTTPD Server Proj...

Не так давно мне пришлось настраивать LAMP кластер с балансером несколькими WEB нодами и одной базой данных. В отличие от не больших сайтов с низкой загруженностью, крупным проектам нужна более детальная настройка. В этой статье я собираюсь рассказать о настройке лишь одного модуля под названием prefork.c это один из нескольки multi-processing модулей для Apache httpd и самый распространённый по ряду причин. Во время своих изысканий, я перерыл очень много документации и статей в интернете основная часть которых сводилась к тому, что параметры prefork.c для каждого хоста следует выбирать тестовым путём. Вышеуказанное заявление не лишено смысла, универсальных настроек не существует, но оно не решает основной задачи: а что же делать конкретно мне прямо сейчас, особенно в условиях продакшн сервера. Я решил попытаться ответить на этот вопрос, и сделать максимально простое и универсальное средство для решения этой задачи.

Основная задача prefork.c это научить Apache обрабатывать большое количество запросов в несколько потоков, ведь чем больше параллельно обрабатываемых запросов, тем быстрее и больше запросов будет обработано. Но не стоит забывать что если мы запустим слишком много параллельных потоков, то мы выберем все ресурсы сервера и наш сервер не сможет с должной скоростью обрабатывать запросы, а в худшем случае вообще перестанет отвечать.

Чтобы выжать из системы максимум, и избежать эксцессов нужно учесть несколько факторов:
  1. Количество ОЗУ на сервере
  2. Сколько памяти в процентах мы готовы пожертвовать Apache
  3. Сколько кушает в среднем один htttpd
  4. Сколько мы можем запустить параллельно httpd чтобы не превысить пункт (2)
Формула расчёта максимального количества пользователей Apache выглядит примерно так:
(("вся папять"-"25%")/("вся память использованная для всех процессов httpd"/"количество httpd процессов"))
Для успешной работы скрипта у вас в системе должна быть установлена утилита bc

Приступим.
Запишите скрипт
cat > apache_prefork.sh <<EOF
#!/bin/bash
TotalMem=\$(free -m | grep Mem | awk '{ print \$2 }')
HttpMem=\$(ps aux | egrep 'httpd|apache2' | grep -v grep | awk '{sum +=\$6}; END {print sum}')
HttpCount=\$(ps aux | egrep 'httpd|apache2' | grep -v grep | wc -l)
Http1tread=\$(echo "\$HttpMem/\$HttpCount/1024" | bc)
HttpMaxTreads=\$(echo "\$TotalMem/100*75/\$Http1tread" | bc)

StartServers=\$(echo "\$HttpMaxTreads/5" | bc)
MinSpareServers=\$StartServers
MaxSpareServers=\$(echo "\$MinSpareServers*2" | bc)
ServerLimit=\$HttpMaxTreads
MaxClients=\$HttpMaxTreads
MaxRequestsPerChild=\$(echo "\$MaxClients*\$MinSpareServers" | bc)

echo -e "
<IfModule prefork.c>
StartServers\t    \$StartServers
MinSpareServers\t    \$MinSpareServers
MaxSpareServers\t    \$MaxSpareServers
ServerLimit\t    \$ServerLimit
MaxClients\t    \$MaxClients
MaxRequestsPerChild\t    \$MaxRequestsPerChild
</IfModule>
"
EOF

Для системы с 8-ми гигабайтами оперативной памяти, при условии что один трэд Apache употребляет примерно 50Мб у меня получились следующие значения.

Выполните скрипт.
bash ./apache_prefork.sh 

<IfModule prefork.c>
StartServers    23
MinSpareServers    23
MaxSpareServers    46
ServerLimit    116
MaxClients    116
MaxRequestsPerChild    2668
</IfModule>
То есть при пиковой нагрузке Apache не превысит следующего значения 50*116=5800Мб

Напоминаю что этот скрипт учитывает только Apache ноду. Если у вас на сервере стоят еще какие бы то ни было сервисы, то вам приедятся учесть их в формуле.

Пример формулы для связки Apache+MySQL:
(("вся папять"-"память потребляемая для MySQL при средней нагрузке"-"25%")/("вся память использованная для всех процессов httpd"/"количество httpd процессов"))
Enhanced by Zemanta