Я подготовил сервер с 8 ядрами и планирую развернуть сетевую службу. Для распределения нагрузки запросов я хотел бы запустить 8 экземпляров своей службы. Ничего шокирующего. У меня нет доступа к аппаратному балансировщику нагрузки. Должен отметить, что в настоящее время я выделил 5 публичных IP-адресов (но могу получить больше).
Поэтому я хотел бы услышать ваши рекомендации по структурированию программного решения балансировки нагрузки.
Очевидным выбором будет:
- использовать HAProxy; или
- предварительно разветвить свое приложение (как это делают Facebook Tornado и Unicorn);
- вставьте свою идею здесь.
Мои цели:
- распределить нагрузку запросов между экземплярами сервиса; и
- разрешить последовательные перезапуски моей службы (обновления кода).
Должен отметить, что это не HTTP-сервис, поэтому NGiNX и ему подобные здесь не подходят.
Мне не нравится HAProxy из-за его требований к памяти; похоже, он требует буфера чтения и записи на каждое клиентское соединение. Таким образом, у меня будут буферы на уровне ядра, в HAProxy и в моем приложении. Это становится глупым! Может быть, я что-то упускаю в этом отношении?
Спасибо!
решение1
Независимо от решения, если вы устанавливаете процесс для пересылки потоковых данных, ему потребуются буферы на каждое соединение. Это связано с тем, что вы не всегда можете отправить все, что получили, поэтому вам придется хранить излишки в буфере. При этом использование памяти будет зависеть от количества одновременных соединений. Один большой сайт с радостью использует haproxy с настройками по умолчанию на 150000 одновременных соединений (4 ГБ ОЗУ). Если вам нужно больше, версия 1.4 позволяет вам изменять размер буфера без перекомпиляции. Однако имейте в виду, что буферы ядра на сокет никогда не опустятся ниже 4 КБ на направление и на сокет, то есть не менее 16 КБ на соединение. Это означает, что бессмысленно заставлять haproxy работать с менее чем 8 КБ на буфер, так как он и так будет потреблять меньше, чем ядро.
Также, если ваш сервис — чистый TCP, а прокси не имеет никакой дополнительной ценности, взгляните на сетевые решения, такие как LVS. Он намного дешевле, поскольку обрабатывает пакеты и не нуждается в поддержке буферов, поэтому буферы сокетов будут отбрасывать пакеты, когда они заполнятся, и его можно установить на той же машине, что и сервис.
Редактировать: Хавьер, предварительно разветвленные процессы, полагающиеся на ОС для балансировки нагрузки, вообще не масштабируются так хорошо. ОС просыпаетсякаждыйпроцесс, когда он получает соединение, только один из них получает его, а все остальные снова засыпают. Haproxy в многопроцессном режиме показывает свою лучшую производительность около 4 процессов. При 8 процессах производительность уже начинает падать. Apache использует хороший трюк против этого, он делает блокировку вокруг accept(), так что только один процесс ждет accept. Но это убивает функцию балансировки нагрузки ОС и останавливает масштабирование между 1000 и 2000 процессами. Он должен использовать массив из нескольких блокировок, чтобы несколько процессов проснулись, но он этого не делает.
решение2
без подробностей о вашем сервисе очень сложно сказать; но в целом я бы склонился к preforking. Это проверенная и верная стратегия сервера (а не новомодный трюк, как думают некоторые, почитав фан-сайты Tornado/Unicorn).
Кроме того, несколько советов:
каждый предварительно разветвленный процесс может использовать современные нестратегии
select
(в основном libevent) для обработки огромного количества клиентов.Очень редко соотношение 1:1 между ядрами и процессами обеспечивает оптимальную производительность; обычно гораздо лучше реализовать динамическую адаптацию к нагрузке.