Назад | Перейти на главную страницу

Взвешенный круговой алгоритм через TTL - возможно?

В настоящее время я использую циклический перебор 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 не для балансировки нагрузки
  • DNS не обеспечивает отказоустойчивости
  • 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, заключается в следующем:

  • Настроить относительное происхождение записей в авторитетных DNS-ответах. Т.е. если Server A должен иметь 1/3 трафика и Server B должен иметь 2/3, тогда 1/3 авторитетных ответов DNS на DNS-прокси будет содержать только AIP, и только 2/3 ответов BIP. (Если 2 или более серверов имеют одинаковый «вес», их можно объединить в один ответ.)
  • Поддерживайте низкий TTL DNS, чтобы несбалансированная нагрузка выравнивалась относительно быстро. Поскольку за нижележащими DNS-прокси-серверами стоит очень неравномерное количество клиентов, вам нужно часто перетасовать записи.

Amazon Служба DNS Route 53 использует этот метод.

Объем полосы пропускания (не запросов) превышает то, что может обработать один сервер с Ethernet. Поэтому мне нужно решение для балансировки, которое распределяет пропускную способность между несколькими серверами.

Правильно. Насколько я понимаю, у вас есть своего рода «дешевая» служба загрузки / распространения видео / загрузки больших файлов, где общий битрейт службы превышает 1 ГБит.

Трудно быть точным, не зная точных характеристик вашего сервиса и схемы вашего сервера. Но а общее решение в этом случае:

  • Циклический перебор DNS для двух или более экземпляров балансировщика нагрузки на уровне TCP / IP или HTTP.
  • Каждый экземпляр балансировщика нагрузки является высокодоступным (2 идентичных балансировщика нагрузки, которые взаимодействуют, чтобы всегда поддерживать один IP-адрес).
  • Каждый экземпляр балансировщика нагрузки использует взвешенный циклический алгоритм или взвешенную обработку случайных соединений с внутренними серверами.

Такой тип установки может быть построен с использованием программного обеспечения с открытым исходным кодом или со специальными устройствами от многих поставщиков. В тег балансировки нагрузки вот отличная отправная точка, или вы можете нанять системных администраторов, которые сделали это раньше, чтобы проконсультироваться за вас ...

Чтобы справиться с такого рода настройками, вам нужно взглянуть на реальное решение для балансировки нагрузки. Читать Виртуальный сервер 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