Алгоритмы балансировки: round robin, least connections и другие
Основы4 минРедакция Innovialabs
Коротко
Для stateless API обычно хватает round robin, для долгих соединений (WebSocket, стриминг) лучше least connections, для серверов разной мощности — взвешенные варианты, а IP hash нужен, только если без «липких» сессий не обойтись.
Коротко: какой алгоритм выбрать
Балансировщик нагрузки принимает входящие запросы и распределяет их между несколькими серверами (backend). Алгоритм определяет, какой сервер получит следующий запрос.
Быстрый ориентир:
- Одинаковые серверы, короткие stateless-запросы → round robin.
- Серверы разной мощности → weighted round robin или weighted least connections.
- Долгие соединения (WebSocket, загрузка файлов, стриминг) → least connections.
- Нужно, чтобы клиент попадал на один и тот же сервер → IP hash или consistent hashing.
- Время ответа серверов сильно скачет → least response time или power of two choices, если их поддерживает ваш балансировщик.
Round robin
Запросы раздаются по кругу: первый — серверу A, второй — B, третий — C, затем снова A.
- Плюсы: простой, предсказуемый, не требует знать состояние серверов.
- Минусы: не учитывает, что один запрос может обрабатываться миллисекунды, а другой — секунды. Медленный сервер получает столько же запросов, сколько быстрый.
- Подходит: stateless API за одинаковыми серверами, где запросы примерно равны по тяжести.
Weighted round robin
То же самое, но каждому серверу назначается вес. Сервер с весом 3 получит втрое больше запросов, чем сервер с весом 1.
- Подходит: когда в пуле машины разной мощности или вы постепенно выводите новый сервер под нагрузку.
- Минус: веса задаются вручную и не реагируют на текущую загрузку.
Least connections
Новый запрос уходит на сервер с наименьшим числом активных соединений.
- Плюсы: сам подстраивается под неравномерную нагрузку. Если сервер «застрял» на тяжёлых запросах, новые пойдут к другим.
- Минусы: балансировщику нужно отслеживать соединения; при очень коротких запросах разница с round robin почти незаметна.
- Подходит: WebSocket, long polling, загрузки файлов, запросы с непредсказуемой длительностью.
Есть и weighted least connections, где учитываются и соединения, и вес сервера.
IP hash и consistent hashing
Сервер выбирается по хешу от IP клиента (или другого ключа: cookie, ID пользователя). Один и тот же клиент стабильно попадает на один и тот же сервер — это называется sticky sessions.
- Плюсы: сессия в памяти сервера не теряется, локальный кеш эффективнее.
- Минусы: нагрузка может распределиться неравномерно (например, многие пользователи за одним NAT получат один IP). При добавлении или удалении сервера обычный хеш перетасует большинство клиентов.
- Consistent hashing решает последнюю проблему: при изменении пула переезжает лишь небольшая часть ключей. Его используют для кеш-серверов и шардирования.
Лучше всего — делать приложение stateless (сессии в Redis или в токене), тогда sticky sessions не нужны вовсе.
Least response time и power of two choices
- Least response time учитывает не только число соединений, но и среднее время ответа сервера. Хорош при неоднородных серверах, но поддерживается не везде и сложнее в настройке.
- Power of two choices: балансировщик выбирает два случайных сервера и отправляет запрос на менее загруженный из них. Простой приём, который хорошо работает в больших пулах и при нескольких независимых балансировщиках.
- Random — случайный выбор. Звучит наивно, но на больших объёмах распределяет почти равномерно.
Сравнение
| Алгоритм | Учитывает загрузку | Sticky | Лучше всего для |
|---|---|---|---|
| Round robin | Нет | Нет | Одинаковые серверы, stateless API |
| Weighted round robin | Нет (статичные веса) | Нет | Серверы разной мощности |
| Least connections | Да | Нет | Долгие соединения |
| IP hash | Нет | Да | Legacy-приложения с сессией в памяти |
| Consistent hashing | Нет | Да | Кеши, шардирование |
| Power of two choices | Да | Нет | Большие пулы, распределённые балансировщики |
Пример в nginx
upstream api {
least_conn;
server 10.0.0.11:3000 weight=2;
server 10.0.0.12:3000;
server 10.0.0.13:3000 backup;
}
Без директивы least_conn nginx использует weighted round robin. backup получает трафик, только когда основные серверы недоступны. Подробнее — в документации nginx.
Что важнее алгоритма
- Health checks. Балансировщик должен перестать слать запросы на упавший сервер. Без этого любой алгоритм отправит пользователей в ошибку.
- Таймауты и повторы. Настройте, что делать, если сервер не ответил, но не повторяйте неидемпотентные запросы (оплаты, создание заказов).
- Мониторинг. Смотрите на распределение нагрузки и время ответа по каждому серверу, а не только в среднем.
- Сам балансировщик не должен быть единственной точкой отказа.