Если у вас есть популярный веб-сервис, которым пользуются в разных странах (и время отклика тогда имеет значение), или в интранете разных городах с узким каналом между ним, имеет смысл подумать над распределением серверов ближе к конечным пользователям. Об этом писали на хабре, но как то отрывочно и не вдаваясь в подробности.
Задача разделяется на
1) Выдача через DNS ближайшего регионального сервера ( GEO DNS )
2) Синхронизация изменений в базе данных между регионами ( DB Replication, Cluster )
Рассмотрим первую задачку:
Надо поднять сервер DNS так? чтобы он отдавал в каждый регион адрес наиболее близкого сервера (как веб так и db).
Это можно сделать с использованием обычного bind сервера, нужно только сгенерировать правила для сопоставления IP адресов и зон.
Для IPv4 можно использовать скрипт genv4.bash (работает для Ubuntu 9.04):
или можно скачать уже сгенерированный тут
Для IPv6 можно использовать пару скриптов (genv6.bash):
и GeoIPv6.pl
или скачать уже сгенерированный тут
после того как у нас есть файл с правилами, настроим bind файл named.conf, добавив в него строчки:
(пример)
Разберем, что тут делается — include подключает созданный нами с файлом правил (acl) по регионам.
Далее, создаются 3 view — для клиентов Северной и Южной америк и для всех остальных клиентов.
match-clients определяет список правил. — вы можете добавить свои собственные acl правила.
Вот, собственно и все по первому шагу.
Продолжение по репликациям и кластеру в MySQL следует…
Задача разделяется на
1) Выдача через DNS ближайшего регионального сервера ( GEO DNS )
2) Синхронизация изменений в базе данных между регионами ( DB Replication, Cluster )
Рассмотрим первую задачку:
Надо поднять сервер DNS так? чтобы он отдавал в каждый регион адрес наиболее близкого сервера (как веб так и db).
Это можно сделать с использованием обычного bind сервера, нужно только сгенерировать правила для сопоставления IP адресов и зон.
Для IPv4 можно использовать скрипт genv4.bash (работает для Ubuntu 9.04):
#!/bin/bash
[ -f GeoIPCountryCSV.zip ] || wget -T 5 -t 1 http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
unzip GeoIPCountryCSV.zip || exit 1
echo -n "Creating CBE (Country,Begin,End) CSV file..."
awk -F \" '{print $10","$6","$8}' GeoIPCountryWhois.csv > cbe.csv
rm -f GeoIPCountryWhois.csv
echo -ne "DONE\nGenerating BIND GeoIP.acl file..."
(for c in $(awk -F , '{print $1}' cbe.csv | sort -u)
do
echo "acl \"$c\" {"
grep "^$c," cbe.csv | awk -F , 'function s(b,e,l,m,n) {l = int(log(e-b 1)/log(2)); m = 2^32-2^l; n = and(m,e); if (n == and(m,b)) {printf "\t%u.%u.%u.%u/%u;\n",b/2^24%6,b/2^16%6,b/2^8%6,b%6,32-l} else {s(b,n-1); s(n,e)}} s($2,$3)'
echo -e "};\n"
done) > GeoIP.acl
rm -f cbe.csv
echo "DONE"
exit 0
или можно скачать уже сгенерированный тут
Для IPv6 можно использовать пару скриптов (genv6.bash):
#!/bin/bash
d='http://geolite.maxmind.com/download/geoip/database/'
f=$(wget -qT 5 -t 1 -O- $d | egrep -o 'GeoIPv6-[0-9]{8}\.csv\.gz' | head -1)
[ -z "$f" ] && exit 1; [ -f $f ] || wget -T 5 -t 1 $d$f || exit 1
echo -n "Creating CBE (Country,Begin,End) CSV file..."
gunzip -c $f | awk -F \" '{print $10","$6","$8}' > cbe.csv
echo -e "DONE\nGenerating BIND GeoIPv6.acl file..."
(for c in $(awk -F , '{print $1}' cbe.csv | sort -u)
do
echo "$c" >&2
echo "acl \"${c}v6\" {"
grep "^$c," cbe.csv | ./GeoIPv6.pl
echo -e "};\n"
done) > GeoIPv6.acl
rm -f cbe.csv
echo "DONE"
exit 0
и GeoIPv6.pl
#!/usr/bin/perl
use strict;
use bignum;
use IPC::Open2; open2(*BCOUT,*BCIN,'bc -l');
sub rs {
my ($b,$e) = @_;
print BCIN "scale=40; l($e-$b 1)/l(2)\n";
my ($l) = split('\.',);
my $m = 2**128-2**$l;
my $n = $m & $e;
if ($n == ($m & $b)) {
my @x; for (my $p = 112; $p > 0; $p -= 16) {
print BCIN "scale=0; $b/2^$p\n";
push(@x,e536);
}
printf "\t%x:%x:%x:%x:%x:%x:%x:%x/%u;\n",$x[0],$x[1],$x[2],$x[3],$x[4],$x[5],$x[6],$be536,128-$l;
} else {
rs($b,$n-1); rs($n,$e);
}
}
while () {chomp($_); my ($c,$b,$e) = split(',',$_); rs($b,$e)}
или скачать уже сгенерированный тут
после того как у нас есть файл с правилами, настроим bind файл named.conf, добавив в него строчки:
(пример)
include "/path/to/GeoIP.acl";
view "north_america" {
match-clients { US; CA; MX; };
recursion no;
zone "example555.com" {
type master;
file "pri/example555-north-america.db";
};
};
view "south_america" {
match-clients { AR; CL; BR; PY; PE; EC; CO; VE; BO; UY; };
recursion no;
zone "example555.com" {
type master;
file "pri/example555-south-america.db";
};
};
view "other" {
match-clients { any; };
recursion no;
zone "example555.com" {
type master;
file "pri/example555-other.db";
};
};
Разберем, что тут делается — include подключает созданный нами с файлом правил (acl) по регионам.
Далее, создаются 3 view — для клиентов Северной и Южной америк и для всех остальных клиентов.
match-clients определяет список правил. — вы можете добавить свои собственные acl правила.
Вот, собственно и все по первому шагу.
Продолжение по репликациям и кластеру в MySQL следует…