В настоящее время я использую циклический перебор DNS для балансировки нагрузки, который отлично работает. Записи выглядят так (у меня TTL 120 секунд)
;; ANSWER SECTION:
orion.2x.to. 116 IN A 80.237.201.41
orion.2x.to. 116 IN A 87.230.54.12
orion.2x.to. 116 IN A 87.230.100.10
orion.2x.to. 116 IN A 87.230.51.65
Я узнал, что не все интернет-провайдеры / устройства обрабатывают такой ответ одинаково. Например, некоторые DNS-серверы меняют адреса случайным образом или всегда циклически их просматривают. Некоторые просто распространяют первую запись, другие пытаются определить, какая из них лучше (близка к региону), глядя на IP-адрес.
Однако, если пользовательская база достаточно велика (распределена между несколькими интернет-провайдерами и т. Д.), Она довольно хорошо сбалансирована. Расхождения от самой высокой к самой низкой загруженности сервера едва ли превышают 15%.
Однако теперь у меня возникла проблема, заключающаяся в том, что я добавляю в системы больше серверов, и не все они имеют одинаковую мощность.
В настоящее время у меня есть серверы только на 1 Гбит / с, но я хочу работать с серверами 100 Мбит / с, а также серверами 10 Гбит / с.
Итак, я хочу представить сервер на 10 Гбит / с с весом 100, сервер на 1 Гбит / с с весом 10 и сервер на 100 Мбит / с с весом 1.
Ранее я дважды добавлял серверы, чтобы привлечь к ним больше трафика (что хорошо работало - пропускная способность почти удвоилась). Но добавить 100 раз сервер 10 Гбит / с к DNS - это немного нелепо.
Поэтому я подумал об использовании TTL.
Если я даю серверу A 240 секунд TTL, а серверу B только 120 секунд (что примерно соответствует минимуму для использования для циклического перебора, поскольку для многих DNS-серверов установлено значение 120, если указан более низкий TTL (так я слышал)). Я думаю, что в идеальном сценарии должно произойти что-то подобное:
First 120 seconds
50% of requests get server A -> keep it for 240 seconds.
50% of requests get server B -> keep it for 120 seconds
Second 120 seconds
50% of requests still have server A cached -> keep it for another 120 seconds.
25% of requests get server A -> keep it for 240 seconds
25% of requests get server B -> keep it for 120 seconds
Third 120 seconds
25% will get server A (from the 50% of Server A that now expired) -> cache 240 sec
25% will get server B (from the 50% of Server A that now expired) -> cache 120 sec
25% will have server A cached for another 120 seconds
12.5% will get server B (from the 25% of server B that now expired) -> cache 120sec
12.5% will get server A (from the 25% of server B that now expired) -> cache 240 sec
Fourth 120 seconds
25% will have server A cached -> cache for another 120 secs
12.5% will get server A (from the 25% of b that now expired) -> cache 240 secs
12.5% will get server B (from the 25% of b that now expired) -> cache 120 secs
12.5% will get server A (from the 25% of a that now expired) -> cache 240 secs
12.5% will get server B (from the 25% of a that now expired) -> cache 120 secs
6.25% will get server A (from the 12.5% of b that now expired) -> cache 240 secs
6.25% will get server B (from the 12.5% of b that now expired) -> cache 120 secs
12.5% will have server A cached -> cache another 120 secs
... I think I lost something at this point, but I think you get the idea...
Как видите, это довольно сложно предсказать, и на практике это точно не сработает. Но это обязательно должно сказаться на распространении!
Я знаю, что циклический взвешенный алгоритм существует и управляется только корневым сервером. Он просто циклически перебирает записи DNS при ответе и возвращает записи DNS с заданной вероятностью, соответствующей взвешиванию. Мой DNS-сервер не поддерживает это, и мои требования не так точны. Если он не весит идеально, все в порядке, но он должен двигаться в правильном направлении.
Я думаю, что использование поля TTL могло бы быть более элегантным и простым решением - и для этого не требуется DNS-сервер, который контролирует это динамически, что экономит ресурсы, - что, на мой взгляд, составляет всю суть балансировки нагрузки DNS по сравнению с аппаратными балансировщиками нагрузки.
У меня вопрос: существуют ли какие-либо передовые практики / методы / практические правила для взвешивания циклического распределения с использованием атрибута TTL записей DNS?
Редактировать:
Система представляет собой систему прямого прокси-сервера. Объем полосы пропускания (не запросов) превышает то, что может обработать один сервер с Ethernet. Поэтому мне нужно решение для балансировки, которое распределяет пропускную способность между несколькими серверами. Есть ли альтернативные методы, кроме использования DNS? Конечно, я могу использовать балансировщик нагрузки с оптоволоконным каналом и т. Д., Но затраты смехотворны, и это также увеличивает только ширину узкого места, но не устраняет его. Единственное, о чем я могу думать, - это IP-адреса anycast (это Anycast или многоадресная рассылка?), Но у меня нет средств для настройки такой системы.
Теперь у меня вопрос ... есть ли какие-нибудь лучшие пункты / методы / практические правила для взвешивания циклического распределения с использованием атрибута TTL записей DNS?
Да, лучшая практика не делай этого !!
Пожалуйста, повторяй за мной
DNS предназначен для сопоставления название к один или несколько IP-адресов. Любое последующее уравновешивание происходит благодаря удаче, а не дизайну.
Взгляни на PowerDNS. Это позволяет вам создать собственный бэкэнд канала. Я изменил пример DNS-бэкэнда балансировщика нагрузки, написанный на perl, чтобы использовать алгоритм ::ConsistentHash:: Кетама модуль. Это позволяет мне устанавливать произвольные веса, например:
my $ketamahe = Algorithm::ConsistentHash::Ketama->new();
# Configure servers and weights
$ketamahe->add_bucket("192.168.1.2", 50);
$ketamahe->add_bucket("192.168.1.25", 50);
И еще один:
# multi-colo hash
my $ketamamc = Algorithm::ConsistentHash::Ketama->new();
# Configure servers and weights
$ketamamc->add_bucket("192.168.1.2", 33);
$ketamamc->add_bucket("192.168.1.25", 33);
$ketamamc->add_bucket("192.168.2.2", 17);
$ketamamc->add_bucket("192.168.2.2", 17);
Я добавил cname из желаемого домена верхнего уровня к субдомену, который я называю gslb, или Global Server Load Balancing. Оттуда я вызываю этот настраиваемый DNS-сервер и отправляю записи A в соответствии с моими желаемыми весами.
Работает как чемпион. У кетама-хеша есть приятное свойство минимального нарушения существующей конфигурации при добавлении серверов или корректировке весов.
Я рекомендую прочитать «Альтернативные DNS-серверы» Ян-Пита Менса. У него есть много хороших идей, а также примеры кода.
Также рекомендую отказаться от TTL-модуляции. Вы уже ушли довольно далеко, и добавление еще одного кладжа наверху чрезвычайно затруднит устранение неполадок и документирование.
Во-первых, я полностью согласен с @Alnitak, что DNS не предназначен для такого рода вещей, и лучше всего не (ab) использовать DNS в качестве балансировщика нагрузки для бедняков.
Теперь у меня вопрос ... есть ли какие-нибудь лучшие пункты / методы / практические правила для взвешивания циклического распределения с использованием атрибута TTL записей DNS?
Чтобы ответить на предпосылку вопроса, подход, используемый для выполнения базового взвешенного циклического перебора с использованием DNS, заключается в следующем:
Server A
должен иметь 1/3 трафика и Server B
должен иметь 2/3, тогда 1/3 авторитетных ответов DNS на DNS-прокси будет содержать только A
IP, и только 2/3 ответов B
IP. (Если 2 или более серверов имеют одинаковый «вес», их можно объединить в один ответ.)Amazon Служба DNS Route 53 использует этот метод.
Объем полосы пропускания (не запросов) превышает то, что может обработать один сервер с Ethernet. Поэтому мне нужно решение для балансировки, которое распределяет пропускную способность между несколькими серверами.
Правильно. Насколько я понимаю, у вас есть своего рода «дешевая» служба загрузки / распространения видео / загрузки больших файлов, где общий битрейт службы превышает 1 ГБит.
Трудно быть точным, не зная точных характеристик вашего сервиса и схемы вашего сервера. Но а общее решение в этом случае:
Такой тип установки может быть построен с использованием программного обеспечения с открытым исходным кодом или со специальными устройствами от многих поставщиков. В тег балансировки нагрузки вот отличная отправная точка, или вы можете нанять системных администраторов, которые сделали это раньше, чтобы проконсультироваться за вас ...
Чтобы справиться с такого рода настройками, вам нужно взглянуть на реальное решение для балансировки нагрузки. Читать Виртуальный сервер Linux и HAProxy. Вы получаете дополнительное преимущество, заключающееся в том, что серверы автоматически удаляются из пула в случае их сбоя, а последствия гораздо легче понять. Взвешивание - это просто настройка, которую нужно настроить.
Вы можете использовать PowerDNS для взвешенного циклического перебора, хотя распределение нагрузки таким несбалансированным образом (100: 1?) Может быть очень интересным, по крайней мере, с алгоритмами, которые я использовал в своем решении, где каждая запись RR имеет связанный с ней вес. , от 1 до 100, и случайное значение используется для включения или исключения записей.
Вот статья, которую я написал об использовании серверной части MySQL в PowerDNS для взвешенного RR DNS: http://www.mccartney.ie/wordpress/2008/08/wrr-dns-with-powerdns/
У R.I.Pienaar также есть несколько примеров на основе Ruby (с использованием бэкэнда конвейера PowerDNS): http://code.google.com/p/ruby-pdns/wiki/RecipeWeightedRoundRobin