алгоритм балансировки

Mykola Zubach zuborg at advancedhosters.com
Mon Jan 22 19:55:43 MSK 2007


On Mon, 22 Jan 2007 19:01:26 +0300 (MSK)
Andrew Kopeyko <kaa at zvuki.ru> wrote:

> On Mon, 22 Jan 2007, Mykola Zubach wrote:
> 
> > Насколько я вижу, сейчас применяется балансировка по кол-ву запросов.
> > В связи с этим возникают следующие проблемы:
> > 1. Неполная и неравномерная загруженность серверов.
> >  Если в пуле один сервер - бенчмарк загружает его полностью.
> >  Если добавить в пул ещё один сервер - загрузка будет составлять
> > 80-100% в зависимости от условий.
> > 2. Страдает отказоустовчивость.
> >  В примере пула балансировки с двумя серверами если на одном из них
> > ляжет апач например, нагрузка на второй сервер пойдет только если стоит
> > net.inet.tcp.blackhole=0
> >  Иначе nginx будет пытаться приконнектиться к лежащему серверу и в
> > течении таймаута коннекта входящие запросы вообще не будут никуда
> > форвардиться - так работает алгоритм балансировки.
> >  Разумеется, net.inet.tcp.blackhole не помогает если один из серверов
> > физически выключен - nginx будет время от времени его опрашивать и в
> > это время продолжительный период запросы никуда не форвардятся.
> >
> >  Эти проблемы отпадают если перейти от балансировки по кол-ву запросов
> 
> Эта проблема отпадает при увеличении числа бэкендов хотя бы до трёх.
> Падает один - продолжаем балансировать между двумя оставшимися.

аж бегом. Пока nginx за N секунд не убедится что тот один лежит, никуда
запросы он форвардить не будет, независимо сколько там ещё серверов
осталось - потому что свое кол-во запросов они отработали и теперь
алгоритм балансировки пытается запросы направить на простаивающий, по
его мнению, сервер.

> А балансировать между единственным оставшимся бэкендом - да, это тяжело.

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

> > к балансировке по кол-ву активных соединений с бек-ендами. То есть
> > слать запрос на тот бек-енд, который обслуживает в данный момент
> > наименьшее кол-во запросов.
> >
> >  Например, если на первый бек-енд пришло и отрабатывается 10
> > тяжелых запросов по генерации контента, nginx может все остальные
> > запросы слать на другой бек-енд, который занимается обработкой меньшего
> > кол-ва запросов, до тех пор, пока не нагрузит его настолько, что кол-во
> > обрабатываемых запросов сравняется с первым бек-ендом.
> >
> >  Алгоритм прост,
> 
> Ну, не скажите - вы же сами абзацем выше говорите о "тяжелых" и 
> "нетяжелых" запросах. Значит, помимо числа обрабатываемых запросов нужно 
> иметь ещё одну метрику - "тяжесть" каждого запроса. Это знает только 
> бэкенд да Вы - как это тайное знание передать nginx'у? Разложить по URI 
> - не получится ;-((

Мерою тяжести запроса является сколько времени бек-енд тратит на его
обработку. Допустим есть два вида запросов, легкий, который требует t
времени на обработку и тяжелый, который требует 2t времени на обработку.
Допустим, и тех и других приходит поровну, в одинаковом кол-ве.
Если пустить легкие запросы на один сервер, а тяжелые на другой, то на
обработчике легких запросов в среднем будет n паралельных соединений, а
на обработчике тяжелых - 2n соединений (Обработчик тяжелых запросов
будет в 2 раза более нагружен, чем обработчик легких запросов).
Моя схема балансировки распределяет нагрузку более равномерно.

> > но надо учитывать, что пока к какому-то бек-енду есть
> > соединения в состоянии "Устанавливается" - этот бек-енд считается
> > нерабочим (неподвержденная работоспособность) и новые запросы на него
> > слаться не должны, разве что других бек-ендов с подтвержденной
> > работоспособностью вообще нет в наличии. Суть в том что к каждому
> > бек-енду не должно быть много устанавливающихся, но не
> > установившихся (SYN-SENT) tcp-сессий, на случай если этот бек-енд
> > действительно испытывает проблемы.
> 
> Таким образом вы насильно понизите максимальное число обрабатываемых одним 
> бэкендом запросов до величины порядка
>    1/(время_установления_соединения)

Отнюдь. Просто при выборе сервера для форварда должен искаться сервера с
наименьшим кол-вом соединений в состоянии (SYN-SENT), а среди них -
сервера с наименьшим кол-вом рабочих соединений. Время установления
соединения в локалке на не сервером оборудовании:

18:43:06.102560 IP 192.168.0.A.57942 > 192.168.0.B.80: S
1894831746:1894831746(0) win 65535 <mss 1460,nop,wscale
1,nop,nop,timestamp 384074671 0,sackOK,eol>
18:43:06.102768 IP 192.168.0.B.80 > 192.168.0.A.57942: S
1535431777:1535431777(0) ack 1894831747 win 65535 <mss 1460,nop,wscale
1,nop,nop,timestamp 1743452870 384074671,nop,nop,sackOK>

0.102768-0.102560 - аж 0.000208 секунды

Так что реально отфорвардить 4К/с запросов вообще без проблем.

А вообще, конечно, отсутствие поддержки HTTP/1.1 при форвардинге
запросов очень печально. Как балансировщик http-трафика - nginx пока
не самое лучшее решение.

> 
> Не лучше ли добавить бэкендов? Заодно и проблему "балансировки между 
> единственным оставшимся бэкендом" решите.

Добавить бек-ендов ? За Ваши деньги - лехко и с радостью. Очень дельное
предложение.

> >
> 
> -- 
> Best regards,
> Andrew Kopeyko <kaa at zvuki.ru>
> http://www.zvuki.ru/ sysadmin
> 
> 





More information about the nginx-ru mailing list