a0d75 Posted November 20, 2009 (edited) Хочу поделиться способом балансировки загрузки NAS серверов средствами DNS сервера. Идея не нова - для хоста vpn.somenet.ru делаем несколько A записей и DNS сервер примерно одинаково нагружает наши сервера. Однако часто, особенно у начинающих провайдеров, имеется "зоопарк" NAS серверов, разных по мощности. И желательно не превышать максимальную нагрузку на каждый сервер. И было бы неплохо автоматически удалять записи для серверов, которые не отвечают. Нижеприведенный скрипт делает все это, динамически обновляет зону для BIND, используя RNDC. На хосте где запускается скрипт должны присутствовать утилиты nsupdate, host, snmpget. На NAS серверах должна быть запущена служба SNMP. #!/usr/bin/perl $balance_host = "vpn.somenet.ru"; $snmp_get = "snmpget -v 2c -c public "; @dns_get = `host $balance_host | cut -d " " -f 4`; $nsupdate_cmd = qq~ server 127.0.0.1 zone somenet.ru key rndc-key JhHyvY+7lUnJ1Ae1WSWcsQ== ~; %hosts = ( # mikrotik max sessions, snmp MIB "1.1.1.2" => [ 70, "SNMPv2-SMI::enterprises.9.9.150.1.1.1.0" ], "1.1.1.3" => [ 70, "SNMPv2-SMI::enterprises.9.9.150.1.1.1.0" ], # ucd-snmp max sessions, snmp MIB "1.1.1.4" => [ 500, "UCD-SNMP-MIB::prCount.1" ], ); # --------------------------------------------------------------------------------------- chomp(@dns_get); foreach (@dns_get){ $actual_dns{$_} = $_; } print `date`; foreach $host (sort keys %hosts){ chomp($current = `$snmp_get $host $hosts{$host}[1] | cut -d " " -f 4`); if($current eq ""){ $current = -1; } if(($current >= $hosts{$host}[0] || $current == -1 ) && defined($actual_dns{$host})){ # delete print "$host has $current connections with max $hosts{$host}[0] -> delete\n"; $nsupdate_cmd .= "update delete $balance_host A $host\n"; $need_update = 1; } elsif(($current < $hosts{$host}[0] && $current != -1) && !defined($actual_dns{$host})){ # insert print "$host has $current connections with max $hosts{$host}[0] -> insert\n"; $nsupdate_cmd .= "update add $balance_host 60 A $host\n"; $need_update = 1; } else { # do nothing if(defined($actual_dns{$host})){ $mode = "enabled"; } else { $mode = "disabled"; } print "$host $mode and has $current connections with max $hosts{$host}[0]\n"; } if(defined($actual_dns{$host})){ delete $actual_dns{$host}; } } foreach $host (sort keys %actual_dns){ print "$host is old - delete\n"; $nsupdate_cmd .= "update delete $balance_host A $host\n"; $need_update = 1; } if($need_update){ $nsupdate_cmd .= "send\n"; print $nsupdate_cmd; open F, "| nsupdate"; print F $nsupdate_cmd; close F; } Пример snmpd.conf для линуксового NAS: rocommunity public proc pppd Далее на машине с BIND запускаем rndc-confgen и правим named.conf, пример: ... key "rndc-key" { algorithm hmac-md5; secret "JhHyvY+7lUnJ1Ae1WSWcsQ=="; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { "rndc-key"; }; }; zone "somenet.ru" in { type master; file "somenet.hosts"; allow-update { key rndc-key; }; }; ... Не забываем добавить в cron вызов скрипта vpn_balancer.pl раз в минуту. Обратите внимание, что после данных манипуляций не рекомендуется вручную вносить изменения в файл somenet.hosts, для этого нужно использовать, например, такую команду: cat << end-of-text | nsupdate server 127.0.0.1 zone somenet.ru key rndc-key JhHyvY+7lUnJ1Ae1WSWcsQ== update add somehost.somenet.ru 86400 A 1.1.1.1 update delete someanotherhost.somenet.ru send end-of-text Edited November 20, 2009 by a0d75 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
SmalleR Posted November 20, 2009 И было бы неплохо автоматически удалять записи для серверов, которые не отвечают. Это совершенно ненужная операция. Время жизни днс кеша на клиенте больше, чем время на подъем НАСа, который не отвечает. Да и не будет клиент "ломится" на них, пока они лежат, если есть у него другие записи в кеше. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
a0d75 Posted November 20, 2009 Время жизни DNS кэша 60 секунд, если Вы внимательно посмотрели скрипт. Каждый неотвечающий NAS увеличивает время соединения клиента на 5-10 секунд, по крайней мере в нашей сети. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
IvanI Posted November 20, 2009 у меня кеш живет 3 секунды Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
SmalleR Posted November 20, 2009 Время жизни DNS кэша 60 секунд, если Вы внимательно посмотрели скрипт. Каждый неотвечающий NAS увеличивает время соединения клиента на 5-10 секунд, по крайней мере в нашей сети. Где логика? Если значение (даже искуственно заниженное) ttl кеша в 6-10 раз больше, чем практический "затык" с неотвечающим НАСом, в вашей сети? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
IvanI Posted November 20, 2009 Текущее время: 21:52:12,95 Введите новое время: C:\>ping vpn.aaa.ru Обмен пакетами с vpn.aaa.ru [192.168.20.47] по 32 байт: Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Статистика Ping для 192.168.20.47: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь), Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек C:\>goto start C:\>time Текущее время: 21:52:17,15 Введите новое время: C:\>ping vpn.aaa.ru Обмен пакетами с vpn.aaa.ru [192.168.20.78] по 32 байт: Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Статистика Ping для 192.168.20.78: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь), Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек C:\>goto start C:\>time Текущее время: 21:52:21,34 Введите новое время: C:\>ping vpn.aaa.ru Обмен пакетами с vpn.aaa.ru [192.168.20.78] по 32 байт: Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.78: число байт=32 время<1мс TTL=64 Статистика Ping для 192.168.20.78: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь), Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек C:\>goto start C:\>time Текущее время: 21:52:24,70 Введите новое время: C:\>ping vpn.aaa.ru Обмен пакетами с vpn.aaa.ru [192.168.20.47] по 32 байт: Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Ответ от 192.168.20.47: число байт=32 время<1мс TTL=64 Статистика Ping для 192.168.20.47: Пакетов: отправлено = 4, получено = 4, потеряно = 0 (0% потерь), Приблизительное время приема-передачи в мс: Минимальное = 0мсек, Максимальное = 0 мсек, Среднее = 0 мсек Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Dyr Posted November 23, 2009 (edited) Реализация интересная, но для данной задачи бессмысленная. У нас прекрасно работали PPTP-сервера с выставленным TTL 0 vpn.ozerki.net. Как минимум винда, в рамках попытки установления TCP-соединения, посылает три пакета, каждый раз при этом разрешая имя в новый ip. Edited November 23, 2009 by Dyr Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
f13 Posted November 23, 2009 я бы через SRV сделал, но тут клинта модифицировать надо Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
a0d75 Posted November 24, 2009 Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300 Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
IvanI Posted November 24, 2009 Проще пофиксить зоопарк, поставив то что будет держать 1300 соединений, по нагрузке + 1 запасной и под развитие Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Dyr Posted November 24, 2009 Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300 Можно и это исправить, вставляя, скажем, две записи IN A x.x.x.1 и одну x.x.x.2 - тогда количество соединений по серверам поделится примерно как два к одному. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
sirmax Posted November 25, 2009 Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300Можно и это исправить, вставляя, скажем, две записи IN A x.x.x.1 и одну x.x.x.2 - тогда количество соединений по серверам поделится примерно как два к одному. Вы уверены? Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Dyr Posted November 25, 2009 Да, а что вас смущает? Именно так будут статистически распределяться в теории и именно это мы и наблюдали на практике. Только надо не забывать выставлять в DNS тип выдачи случайный, а не цикличный (в терминах BIND "rrset-order {order random}") Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
LuckySB Posted November 25, 2009 Да, а что вас смущает? Именно так будут статистически распределяться в теории и именно это мы и наблюдали на практике.Очень странно ж)Количество сессий на каждом NAS зависит не только от того сколько человек к нему ПОДКЛЮЧИЛИСЬ, но и от того сколько ОТКЛЮЧИЛИСЬ. В эпоху анлима народ конечно редко отключаеться... Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
Dyr Posted November 26, 2009 Возможно, мы не настолько долго ставили асинхронное распределение, чтобы накопление разницы между увеличенным прибытием на NAS и примерно одинаковым убытием по всем NASaм оказывалось того порядка, чтобы нарушать нужное распределение. Перечитал...нда...надеюсь, понятно обьяснил. :) Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
replicant Posted December 8, 2010 Распределение будет равномерным. На каждый сервер упадет число коннектов примерно равное числу всех абонентов онлайн деленное на кол-во активных серверов. Это подтверждается практикой. Рекомендуемый размер зоопарка чем больше - тем лучше, т.е. в случае выхода одного сервера нагрузка плавно распределится по другим машинам, а если их много, то не сильно вырастет на каждой отдельно взятой машине. Лучше всего, если все машины в зоопарке будут примерно равны между собой по производительности, чтобы не создавать затык в нормальном режиме работы + не менее 30% должны иметь запас по производительности и те, которые работают под нагрузкой в часы пик. Вставить ник Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...