Какую программную балансировку или распределение нагрузки вы порекомендуете для данного случая?

Какую программную балансировку или распределение нагрузки вы порекомендуете для данного случая?

Я подготовил сервер с 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 между ядрами и процессами обеспечивает оптимальную производительность; обычно гораздо лучше реализовать динамическую адаптацию к нагрузке.

Связанный контент