Каскадирование Squid'ов

Во времена слишком дорогого анлима (64кбита — 1000руб), сотворили с товарищами кластер проксей, дабы увеличить суммарную пропускную способность. Время шло, цены менялись. Сейчас они уже более дружелюбны — мбитный анлим (с ночным удвоением скорости) стоит всё те же 1000руб. Но, не смотря на это, кластером всё ещё иногда пользуемся. Решил вот поделиться с общественностью методом создания такого добра, вдруг кому будет интересно.

Для опытов нам потребуется:

  1. 1 сервер с установленным на нём squid’ом + ещё какой-нибудь проксёй (если хотите, чтобы этот сервер был не только центральным, но и делился инетом). я расскажу про поднятие кластера на базе дебиана, 2 интернет-каналов и 3 сквидов (сквиды для родительских проксе выбраны по 2 причинам: из-за возомжности предоставления статистики по текущим соединениям; из-за лени искать альтернативу)
  2. Любое количество компьютеров, с любыми ОС и любыми http-проксями
  3. Опционально — апач, пхп и скрипт SqStat — для просмотря активности прокси

Будем считать что у нас есть 2 машины — 192.168.1.1 (у неё так же есть 2й ип, со 2м провайдером — 192.168.2.1) и 192.168.1.2.

Немного погуглив — я нашёл заметку без малого 5летней давности — Squid 2 chans. Из неё было выцеплено 2 момента — как, собственно, организовать кластер и как проксировать на разных интерфейсах.

Для начала — создадим дополнительные сервисы squid’a. Сперва — немного подправим конфиг сервера (/etc/squid/squid.conf). Т.к. кэш мне не нужен — я его отрубил. Делается это установкой параметра cache_dir следующим образом:

1
cache_dir null /var/spool/squid

Т.к. отключили кэш — отрубаем и лог записи в кэш

1
cache_store_log none

Откроем доступ к прокси для всех (нужно вставить до записи http_access deny purge):

1
2
acl all src 0.0.0.0/0.0.0.0
http_access allow all

Откроем доступ к прокси по протоколу cache_mgr с локалхоста (я не помню, какие параметры указаны в дефолтном конфиге — так что не помешает перед вставкой проверить, что уже есть):

1
2
3
acl manager proto cache_object # это строка, скорее всего, уже есть в конфиге
http_access allow manager localhost
http_access deny manager

Слушать порт 8080 (по дефолту — 3128):

1
http_port 8080

Для ограничения доступа к прокси — я предпочитаю использовать iptables (по-умолчанию — все пакеты отбрасываются), а не аутентификацию, поэтому прокся из конфига открыта для всех:

1
2
3
4
iptables -N proxy
iptables -A proxy -j REJECT
iptables -I proxy -s 192.168.1.2 -j ACCEPT
iptables -I INPUT -p tcp --dport 8080 -j proxy

Теперь добавим родительские прокси (говорю сразу — с приведённой ниже конфигурацией — ничерта не заработает. но дальше, по ходу повествования — ошибка будет найдена и исправлена :)):

1
2
3
cache_peer 127.0.0.1 parent 8081 0 no-query no-digest round-robin weight=4
cache_peer 127.0.0.1 parent 8082 0 no-query no-digest round-robin weight=1
cache_peer 192.168.1.2 parent 8080 0 no-query no-digest round-robin weight=4

Итого — 3 родительских прокси, с которых не будет запрашиваться кэш (no-query) и cache-digest (no-digest), родители будут циклически переключаться (round-robin). Ну и разный weight — ибо 2й канал у меня слабый. Запрещаем сквиду ходить напрямую (не через родителей):

1
never_direct allow all

Создаём 2 копии конфига — /etc/squid/squid_2.conf и /etc/squid/squid_3.conf. Удаляем из них строки, начинающиеся на cache_peer, never_direct. Изменяем значение параметра http_port на 8081 и 8082 соответственно. Изменяем пути до логов (здесь и далее по тексту — изменения будут указываться только для squid_2, для squid_3 — изменения аналогичны):

1
2
access_log /var/log/squid_2/access.log
cache_log /var/log/squid_2/cache.log

Так же не помешает создать этот путь и сменить владельца, дабы сквид мог писать логи:

1
2
mkdir /var/log/squid_2
chown proxy:proxy /var/log/squid_2

Указываем расположение pid-файла:

1
pid_filename /var/run/squid_2.pid

Расположение кэша я не менял — все 3 прокси спокойно работают с 1 каталогом. Но squid -z (инициализировать кэш) перед первым запуском сделать не помешает.

Теперь приступим к созданию init-скриптов. В файле /etc/init.d/squid комментируем код, ответственный за инициализацию кэша (т.к. скрипт не рассчитан на null-кэш):

