Масштабирование Nginx, PHP-FPM и MongoDB - PullRequest
8 голосов
/ 31 мая 2011

Я ищу лучший способ масштабирования PHP-приложения под Nginx с использованием PHP-FPM. Я смотрю на параллелизм около 1200. В настоящее время все, что больше 400, начинает получать медленное время отклика. Размер ответа, как правило, очень маленький, но некоторые могут быть довольно большими. Размеры запросов обычно невелики, за исключением нескольких избранных.

Все идет быстро, пока он не будет под большой нагрузкой. Время отклика составляет от 2 до 50 секунд. При небольшой нагрузке время отклика варьируется от 100 до 300 миллисекунд.

Настройка сервера - 2 сервера. Балансировщик нагрузки спереди, PHP-FPM, Nginx и MongoDB на обоих боксах. Один сервер запускает ведущий и арбитр mongod, а другой - ведомый (если не происходит аварийное переключение). Я знаю лучшие практики с Mongo, но у меня недостаточно серверов, чтобы иметь выделенные серверы баз данных.

В нем все еще мало свободного места, и средняя загрузка за 1 минуту никогда не превышает 0,7. Это 8 основных блоков с 16 гигабайтами оперативной памяти в каждой, так что это не должно быть узким местом. Mongo совсем не потеет, а Nginx и PHP-FPM тоже не кажутся. Я проверил верхнюю статистику и MongoDB, используя db.serverStatus ().

Мой вопрос, учитывая мой параллелизм, выглядят ли мои настройки Nginx fastcgi правильными, и есть ли что-то, что я могу упустить, даже если это не имеет никакого отношения к настройкам Nginx?

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

Замедлит ли низкий "ulimit -n" это? Mongo использует от 500 до 600 соединений при большой нагрузке. Настройки Ulimit следующие:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 147456
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 147456
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

К вашему сведению, я буду поднимать "ulimit -n" при нагрузочном тестировании для параллелизма 1200.

Заранее спасибо.

Ответы [ 2 ]

6 голосов
/ 01 июня 2011

Кажется, все, что потребовалось, было немного вычислений. Поскольку у меня доступно 8 ядер, я могу генерировать больше рабочих процессов nginx:

nginx.conf

worker_processes 4;
events {
    worker_connections 1024;
}

И 16 ГБ оперативной памяти предоставят место для статического количества рабочих php-fpm.

PHP-fpm.conf

pm = static
pm.max_children = 4096

Настройки Nginx fastcgi остались прежними. Вероятно, у меня немного больше настроек, так как при изменении настроек допустимый параллелизм оставался неизменным, пока нагрузка на сервер снижалась, но, похоже, это помогает, и, по крайней мере, является отправной точкой.

Один сервер, по-видимому, обрабатывает около 2000 одновременных операций, прежде чем нагрузка станет довольно высокой. ApacheBench начинает получать ошибки около 500 одновременных обращений, поэтому тестирование с использованием AB должно проводиться с нескольких серверов.

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

Надеюсь, это поможет другим.

3 голосов
/ 31 мая 2011

MongoDB здесь не является узким местом. Если вам нужно более 1200 одновременных подключений, PHP-FPM (и PHP в целом) может не стать инструментом для работы. На самом деле, поцарапайте это. Это НЕ правильный инструмент для работы. Многие тесты утверждают, что после 200-500 одновременных подключений nginx / PHP-FPM начинает давать сбои (см. здесь ).

В прошлом году я был в аналогичной ситуации, и вместо того, чтобы пытаться масштабировать немасштабируемое, я переписал приложение на Java, используя Kilim (проект, в который я также внес свой вклад). Еще один отличный выбор - это написать на Erlang (это то, что использует Facebook). Я настоятельно рекомендую вам переоценить ваш выбор языка и провести рефакторинг, пока не стало слишком поздно.

Предположим, что PHP-FPM работает нормально, с 1200, может быть, даже 1500 одновременными подключениями. Как насчет 2000? 5000? 10000? Абсолютно, однозначно, безусловно невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...