Раньше, когда надо было распределить нагрузку на несколько серверов, мы прописывали несколько A-записей с одним именем в DNS-зоне, и все работало. Запросы клиентов распределялись примерно поровну. Особенно актуален такой способ балансировки был для раздачи статитического контента.
Недавно наш клиент обратился к нам с проблемой:
В ЧНН начинались проблемы с загрузкой различных флешек — файлы загружались по несколько минут.
Расследование выявило неравномерную загрузку одного из серверов раздачи статики — он отдавал в разы больше трафика в сеть, чем все остальные. Причем периодически нагрузка переходила от одного сервера к другому.
В DNS зоне было прописано что-то типа:
cdn.exampe.com IN A 192.168.10.1 cdn.exampe.com IN A 192.168.12.1 cdn.exampe.com IN A 192.168.15.1 cdn.exampe.com IN A 192.168.16.1 cdn.exampe.com IN A 192.168.11.1 cdn.exampe.com IN A 192.168.19.1
Раньше клиенты получали ответы от DNS-серверов по алгоритму round-robin, но поиск проблемы привел к совершенно неожиданному результату!
Запросы к DNS серверу по адресу 8.8.8.8 неизменно возвращали один и тот же адрес.
Никакого round-robin. Возвращаемый адрес мог смениться, если заканчивался TTL, а мог и не измениться.
Техподдержка корпорации добра ответила в стиле «мы лучше вас знаем, что именно вам надо».
DNS Round Robin has never been an effective means of load-balancing, and is less so today, as applications switch from gethostbyname to getaddrinfo for IPv6 support:
homepage.ntlworld.com/jonathan.deboynepollard/FGA/dns-round-robin-is-useless.html
www.tenereillo.com/GSLBPageOfShame.htm
daniel.haxx.se/blog/2012/01/03/getaddrinfo-with-round-robin-dns-and-happy-eyeballs
RRDNS никогда хорошо не работало, а дальше будет еще хуже. И когда наступит IPv6, станет совсем плохо…
Вот такое мнение у корпорации добра, и никакие графики нагрузки переубедить ее не смогли.
Дальнейшее расследование проблемы показало, что проблема не только в Google, но и в Hetzner, в котором хостится зона.
Проблема номер раз:
Каждый из гугло-серверов передает ответы точно такими же, какими получил от DNS-серверов, обслуживающих зону, ничего не изменяя в них. Если каждый из серверов получает свой вариант последовательности, то при последовательных запросах складывается впечатление, что Google отдает адреса в случайном порядке, хотя на самом деле это ответы отдаются со случайно выбранного сервера.
Проблема номер два:
Хетцнер, в котором хостится проблемная DNS-зона, начал отдавать список адресов для хоста неизменным.
И в итоге на всех гугло-серверах оказалась одинаковая последовательность адресов.
Ответ от ТП Hetzner также не порадовал:
This function is not enabled on our DNS-resolvers. If you want to use that kind of loadbalancing, you have to setup and use your own servers.
Конечно, можно обратиться к платным поставщикам услуг CDN или сказать программистам, чтобы они генерировали ссылки на контент, которые указывают на конкретные сервера (естественно, для каждого запроса сервер в ссылке берется случайным образом, чтобы распределить нагрузку).
Но с админов обычно требуют решить проблему быстро, и чтоб работало сейчас.
А уже потом можно будет поискать решение получше.
Возвращаем редирект на конкретный сервер средствами nginx:
Воспользуемся директивой split_clients, распределим проценты согласно мощности наших серверов и пропишем на каждом из них вот такой конфиг.
Естественно, в строке hostname cdn1.example.com; указываем свое уникальное имя для каждого из серверов.
http {
split_clients "${remote_addr}AAA" $variant {
15% 1;
15% 2;
15% 3;
15% 4;
15% 5;
15% 6;
* 7;
}
server {
listen 80;
server_name cdn.example.com;
return 302 http://cdn$variant.example.com/$request_uri;
}
server {
listen 80;
server_name cdn1.example.com;
location / {
root /srv/www/cdn.example.com/htdocs;
}
}
В итоге nginx возвращает пользователю редиректы на сервер, который определяется на основании хеша ip адреса клиента.
Вот такое вот распределение нагрузки.
PS: Перевели зону с Хетцнера в Яндекс
Комментарии (64)
ertaquo
28.04.2016 12:57Как вариант, можно использовать haproxy — через него можно пробрасывать что угодно и как угодно, с разными схемами балансировки.
klamas
28.04.2016 14:16+8Да, 3 Gbps пустить через один канал/сервер отличный вариант, тогда как, например, 10 серверов и поднимались для балансировки.
Ivan_83
28.04.2016 13:26+3Всё потому что юзеры и многие админы настолько глупы что прописывают гугловские, опенднс, яндекс днс и прочие чужие рекурсивные резолверы. И плевали они на приватность и на вменяемость и в некоторых случаях на локальные ресурсы провайдера/организации.
Понятно же что нужно либо пользоваться тем, что даёт провайдер либо поднимать свой, типа unbound или другой вменяемый рекурсер с кешем.
2 zuborg:
Гугл держит за яйца всех поставщиков контента, и чем они мельче- тем сильнее сжимает их в тисках.
Поэтому мнение отдельных лиц и организаций ему совершенно безразлично.
2 ertaquo:
До тех пор пока у тебя ширины линка будет хватать и мощи для проксирования. Дальше проблема распределения на несколько адресов снова всплывает.
Проксирование ради распределения нагрузки вообще так себе идея.Notimer
29.04.2016 18:30По сути своей верно — прописывать публичные ДНСы, это как надеяться что уличный фонарь будет освещать твоё окно всю жизнь без проблем.
a0fs
29.04.2016 18:31+3Не глупы а дорожат временем. Гораздо легче пользоваться готовым и хорошо (до последнего времени) работающим сервисом, чем поднимать своё. Кроме того, ИМХО, Гугло-Яндекс ДНС это нескончаемое добро по сравнению с криво настроенными домашними резолверами.
Приватность ИМХО не самоцель. Я вообще не вижу проблем от использования публичных DNS поисковиков. При таких объёмах запросов меня никто не видит. А статистика и особенно мониторинг странных доменов со зловредами — прекрасное подспорье в защите против зловредов на уровне поисковиков.
Провайдерские ДНС местами хуже. Достаточно вспомнить Ростелеком (особенно южный филиал, где ДНС-ы ложились по лету как по часам), yota DNS-ами не баловала (не знаю как сейчас).
Кроме того в конторе на 3 виндоус машины плюс один D-Link роутеро-свич именно Гугло-Яндекс DNS позволяет (позволяло...) забыть о проблемах с DNS.Ivan_83
03.05.2016 20:31Я один раз настроил unbound для себя дома, и растираживал потом конфиг клиентам.
Вбить 3 команды и скопировать один файл это несомненно дольше, чем вбить пару ип адресов, однако те ип адреса никому ничего не должны и могут в любой момент перестать работать, и тогда придётся бегать и срочно менять везде настройки.
Вы можете поступать со своей личной жизнью как хотите, но когда офисный админ за других решает проблему ДНС таким образом то я рекомендую лечение молотком в голову.
Поступая таким опрометчивым образом человек не только насильственно лишает других приватности, но и палит контору с её контрагентами.
Плюс вы видимо ещё мало страдали от мегакорпораций владеющих интернетом (гугл, яндекс, мс), раз продолжаете складывать свои яйца в их корзины.
Любой конторе я рекомендую завести сервер/роутер (хоть с мусорного компа, лишь бы железо не глючило), с BSD/Linux, который будет и файлопомойкой и роутером и в том числе днс кешем+рекурсером.
За комфорт нужно платить.
shoguevara
28.04.2016 14:07Согласен, без предупреждения такие вещи делать не очень корректно, но тем не менее отрицать доводы представителей «корпорации бобра», тоже тяжеловато: сейчас существует огромное количество разного рода балансировщиков нагрузок, начиная с промышленных, которые могут стоить, как самолет, заканчивая опенсорсными, как приведенный выше haproxy или более продвинутый pfsense. Почему вы хотите продолжать пользоваться «недобалансировкой» с использованием RR на DNS?
Хотя, тут могут быть и другие причины, например: некоторые пользователи могут решить, что так как данная конфигурация плохо балансирует нагрузку, то виноват в этом гугл. Решили себя обезопасить, ничего личного, «от дурака».Velikodniy
28.04.2016 14:38Пример. Есть несколько серверов, в интернет смотрит отдельный лоадбалансер. Как обеспечить отказоустойчивость балансера, кроме как дублируя его и используя RRDNS?
darken99
28.04.2016 14:57Кроме RRDNS есть еще как минимум heartbeat и routed/relayd (тут точно названия не помню)
Velikodniy
28.04.2016 17:58Это, как я понимаю, предполагает наличия собственного ДЦ.
rekby
28.04.2016 20:55Нет, ДЦ свой не нужен. Достаточно автономной системы и сетки IP-адресов.
pansa
28.04.2016 23:06Только есть нюанс, насколько я знаю — сетка, которая будет отдана под аникаст, должна быть не менее /24.
rekby
28.04.2016 23:30увы, как бы расточительно это ни было :(
Я тоже одно время хотел сделать anycast на несколько штук адресов. Вариантов не нашел — пришлось брать /24 и маршрутизировать сеть через BGP.
darken99
29.04.2016 14:34Все это не нужно, достаточно 1 virtual IP (ну либо решить вопрос с доступом к серверам и использовать вообще только 1 IP на несколько)
klamas
29.04.2016 15:25Не подскажете где такие раздают?
Хочу по три сервера на каждый континент поставить и этот ваш virtual IP туда как нельзя кстати бы подошел.
Про в скобках, тоже, пожалуйста, подробнее напишите, очень хочется поскорее внедрить!darken99
29.04.2016 16:17Virtual IP просите у хостера, с саппортом можно общаться ;)
Тот же Hetzner дает KVM ко всем серверам бесплатно и сразу, если сервера в одной стойке (что опять же легко получается при запросе ) то берете адреса что вам выдали и делаете их не статическими а мигрирующимиSaymon21
29.04.2016 18:29Не KVM, а LaRa наверное, на время. Она убога. Во вторых. Я вот так и не смог придти к тому, как как следует при выходе одного балансера перекинуть vip на соседний сервер. Если подскажите, респект.
darken99
29.04.2016 19:07Не суть важно.
Берете любой демон типа heartbeat, главное условие чтобы между серверами был броадкаст либо юникаст (т.е. не роутинг).
На каждом сервере есть свой IP, можно их и использовать, просто каждый сервер будет для одного IP мастером.
Ну и не привязываем балансер к конкретному IP.
Или привязываете, каждый ведь волен извращаться как ему нравится ;)Saymon21
30.04.2016 06:26Вы точно работали с хетзнеровским v-ip или я не понимаю чего-то? Там-же на их оборудовании роутинг идёт на нужную тачку. Или, через api им сообщать, куда роутить?
darken99
01.05.2016 22:56Вы вообще понимаете как работает сеть, что такое роутинг, каким образом маршрутизатор определяет на какой физический хост отправлять пакеты?
Если нет то либо сначала изучите основы либо вообще даже не пытайтесь
LuckySB
28.04.2016 21:43+2К сожалению тут как раз ситуация, когда есть N серверов в разных ДЦ,
разбросанных от штатов до селектела, через хетцнер… ;)
и они никак не завязны на какую-то БД или бекенд. Самодостаточны и генерируют много трафика.
haproxy и прочее точно так же будут упираться в гигабит.
Darka
28.04.2016 16:17HSRP/VRRP/CARP
shoguevara
28.04.2016 17:27HA на уровне балансеров чем не устраивает? Ответ на этот вопрос еще давно за нас продумали =)
rekby
28.04.2016 20:55RoundRobin отказоустойчивости не обеспечивает — если один балансер из двух упадёт, то половина запросов отвалится.
Отказоустойчивость решается или сменой A-записи при падении узла или обеспечением отказоустойчивости самого IP например путём его анонса из разных ДЦ.Velikodniy
28.04.2016 21:27Если смотреть на браузеры, то в случае падения первого адреса из списка после таймаута подхватывается следующий и дальше кэшируется, так что можно сказать, что худо-бедно, но обеспечивает.
Nikitian
04.05.2016 11:28Как вариант, использовать какие-либо health check. Мы используем от амазона и они оперативно переключают записи в dns при фейле в течение пары минут + всякие плюшки типа geo-dns.
ibKpoxa
28.04.2016 14:07А мне гуглоднс возвращает больше одного адреса:
lamo$ host vk.com 8.8.8.8 Using domain server: Name: 8.8.8.8 Address: 8.8.8.8#53 Aliases: vk.com has address 87.240.131.120 vk.com has address 87.240.143.241 vk.com has address 87.240.131.117 vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:801 vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:802 vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:803
Velikodniy
28.04.2016 14:31+1Неужели одумались?
[13:49:30] > dig @8.8.8.8 google.com A
;; ANSWER SECTION:
google.com. 299 IN A 216.58.214.78
[14:00:50] > dig @8.8.8.8 google.com A
;; ANSWER SECTION:
google.com. 299 IN A 217.19.208.238
google.com. 299 IN A 217.19.208.216
google.com. 299 IN A 217.19.208.245
...
ainu
28.04.2016 14:37+6Ещё бы они для самих себя устроили такую подлянку. Сами себе небось robin-ном распределяют нагрузку.
AgaFonOff
28.04.2016 14:46На мою настройку RRDNS четыре восьмерки пока показывают разные последовательности IP при последовательных запросах. Возможно это как-то различается по разным частям гугло-инфраструктуры, так что оригинальный алярм статьи я пока не подтверждаю.
mva
28.04.2016 15:41+1судя по таймштампу вы запрашивали второй раз после истечения TTL. А это — именно то, о чём написано в ОП. И это не RR.
M-A-XG
28.04.2016 14:15А как эту проблему решаею ВК и ФБ?
Не в плане cdn, а в плане самого сайта.baltazorbest
28.04.2016 14:43vk.com:
vk.com. 202 IN A 87.240.143.241
vk.com. 202 IN A 87.240.131.117
vk.com. 202 IN A 87.240.131.118
facebook.com:
facebook.com. 29 IN A 31.13.76.68
Что то мне подсказывает что у facebook настроено что то типа CARP (для freebsd) для linux не помню как называется, но есть то же похожее на уровне ядра, суть в том что 1 адрес присвоен N серверам и при падении одного хоста, адрес используется другим, ну или есть корпоративное решение такого рода.Darka
28.04.2016 16:19Anycast
Greendq
28.04.2016 20:15А есть же ограничение на количество одновременных соединений к одному и тому же адресу? Пусть большое, но оно же есть!!!!??? И как с этим ФБ справляется?
ToSHiC
04.05.2016 13:59Такое ограничение есть только на клиенте. Балансировщики нагрузки по факту оперируют ip пакетами, «подсматривая» в tcp заголовки, но не устанавливают соединение сами, так что для них вообще нету такой проблемы. Серверу тоже без разницы, сколько клиентов присоединится на его порт, главное, чтобы сокетов на всех хватило. А вот клиент на каждое соединение тратит 1 эфемерный порт (теоретически, можно сэкономить и шарить один и тот же исходящий порт, если серверные адрес/порт отличаются, но так, на сколько я знаю, никто пока не делает, потому что не нужно), которых обычно выделено около 30 тысяч (net.ipv4.ip_local_port_range = 32768 61000).
ToSHiC
28.04.2016 19:56Довольно просто. Внутри сети используется динамическая маршрутизация, например OSPF. Внутренние балансеры траффика анонсируют маршрут на один и тот же адрес с одинаковой стоимостью, и нагрузка размазывается по ним равномерно. В случае наличия нескольких точек входа в сеть стоимость может быть и не одинаковой, ею можно перенаправлять нагрузку внутри сети.
Каждый балансер уже следит за живостью HTTP серверов и направляет траффик на них, учитывая их загрузку и прочие факторы. Может показаться, что балансеры лишние, но это не так: их можно поставить существенно меньше, чем фронтов, и они могут прокачивать через себя много траффика, 10 гигабит через одну машину — легко, а если постараться — то и 40 гигабит.
Если интересны подробности, то рекомендую прочитать статью от гугла про их Maglev: http://static.googleusercontent.com/media/research.google.com/ru//pubs/archive/44824.pdf
jetman
28.04.2016 14:43+1В ЧНН начинались проблемы с загрузкой различных флешек — файлы загружались по несколько минут.
Тут имеются в виду SWF файлы («флешки»)? Если для сохранения информации во флешках используют SharedObject (а они точно используют), то из-за вашего редиректа на каждый поддомен cdn'a будет свое сохранение. То есть пользователям будет казаться, что они потеряли сохранения, если попадут на новый cdn при следующем посещении и только в случае, если у пользователя динамический ip адрес, а это мобильные клиенты, да и вообще большинство домашних провайдеров — имхо таких людей будет очень много.
Noa69
28.04.2016 15:00-2В выдаче 8.8.8.8 порядок этих ип всегда одинаков, в отличии от ожидаемого поведения «нормального» DNS сервера:
host vk.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
vk.com has address 87.240.131.118
vk.com has address 87.240.131.119
vk.com has address 87.240.131.120
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:904
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:905
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:906
host vk.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
vk.com has address 87.240.131.118
vk.com has address 87.240.131.119
vk.com has address 87.240.131.120
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:807
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:808
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:809
vk.com mail is handled by 10 mail.vk.com.
[root@schm-dhcp ~]# host vk.com 8.8.8.8
Using domain server:
Name: 8.8.8.8
Address: 8.8.8.8#53
Aliases:
vk.com has address 87.240.131.119
vk.com has address 87.240.131.120
vk.com has address 87.240.143.241
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:807
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:808
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:809
vk.com mail is handled by 10 mail.vk.com.
[root@schm-dhcp ~]# host vk.com
vk.com has address 87.240.143.241
vk.com has address 87.240.131.118
vk.com has address 87.240.131.117
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:907
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:908
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:909
vk.com mail is handled by 10 mail.vk.com.
[root@schm-dhcp ~]# host vk.com
vk.com has address 87.240.131.118
vk.com has address 87.240.131.117
vk.com has address 87.240.143.241
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:908
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:909
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:907
vk.com mail is handled by 10 mail.vk.com.
[root@schm-dhcp ~]# host vk.com
vk.com has address 87.240.131.117
vk.com has address 87.240.143.241
vk.com has address 87.240.131.118
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:909
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:907
vk.com has IPv6 address 2a00:bdc0:3:103:1:0:403:908
LuckySB
28.04.2016 21:36Написал update
Пока гипотеза сменилась.
В основном виноват Hetzner, в котором зона хостится.
Он перестал порядок записей менять и каждый раз отдает один и тот же вариант.
А гугл, в отличие от яндекса, похоже кеширует просто последовательность символов, полученную от хетцнера.
и ничего не меняя отправляет ее в ответ на запросы.
estum
29.04.2016 01:29По-моему в данном случае использовать split_clients не совсем правильно, лучше upstream.
LuckySB
29.04.2016 02:16почему?
нам надо разделить клиентов на несколько частей — split clients
А главный плюс апстрима — определение упавших бекендов тут не используется.
в качестве апстрима мы же будем указывать вирт. сервера в том же nginxestum
29.04.2016 02:27При добавлении сервера вам придется изменять долю у всех остальных записей, нет резолва и остальных фич апстрима, плюс необходимость компиляции еще одного модуля.
LuckySB
29.04.2016 02:36не совсем понял, зачем тут нужен резолв и остальные фичи?
в общем затраты на конфигурацию не существенны — они одноразовые
а вот бессмысленные затраты на создание tcp-Соединений к апстримам будут на каждый запросAd3pt
29.04.2016 06:37> а вот бессмысленные затраты на создание tcp-Соединений к апстримам будут на каждый запрос
А нельзя использовать keepalive до апстримов?
zuborg
Немного удивляет и отношение Гугла к этой ситуации, и то, что они вообще допустили такое.
dronnix
По ссылкам из ответа их техподдержки понятно, почему они такое допустили. Рекомендую к прочтению.
AgaFonOff
Ну им-то пофиг, что RR народ использовал для простого и дешевого решения проблемы распределения нагрузки. По сути они теперь вынуждают больше тратить на инфраструктуру.
dronnix
Почитайте матчасть, дело не в Google, а в RFC 3484 и функции getaddrinfo(), которая ему следует.