1
2
3
4
5
# if [ -d "$cdr" -a! -d "$cdr/00" ]
# then
# log_warning_msg «Creating squid spool directory structure»
# $DAEMON -z
# fi

Копируем /etc/init.d/squid => /etc/init.d/squid_2. Изменяем squid_2:

1
2
3
NAME=squid_2
...
SQUID_ARGS="-D -sYC -f /etc/squid/squid_2.conf"

Так же, для душевного равновесия, можно изменить сообщения, которые выдаёт скрипт:

1
2
3
4
5
log_daemon_msg «Starting Squid HTTP proxy» «squid_2»
...
log_daemon_msg «Stopping Squid HTTP proxy» «squid_2»
...
log_daemon_msg «Restarting Squid HTTP proxy» «squid_2»

Для следующего фокуса — в начале инит-скрипта должны быть примерно следующие строки:

1
2
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6

Настраиваем запуск свеже созданного сервиса с системой:

1
update-rc.d squid_2 defaults

Запускаем дочерние прокси:

1
2
invoke-rc.d squid_2 start
invoke-rc.d squid_3 start

Вот он, момент истины — запускаем центральный прокси

1
invoke-rc.d squid start

и…

1
FATAL: ERROR: cache_peer 127.0.0.1 specified twice

… и нас жестоко обламывают.

Немного подумав (руки до гугля не доходят) — заменяем в одной записи 127.0.0.1 => localhost. Запускаем, и вот оно — счастье. Сквид на 2й машине можно настроить копированием /etc/squid/squid.conf и удалением оттуда упоминаний о cache_peer и never_direct + поправить права доступа по протоколу cache_mgr. Для тестирования — настроить любимый браузер на использования прокси и открыть любую страницу. Смотрим /var/log/squid/access.log, там должны быть примерно следующие строки:

1
2
3
4
1214499645.364 15335 89.189.176.111 TCP_MISS/206 214755 GET ru.download.nvidia.com/Windows/177.41/177.41_geforce_winxp_64bit_international_whql.exe — ROUNDROBIN_PARENT/192.168.1.2 application/octet-stream
1214499646.148 11138 89.189.176.111 TCP_MISS/206 534572 GET ru.download.nvidia.com/Windows/177.41/177.41_geforce_winvista_64bit_international_whql.exe — ROUNDROBIN_PARENT/127.0.0.1 application/octet-stream
1214499650.695 3564 89.189.176.111 TCP_MISS/206 370947 GET ru.download.nvidia.com/Windows/177.41/177.41_geforce_winvista_64bit_international_whql.exe — ROUNDROBIN_PARENT/localhost application/octet-stream
1214499658.899 52092 89.189.176.111 TCP_MISS/206 1115575 GET ru.download.nvidia.com/Windows/177.41/177.41_geforce_winvista_64bit_international_whql.exe — ROUNDROBIN_PARENT/192.168.1.2 application/octet-stream

Далее по плану — SqStat. Скачиваем архив, распаковываем в любую www-папку, переименовываем config.inc.php.defaults => config.inc.php и правим:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$squidhost[0]=«localhost»;
$squidport[0]=8080;
$cachemgr_passwd[0]="";
$resolveip[0]=false; # для красоты — можно и true поставить :)
$hosts_file[0]=«hosts.txt»;
$group_by[0]=«host»;

$squidhost[]=«localhost»;
$squidport[]=8081;
$cachemgr_passwd[]="";
$resolveip[]=false;
$hosts_file[]=«hosts.txt»;
$group_by[]=«host»;

$squidhost[]=«localhost»;
$squidport[]=8082;
$cachemgr_passwd[]="";
$resolveip[]=false;
$hosts_file[]=«hosts.txt»;
$group_by[]=«host»;

$squidhost[]=«localhost»;
$squidport[]=8081;
$cachemgr_passwd[]="";
$resolveip[]=false;
$hosts_file[]=«hosts.txt»;
$group_by[]=«host»;

$squidhost[]=«192.168.1.2»;
$squidport[]=8080;
$cachemgr_passwd[]="";
$resolveip[]=true;
$hosts_file[]=«hosts.txt»;
$group_by[]=«host»;

Открываем браузером sqstat.php и наблюдаем за активностью.

Так же выкладываю немного изменённую версию SqStat — дополнительно отображает суммарную скорость\объём по параметру группировки — sqstat.class.php, файл нужно положить в папку с оригинальным sqstat, заменив оригинал.

В пассивном режиме 3 сквида жрут 2.3% памяти, что в пересчёте на МБ составляет 14,72.

P.S. # squid -v

Squid Cache: Version 2.6.STABLE5

UPD: все же, надеюсь, понимают, что при скачивании в 1 поток через такую прокси — увеличения скорости не будет? для увеличения скорости необходимо запустить закачку с n потоками, где n — количество проксей в кластере (если веса одинаковы).

Comments