Почему работа не распределяется между рабочими-оружейниками равномерно?

Я запускаю свое большое общедоступное веб-приложение. Это внутренний сервер Python HTTP, который отвечает на тысячи HTTP-запросов в минуту. Это написано с Flask & SQLAlchemy. Приложение работает на EC2 в AWS. Тип экземпляра c3.2xlarge (он имеет 8 процессоров).

Я использую Gunicorn в качестве своего веб-сервера. Gunicorn имеет 17 рабочих процессов и 1 мастер-процесс. Ниже вы можете увидеть 17 рабочих-оружейников:

$ sudo ps -aefF | grep gunicorn | grep worker | wc -l
17

$ sudo ps -aefF --sort -rss | grep gunicorn | grep worker
UID       PID  PPID  C      SZ     RSS PSR STIME TTY     TIME                           CMD
my-user 15708 26468  6 1000306 3648504   1 Oct06   ? 08:46:19 gunicorn: worker [my-service]
my-user 23004 26468  1  320150  927524   0 Oct07   ? 02:07:55 gunicorn: worker [my-service]
my-user 26564 26468  0  273339  740200   3 Oct04   ? 01:43:20 gunicorn: worker [my-service]
my-user 26562 26468  0  135113  260468   4 Oct04   ? 00:29:40 gunicorn: worker [my-service]
my-user 26558 26468  0  109946  159696   7 Oct04   ? 00:15:14 gunicorn: worker [my-service]
my-user 26556 26468  0  125294  148180   6 Oct04   ? 00:13:07 gunicorn: worker [my-service]
my-user 26554 26468  0  120434  128016   5 Oct04   ? 00:10:13 gunicorn: worker [my-service]
my-user 26552 26468  0   99233  116832   5 Oct04   ? 00:08:24 gunicorn: worker [my-service]
my-user 26550 26468  0   94334   96784   0 Oct04   ? 00:05:28 gunicorn: worker [my-service]
my-user 26548 26468  0   92865   90512   2 Oct04   ? 00:04:47 gunicorn: worker [my-service]
my-user 27887 26468  1   91945   86564   0 17:44   ? 00:02:57 gunicorn: worker [my-service]
my-user 26546 26468  0  127841   84464   5 Oct04   ? 00:03:39 gunicorn: worker [my-service]
my-user 26544 26468  0   90290   80736   2 Oct04   ? 00:03:12 gunicorn: worker [my-service]
my-user 26540 26468  0  107669   78176   5 Oct04   ? 00:02:33 gunicorn: worker [my-service]
my-user 26542 26468  0   89446   76616   5 Oct04   ? 00:02:49 gunicorn: worker [my-service]
my-user 26538 26468  0   88056   72028   5 Oct04   ? 00:02:02 gunicorn: worker [my-service]
my-user 26510 26468  0  106046   70836   2 Oct04   ? 00:01:49 gunicorn: worker [my-service]

Я изучаю журналы всех HTTP-запросов, поступивших за последние 7 дней. Я сгруппировал и суммировал запросы по идентификатору процесса, который вы видите во мне ps Команда выше. Ниже вы можете увидеть результирующий график.

Как видите, 5 рабочих-оружейников выполняют почти 100% работы. Остальные 12 в основном простаивают. И из этих 5 один рабочий (PID #15708) выполняет большую часть работы.

Почему это происходит? Я хотел бы понять алгоритм, который Gunicorn использует для распределения работы среди своих работников. Это определенно не круговой? Где я могу увидеть используемую стратегию и как ее настроить? Чем можно объяснить взлеты и падения на этом графике? (Например, PID #332 выполнял большую часть работы до 7 октября, когда он начал снижаться и его настигло повышение PID # 15708)

Было бы полезно получить четкое объяснение и / или ссылки на соответствующую документацию.

1 ответ

Решение

Согласно документации:

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

А также:

Gunicorn полагается на операционную систему, которая обеспечивает балансировку нагрузки при обработке запросов.

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

Вы, вероятно, можете смело снизить количество работников ((2 x num cores) + 1 это только стартовая рекомендация). Это уменьшит вероятность перерасхода ресурсов и может повысить производительность вашего приложения.

Другие вопросы по тегам