Перейти к содержимому
Калькуляторы

Балансировщик загрузки NAS средствами DNS

Хочу поделиться способом балансировки загрузки 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

Изменено пользователем a0d75

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И было бы неплохо автоматически удалять записи для серверов, которые не отвечают.

Это совершенно ненужная операция.

Время жизни днс кеша на клиенте больше, чем время на подъем НАСа, который не отвечает.

Да и не будет клиент "ломится" на них, пока они лежат, если есть у него другие записи в кеше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Время жизни DNS кэша 60 секунд, если Вы внимательно посмотрели скрипт. Каждый неотвечающий NAS увеличивает время соединения клиента на 5-10 секунд, по крайней мере в нашей сети.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

у меня кеш живет 3 секунды

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Время жизни DNS кэша 60 секунд, если Вы внимательно посмотрели скрипт. Каждый неотвечающий NAS увеличивает время соединения клиента на 5-10 секунд, по крайней мере в нашей сети.

Где логика? Если значение (даже искуственно заниженное) ttl кеша в 6-10 раз больше, чем практический "затык" с неотвечающим НАСом, в вашей сети?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Текущее время: 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 мсек

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Реализация интересная, но для данной задачи бессмысленная. У нас прекрасно работали PPTP-сервера с выставленным TTL 0 vpn.ozerki.net. Как минимум винда, в рамках попытки установления TCP-соединения, посылает три пакета, каждый раз при этом разрешая имя в новый ip.

Изменено пользователем Dyr

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

я бы через SRV сделал, но тут клинта модифицировать надо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Проще пофиксить зоопарк, поставив то что будет держать 1300 соединений, по нагрузке + 1 запасной и под развитие

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300

Можно и это исправить, вставляя, скажем, две записи IN A x.x.x.1 и одну x.x.x.2 - тогда количество соединений по серверам поделится примерно как два к одному.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Основная задача - защита NAS от перегруза. У нас зоопарк, одни могут нормально держать 500 соединений, другие - 300
Можно и это исправить, вставляя, скажем, две записи IN A x.x.x.1 и одну x.x.x.2 - тогда количество соединений по серверам поделится примерно как два к одному.

Вы уверены?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, а что вас смущает? Именно так будут статистически распределяться в теории и именно это мы и наблюдали на практике.

Только надо не забывать выставлять в DNS тип выдачи случайный, а не цикличный (в терминах BIND "rrset-order {order random}")

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, а что вас смущает? Именно так будут статистически распределяться в теории и именно это мы и наблюдали на практике.
Очень странно ж)

Количество сессий на каждом NAS зависит не только от того сколько человек к нему ПОДКЛЮЧИЛИСЬ, но и от того сколько ОТКЛЮЧИЛИСЬ.

В эпоху анлима народ конечно редко отключаеться...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Перечитал...нда...надеюсь, понятно обьяснил. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Распределение будет равномерным. На каждый сервер упадет число коннектов примерно равное числу всех абонентов онлайн деленное на кол-во активных серверов.

 

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

 

Лучше всего, если все машины в зоопарке будут примерно равны между собой по производительности, чтобы не создавать затык в нормальном режиме работы + не менее 30% должны иметь запас по производительности и те, которые работают под нагрузкой в часы пик.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Гость
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Вставить в виде обычного текста

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.