Mozhay Опубликовано 16 октября, 2010 (изменено) · Жалоба Доброго времени суток. Не подскажите, может кто сталкивался: следующая схема - бордер на x86 микротике, за ним в зоне реальников 2 ната, за ними - серые юзеры ( ядро ). До недавнего момента стоял Gentoo, без SMP ( rshaper не умеет с SMP работать ). Решили перейти на freebsd + firewall_nat + pipes ( tables ). Всё отлично, НО: как только загружаются цепочки ната - задержки во вне и у клиентов и на самих натах вырастают до 100-120мс и очень сильно падает пропускная способность интерфейсов. Обе машины одинаковые, вот конфиг: FreeBSD gw1 7.3-RELEASE FreeBSD 7.3-RELEASE #1: Thu Oct 14 23:11:23 MSD 2010 root@gw1:/usr/obj/usr/src/sys/GW1 i386 lspci 00:00.0 Host bridge: Intel Corporation 5000P Chipset Memory Controller Hub (rev b1) 00:02.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x8 Port 2-3 (rev b1) 00:03.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 3 (rev b1) 00:04.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x8 Port 4-5 (rev b1) 00:05.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 5 (rev b1) 00:06.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x8 Port 6-7 (rev b1) 00:07.0 PCI bridge: Intel Corporation 5000 Series Chipset PCI Express x4 Port 7 (rev b1) 00:08.0 System peripheral: Intel Corporation 5000 Series Chipset DMA Engine (rev b1) 00:10.0 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev b1) 00:10.1 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev b1) 00:10.2 Host bridge: Intel Corporation 5000 Series Chipset FSB Registers (rev b1) 00:11.0 Host bridge: Intel Corporation 5000 Series Chipset Reserved Registers (rev b1) 00:13.0 Host bridge: Intel Corporation 5000 Series Chipset Reserved Registers (rev b1) 00:15.0 Host bridge: Intel Corporation 5000 Series Chipset FBD Registers (rev b1) 00:16.0 Host bridge: Intel Corporation 5000 Series Chipset FBD Registers (rev b1) 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev d9) 00:1f.0 ISA bridge: Intel Corporation 631xESB/632xESB/3100 Chipset LPC Interface Controller (rev 09) 00:1f.1 IDE interface: Intel Corporation 631xESB/632xESB IDE Controller (rev 09) 00:1f.2 RAID bus controller: Intel Corporation 631xESB/632xESB SATA RAID Controller (rev 09) 00:1f.3 SMBus: Intel Corporation 631xESB/632xESB/3100 Chipset SMBus Controller (rev 09) 01:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Upstream Port (rev 01) 01:00.3 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express to PCI-X Bridge (rev 01) 02:00.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E1 (rev 01) 02:01.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E2 (rev 01) 02:02.0 PCI bridge: Intel Corporation 6311ESB/6321ESB PCI Express Downstream Port E3 (rev 01) 05:00.0 Ethernet controller: Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper) (rev 01) 05:00.1 Ethernet controller: Intel Corporation 80003ES2LAN Gigabit Ethernet Controller (Copper) (rev 01) 0a:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 0a:00.1 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 0c:0c.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02) cat /etc/sysctl.conf #security.bsd.see_other_uids=0 net.inet.ip.forwarding=1 net.inet.ip.fastforwarding=1 net.inet.ip.fw.one_pass=0 net.inet.ip.dummynet.io_fast=1 net.inet.icmp.icmplim=1024 net.inet.ip.fw.dyn_buckets=2048 net.inet.ip.dummynet.hash_size=1024 Нат запускается скриптом ( связка с Трафик-Инспектор сервер - остаточное явление - доживает дни до перехода на UTM) - строки запуска на 1 абонента такие: # общие exec("ipfw -f flush"); exec("ipfw -f pipe flush"); exec("ipfw -f queue flush"); exec("ipfw nat 65000 config ip 109.197.112.2 log"); exec("ipfw pipe 1 config bw 8192Kbit/s mask dst-ip 0xffffffff"); exec("ipfw add pipe 1 ip from table\(101\) to any out"); exec("ipfw add pipe 1 ip from any to table\(101\)"); # ........ # сам юзер: exec("ipfw add $user_id nat 65000 ip from $user_ip/32 to any"); exec("ipfw add $user_id nat 65000 ip from any to $real_ip"); и в трубу: exec("ipfw table 101 add $user_ip"); После этого, скрипт работает в бесконечном цикле, отлавливает по in_array кто вошёл, кто вышел и добавляет или удаляет цепочки ната и мемберов из групп пайпов. Никакого дублирования нет точно, проверял много раз - всё чётко. НО: вырастают безумно таймы и падает производительность интерфейсов. Вот ещё некоторые данные: last pid: 9419; load averages: 1.84, 1.86, 1.58 up 0+00:42:17 15:32:59 78 processes: 7 running, 52 sleeping, 19 waiting CPU 0: 31.6% user, 0.0% nice, 0.4% system, 0.0% interrupt, 68.0% idle CPU 1: 0.4% user, 0.0% nice, 0.4% system, 0.0% interrupt, 99.2% idle CPU 2: 0.4% user, 0.0% nice, 67.3% system, 0.0% interrupt, 32.3% idle CPU 3: 0.0% user, 0.0% nice, 99.6% system, 0.0% interrupt, 0.4% idle Mem: 14M Active, 9016K Inact, 97M Wired, 44K Cache, 11M Buf, 3382M Free Swap: 8192M Total, 8192M Free PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND 13 root 1 171 ki31 0K 8K CPU1 1 39:41 100.00% idle: cpu1 27 root 1 -68 - 0K 8K CPU3 3 30:54 100.00% em1 taskq 14 root 1 171 ki31 0K 8K RUN 0 36:32 91.06% idle: cpu0 26 root 1 -68 - 0K 8K CPU2 2 22:44 70.46% em0 taskq 12 root 1 171 ki31 0K 8K RUN 2 18:38 33.98% idle: cpu2 1068 root 1 100 0 12116K 7060K select 0 7:10 17.48% php vmstat -i interrupt total rate irq1: atkbd0 4 0 irq20: atapci1 8111 3 cpu0: timer 4984635 1971 irq256: em0 5471836 2164 irq257: em1 1848173 731 cpu1: timer 4984449 1971 cpu3: timer 5017736 1984 cpu2: timer 5017735 1984 Total 27332679 10811 gw0# ping ya.ru PING ya.ru (87.250.251.3): 56 data bytes 64 bytes from 87.250.251.3: icmp_seq=0 ttl=58 time=103.548 ms 64 bytes from 87.250.251.3: icmp_seq=1 ttl=58 time=93.891 ms 64 bytes from 87.250.251.3: icmp_seq=2 ttl=58 time=90.336 ms 64 bytes from 87.250.251.3: icmp_seq=3 ttl=58 time=109.123 ms 64 bytes from 87.250.251.3: icmp_seq=4 ttl=58 time=103.121 ms На микротике: [admin@MikroTik] > ping ya.ru 77.88.21.3 64 byte ping: ttl=62 time=4 ms 77.88.21.3 64 byte ping: ttl=62 time=4 ms 77.88.21.3 64 byte ping: ttl=62 time=4 ms 77.88.21.3 64 byte ping: ttl=62 time=4 ms 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 4/4.0/4 ms Думаю проблема в этом: top -SP CPU0 0 551:36 100.00% em1 taskq Кто сталкивался - ткните носом. Не хочется экспериментировать с natd, говорят что кернел нат быстрее, думаю проблема в настройках sysctl ..... Буду благодарен за помощь. Изменено 16 октября, 2010 пользователем Mozhay Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Latik Опубликовано 16 октября, 2010 (изменено) · Жалоба Вместо 2*count($user_ip) правил: exec("ipfw add $user_id nat 65000 ip from $user_ip/32 to any");exec("ipfw add $user_id nat 65000 ip from any to $real_ip"); сделать где-то сверху exec("ipfw add nat 65000 ip from table 101 to any"); exec("ipfw add nat 65000 ip from any to $real_ip"); Изменено 16 октября, 2010 пользователем Latik Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Mozhay Опубликовано 16 октября, 2010 · Жалоба Я правильно понял, что такая нагрузка из-за большого ( более 1200 ) пар цепочек ната ? Т.е. я по анологии с трубой пихаю юзеров в таблицу? exec("ipfw -f flush"); exec("ipfw -f pipe flush"); exec("ipfw -f queue flush"); exec("ipfw disable one_pass"); exec("ipfw nat 65000 config ip 109.197.112.2 log"); # труба exec("ipfw pipe 81 config bw 8192Kbit/s mask dst-ip 0xffffffff"); exec("ipfw add pipe 81 ip from table\(108\) to any out"); exec("ipfw add pipe 81 ip from any to table\(108\)"); # нат exec("ipfw add nat 65000 ip from table 108 to any"); exec("ipfw add nat 65000 ip from any to 109.197.112.2"); # типичный пользователь - добавление exec("ipfw table 108 add $user_ip"); # типичный пользователь - удаление exec("ipfw table 108 delete $user_ip"); Получается таблица одна и на нат и на трубу? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 16 октября, 2010 · Жалоба Я правильно понял, что такая нагрузка из-за большого ( более 1200 ) пар цепочек ната ?Наверняка.Пакет не должен пробегать больше сотни правил. Смотрите "tablearg" в man ipfw. В идеале NAT лучше унести на Linux, а на FreeBSD оставить только шейперы. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 16 октября, 2010 (изменено) · Жалоба До недавнего момента стоял Gentoo, без SMP ( rshaper не умеет с SMP работать ). Решили перейти на freebsd + firewall_nat + pipes ( tables ). NAT лучше реализовать на отдельной машине (на пограничном маршрутизаторе), иначе будут проблемы с классификацией трафика по IP, а сам шейпер можно сделать мостом. Кроме того, все нормальные люди делают шейпинг на Linux с помощью фильтров u32 или flow. Изменено 16 октября, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Mozhay Опубликовано 16 октября, 2010 · Жалоба До недавнего момента стоял Gentoo, без SMP ( rshaper не умеет с SMP работать ). Решили перейти на freebsd + firewall_nat + pipes ( tables ).NAT лучше реализовать на отдельной машине (на пограничном маршрутизаторе), иначе будут проблемы с классификацией трафика по IP, а сам шейпер можно сделать мостом. Кроме того, все нормальные люди делают шейпинг на Linux с помощью фильтров u32 или flow. С таблицами на нат стало приемлемо ( по 700-750 юзеров на каждый из 2х натов в пике): 35 root 1 -68 - 0K 8K - 0 775:37 31.93% em1 taskq 34 root 1 -68 - 0K 8K - 3 551:22 18.46% em0 taskq Огромное спасибо всем) А по теории организации - у меня бордером стоит Микротик x86 ( RB1000 стоит на горячую замену с аналогичными настройками без коммутации ) - он разруливает bgp на 3 внешних канала ( временно работает только один и второй в фейл-овере ), за ним моя сетка /21 - там уже сервера и внешние интерфейсы натов ( они же шейперы ). За ними стоит ядро на DGS-3610G стекируемые по 10G, на котором ip policy на роутинг как load-balance - он сам рулит распределением на 2 ната. Какой смысл разделять шейпинг и нат? Т.е. немного не так - какая разница: 2 сервера с нат+шейпер или 1 нат и 1 шейпер? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 16 октября, 2010 · Жалоба все нормальные люди делают шейпинг на LinuxНе все :) Во-первых, sc не умеет динамически менять скорость по времени суток, объёму трафика и т.д. Или уже умеет? Во-вторых, sc поддерживает только одну сеть /16. Как быть тем, у кого блоков несколько (например, два - приватные и публичные)? В-третьих, sc - это невероятный монстр: 3330 строк! Для сравнения, шейпер для freebsd+ipfw+dummynet состоит из 756 строк (разница в 4,5 раза), включая серверные модули для пары биллингов, умеет динамически менять скорость и не ограничен IP-диапазонами. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 16 октября, 2010 · Жалоба какая разница: 2 сервера с нат+шейпер или 1 нат и 1 шейпер?У одной задачи больше шансов целиком уместиться в процессорный кэш.Плюс уменьшаются внутренние расходы на синхронизацию. Это в теории. На практике - лично у меня вторая схема оказалась быстрее. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 16 октября, 2010 (изменено) · Жалоба все нормальные люди делают шейпинг на LinuxНе все :) Не вырывайте слова из контекста. Я имею в виду, что если люди и делают шейпер на Linux, то с помощью классификаторов u32 или flow, а не какого-то устаревшего rshaper. Во FreeBSD мне самому больше нравится реализация правил шейпинга, потому что они проще. Во-первых, sc не умеет динамически менять скорость по времени суток, объёму трафика и т.д.Или уже умеет? Поддержку множителя сделать довольно просто, а менять в зависимости от времени суток надо с помощью cron. Во-вторых, sc поддерживает только одну сеть /16.Как быть тем, у кого блоков несколько (например, два - приватные и публичные)? Это я еще полгода назад доделал. Если использовать filter_method = u32, то поддерживается сколько угодно блоков с одинаковыми октетами, но IP-адресов все равно должно быть не больше 2^16 - 2. В-третьих, sc - это невероятный монстр: 3330 строк!Для сравнения, шейпер для freebsd+ipfw+dummynet состоит из 756 строк (разница в 4,5 раза), включая серверные модули для пары биллингов, умеет динамически менять скорость и не ограничен IP-диапазонами. Там еще POD для создания man-страницы в исходник встроен, который занимает половину количества строк. Во FreeBSD правила намного проще, и для нее не надо полторы тыщи строк городить. Если бы я писал для FreeBSD (что уже неоднократно делалось многими), то тоже вышло бы примерно 500-700 строк. А для Linux получилось много кода, потому что надо генерировать довольно нетривиальные хэш-фильтры, проверять правильность входных данных и т.п. В простых админских скриптах никаких проверок обычно не делается, т.к. можно положиться на используемые программы. При использовании пакетных режимов одно некорректное правило может прервать процесс загрузки правил. Изменено 16 октября, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Ilya Evseev Опубликовано 16 октября, 2010 · Жалоба Там еще POD для создания man-страницы в исходник встроен, который занимает половину количества строк.sc.conf.pod - 335 строк.sc - 485 из 2520. В сумме 620 из 3330. С одной стороны, на половину никак не тянет. С другой стороны, если утилиту приходится сопровождать столь объёмным описанием, не есть ли это признак её чрезмерной усложнённости? ;-) В любом случае, хорошо, что такой инструмент есть. Мой Вам респект! Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 16 октября, 2010 (изменено) · Жалоба Вообще, да. Сложновато получилось. Было бы неплохо кусок кода, генерирующий хэш-фильтры по списку подсетей, переписать на C и перекинуть в tc. Сейчас хэш-фильтрами пользоваться без прослоек абсолютно невозможно, поэтому собственно все и шейпят на FreeBSD, где более внятный язык правил. Изменено 16 октября, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Dyr Опубликовано 18 октября, 2010 · Жалоба Интересно, не пробовал ли кто-нибудь из присутствующих dummynet под Linux - Луиджи не так давно портировал ipfw и dummynet под Linux (и под Windows, кстати). Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...