Jump to content
Калькуляторы

sc: скрипт для управления Linux-шейпером

Очень жаль, буду сочинять сам, получается не так красиво как хочется. ))

По поводу IFB, не помню точно, но по моему у него проблемы при работе с маркированными пакетами.

Share this post


Link to post
Share on other sites

А как задается максимальная пропускная способность интерфейса?

Share this post


Link to post
Share on other sites
А как задается максимальная пропускная способность интерфейса?
А зачем? Максимальная скорость считается равной номинальной скорости интерфейса на канальном уровне. Настроек в программе для этого дела нет, т.к. мне было не нужно. Если надо ограничить, можете в функциях rul_init_u32 и rul_init_flow после создания qdisc дописать код вида:

$TC->("class add dev $dev parent 1: classid 1:$root_cid htb rate $max_rate ceil $max_rate");

где $dev -- интерфейс, $root_cid -- номер root classid (какой-то из неиспользуемых под хосты), $max_rate -- скорость.

Edited by photon

Share this post


Link to post
Share on other sites
А зачем? Максимальная скорость считается равной номинальной скорости интерфейса на канальном уровне.

так если провайдер нам отдает не 100 мегабит, а 40, то об этом Вашему скрипту необязательно знать?

Share this post


Link to post
Share on other sites
А зачем? Максимальная скорость считается равной номинальной скорости интерфейса на канальном уровне.

так если провайдер нам отдает не 100 мегабит, а 40, то об этом Вашему скрипту необязательно знать?

Конечно необязательно. Шейпинг (внесение задержек) делается на стороне отправителя, т.е. если вам провайдер отдает трафик со скоростью 40mbit, то это зависит только от него. Сколько отдаете вы ему -- не суть важно, главное чтобы у принимающей стороны буфер не переполнялся и потерь не было.
Edited by photon

Share this post


Link to post
Share on other sites

2photon: ты уже реализовывал схему, shape+policy и policy+policy? Если это делать то фильтры как лучше сделать iptables/ipset + fw в tc? Или как то можно хешировать?

Share this post


Link to post
Share on other sites

[root@rtr-test ~]# sc init

[root@rtr-test ~]# sc list

Option "-p" is unknown, try "tc -help".

sc: unable to close pipe for /sbin/tc at /usr/local/sbin/sc line 768

main::log_carp('unable to close pipe for /sbin/tc') called at /usr/local/sbin/sc line 997

main::rul_load_u32() called at /usr/local/sbin/sc line 1498

main::cmd_list() called at /usr/local/sbin/sc line 414

main::main('list') called at /usr/local/sbin/sc line 349

 

 

Linux rtr-test 2.6.18-194.el5 #1 SMP Fri Apr 2 14:58:14 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

centos 5.5

iptables v1.4.9.1

ipset v4.3, protocol version 4.

Kernel module protocol version 4.

[root@rtr-test ~]# tc -p

Option "-p" is unknown, try "tc -help".

[root@rtr-test ~]# tc -V

tc utility, iproute2-ss061002

 

 

Edited by Myp

Share this post


Link to post
Share on other sites
2photon: ты уже реализовывал схему, shape+policy и policy+policy? Если это делать то фильтры как лучше сделать iptables/ipset + fw в tc? Или как то можно хешировать?
Реализовал, но не довел до конца и еще не тестровал на практике. Полисинг делается на хэш-фильтрах u32. Разница по сравнению с шейпингом лишь в том, что на интерфейсе создается ingress qdisc ffff:,

tc qdisc add dev $dev handle ffff: ingress

хэш-фильтр,

tc filter add dev $dev parent ffff: protocol ip pref $pref_hash u32
tc filter add dev $dev parent ffff: protocol ip pref $pref_hash handle $ht1: u32 divisor $div1
tc filter add dev $dev parent ffff: protocol ip pref $pref_hash u32 ht 800:: match ip $match $net hashkey mask $hmask1 at $offset link $ht1:

($offset = 12 или 16 в зависимости от интерфейса и направления трафика) и краевые фильтры

tc filter replace dev $dev parent ffff: pref $pref_leaf handle $ht:$key u32 ht $ht:$key: match ip src $ip police rate $rate buffer 30000 drop flowid ffff:

 

qdisc и class для полисинга, естественно, не нужны.

 

[root@rtr-test ~]# sc init

[root@rtr-test ~]# sc list

Option "-p" is unknown, try "tc -help".

sc: unable to close pipe for /sbin/tc at /usr/local/sbin/sc line 768

main::log_carp('unable to close pipe for /sbin/tc') called at /usr/local/sbin/sc line 997

main::rul_load_u32() called at /usr/local/sbin/sc line 1498

main::cmd_list() called at /usr/local/sbin/sc line 414

main::main('list') called at /usr/local/sbin/sc line 349

 

[root@rtr-test ~]# tc -V

tc utility, iproute2-ss061002

Значит надо использовать более новую версию tc, в которой уже есть ключ -p, а не четырехлетней давности. Исходник здесь: http://devresources.linuxfoundation.org/de...oute2/download/

Или можно убрать из sc ключ -p, который выводит в фильтрах IP-адреса в десятичном формате вместо шестнадцатеричных значений.

Кроме того, sc list сразу после sc init -- это неправильная последовательность команд. Она не создает никаких правил для конкретных IP-адресов. Чтобы sc list было что показывать, надо выполнить sc add ... или заполнить базу какими-то данными и выполнить sc load вместо init и add.

Edited by photon

Share this post


Link to post
Share on other sites
Разница по сравнению с шейпингом лишь в том, что на интерфейсе создается ingress qdisc ffff:
Спс за ответ. Т.е. относительно стандартной схемы с шейпингом, изменения в паре if и убрать class и qdisc?

Правильно ли я понимаю, что нужно менять направление, т.е. полисится входящий на интерфейс трафик?

Еще такой вопрос, на сколько снижается нагрузка на систему по сравнению с шейпингом? Имеет ли смысл, исходящий как раз полисить?

 

Реальна ли такая схема, например юзеры со скоростями до N Мбит шейпятся, свыше N Мбит полисятся?

Edited by SokolovS

Share this post


Link to post
Share on other sites
Спс за ответ. Т.е. относительно стандартной схемы с шейпингом, изменения в паре if и убрать class и qdisc?

Правильно ли я понимаю, что нужно менять направление, т.е. полисится входящий на интерфейс трафик?

Да.

 

Еще такой вопрос, на сколько снижается нагрузка на систему по сравнению с шейпингом? Имеет ли смысл, исходящий как раз полисить?

Реальна ли такая схема, например юзеры со скоростями до N Мбит шейпятся, свыше N Мбит полисятся?

Вот это как раз не очевидно. По-моему, выгоды от полисинга будет мало. Проще всех шейпить с максимально простой краевой дисциплиной (pfifo, bfifo), чем устраивать такие сложные танцы с правилами. Если делать полисинг в одном направлении, а шейпинг в другом, вся обработка трафика будет сидеть на одном интерфейсе, что нежелательно. Имеет смысл сравнивать конфигурации shaping+shaping и policing+policing.
Edited by photon

Share this post


Link to post
Share on other sites
Если делать полисинг в одном направлении, а шейпинг в другом, вся обработка трафика будет сидеть на одном интерфейсе, что нежелательно. Имеет смысл сравнивать конфигурации shaping+shaping и policying+policying.
Спс. Что-то сразу об этом не подумал.

Ну а в схеме policying+policying есть выигрыш?

Share this post


Link to post
Share on other sites
Если делать полисинг в одном направлении, а шейпинг в другом, вся обработка трафика будет сидеть на одном интерфейсе, что нежелательно. Имеет смысл сравнивать конфигурации shaping+shaping и policying+policying.
Спс. Что-то сразу об этом не подумал.

Ну а в схеме policying+policying есть выигрыш?

Не знаю, я пока не сравнивал. С точки зрения качества обслуживания у юзеров с малыми гарантированными скоростями от полисинга явно будут проблемы с потоковым видео и звуком. Если делать смешанные схемы (кого-то шейпить, кого-то полисить), то будет происходить периодическое забивание приемной очереди интерфейса, которое ухудшит жизнь людям с низкими скоростями, и надо будет настраивать приоритеты обслуживания очередей в пользу бедных. Вот когда у каждого будет в среднем около 10 Мбит/с, тогда есть смысл всех полисить.

Share this post


Link to post
Share on other sites

Полисинг по свойствам оказался лучше, чем я о нем думал. TCP-трафик нарезает довольно точно, даже при 64kbit/s, хотя флуктуации все равно больше, чем при шейпинге. Для больших полос пропускания нужно сильно увеличивать burst (до 1-2 мегабайтов). На днях сделаю релиз версии sc с полисингом.

 

Вышла версия 1.2.0: https://sourceforge.net/projects/sc-tool/.

Edited by photon

Share this post


Link to post
Share on other sites

Ок. Спс за новую версию. Я тоже на днях тестировал полисинг и на скоростях от 1 Мбит практически не увидел разницы, TCP корректирует скорость нормально. Игрухам по UDP таких скоростей не требуется, ну а торрентчикам вобще поифг лишь бы скорость выдавало. burst действительно нужно побольше ставить, дефолта конечно же мало.

Edited by SokolovS

Share this post


Link to post
Share on other sites

photon

Доброго времени суток.

Вопрос. С каким количеством пользователей может работать ваш скрипт? 2к, 4к, 6к юзеров? При условии что канал выхода шлюз-шейпер-сервера в интернет 1 гигабит, как в теории, так и на практике.

Share this post


Link to post
Share on other sites
photon

Доброго времени суток.

Вопрос. С каким количеством пользователей может работать ваш скрипт? 2к, 4к, 6к юзеров? При условии что канал выхода шлюз-шейпер-сервера в интернет 1 гигабит, как в теории, так и на практике.

Дело скорее не в скрипте, а в возможностях железа и QoS-подсистемы ядра. Теоретически, количество пользователей ограничено максимальным количеством дочерних классов (2^{16} - 2 = 65534). На практике подобный шейпер успешно обслуживал около 4000 пользователей (Core 2 Quad Q6600, броадкомовские сетевухи) с общим пакетрейтом до 200 kpps в пиках. С полисингом еще не пробовал, т.к. сейчас работаю в другом месте. Генерируемые правила достаточно оптимальны, поэтому на i7 с интеловскими сетевухами вполне можно потянуть 5000 юзеров или больше.
Edited by photon

Share this post


Link to post
Share on other sites

2photon: с полисингом не все так гладко получилось у меня :( Там же правило вешается в фильтре, а у юзера может быть подсеть или несколько адресов. Это минус относительно шейпинга где указывается класс и все IP юзера можно на этот класс повесить.

Edited by SokolovS

Share this post


Link to post
Share on other sites

Теоретически, на фильтр можно вешать подсеть, если маску явно указывать. Но между несколькими IP из разных подсетей полосу нельзя поделить с помощью полисинга. Я, кстати, не внедряю эту возможность даже для шейпинга, поскольку схема с одним IP на канал значительно упрощает структуру базы данных и соответствующие функции для работы с ней. Иначе придется работать с двухсвязным списком, где у каждого адреса будет указан его основной IP, а также делать в коде кучу проверок по поводу того, является ли данный IP основным или дополнительным.

Edited by photon

Share this post


Link to post
Share on other sites

Кстати ты как то расчитываешь burst/cburst или по дефолту все?

Share this post


Link to post
Share on other sites

Кстати ты как то расчитываешь burst/cburst или по дефолту все?

По дефолту. Там оно само вроде как рассчитывается, исходя из минимальных требований к burst, про которые в man tc-htb говорится. Для шейпинга главное, чтобы quantum не уменьшался до величин меньше MTU, иначе повалят ошибки, поэтому он зафиксирован на значении 1500. Для полисинга на скоростях в несколько десятков мегабит нужен burst примерно в 1 Мб. Чтобы уменьшить амплитуду начального всплеска скорости для малых полос пропускания, можно поставить burst поменьше.

Edited by photon

Share this post


Link to post
Share on other sites
Дело скорее не в скрипте, а в возможностях железа и QoS-подсистемы ядра. Теоретически, количество пользователей ограничено максимальным количеством дочерних классов (2^{16} - 2 = 65534). На практике подобный шейпер успешно обслуживал около 4000 пользователей (Core 2 Quad Q6600, броадкомовские сетевухи) с общим пакетрейтом до 200 kpps в пиках. С полисингом еще не пробовал, т.к. сейчас работаю в другом месте. Генерируемые правила достаточно оптимальны, поэтому на i7 с интеловскими сетевухами вполне можно потянуть 5000 юзеров или больше.
А как был настроен скрипт на том шейпере с ~4к пользователями: для работы через ipset+iptables или u32? И какая разница между ними вплане быстродействия\ресурсопотребления?

 

Share this post


Link to post
Share on other sites

А как был настроен скрипт на том шейпере с ~4к пользователями: для работы через ipset+iptables или u32? И какая разница между ними вплане быстродействия\ресурсопотребления?

На том шейпере использовался u32, поскольку нужно было сделать несколько IP на канал, от чего в последствии отказались. Правила, которые генерируются сейчас, используют хэширование по двум октетам, и поэтому несколько оптимальнее, чем раньше. Фильтр flow появился относительно недавно, и он применим только в том случае, если у пользовательских IP-адресов не совпадают два последних октета. Правила для flow генерировать значительно проще. ipset там нужен для хранения списка разрешенных IP, поскольку фильтры для отдельных адресов в случае flow не создаются. Если на шейпере не используется iptables (не загружаются правила и модули ядра), то u32 более оптимален.

Edited by photon

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Большая просьба к людям, использующим скрипт в production, отписаться в теме по поводу текущих нагрузок (общий пакетрейт и загруженность процессора в часы наибольшей нагрузки), параметров железа (процессор, модель используемых сетевух) и числа обслуживаемых пользователей. Также весьма интересным является сравнение нагрузок процессора при использовании полисинга и шейпинга с фильтром u32.
Не у себя, но пример показателен, статистика в ЧНН

2 x Intel Xeon E5530  @ 2.40GHz
top - 23:26:47 up 15 days, 5 min,  1 user,  load average: 0.04, 0.14, 0.11
Tasks: 152 total,   1 running, 151 sleeping,   0 stopped,   0 zombie
Cpu0  :  8.6%us,  0.6%sy,  0.0%ni, 90.3%id,  0.1%wa,  0.0%hi,  0.4%si,  0.0%st
Cpu1  :  2.3%us,  0.2%sy,  0.0%ni, 76.3%id,  0.1%wa,  1.9%hi, 19.3%si,  0.0%st
Cpu2  :  1.6%us,  0.1%sy,  0.0%ni, 76.7%id,  0.0%wa,  1.9%hi, 19.6%si,  0.0%st
Cpu3  :  1.3%us,  0.1%sy,  0.0%ni, 77.2%id,  0.0%wa,  1.9%hi, 19.5%si,  0.0%st
Cpu4  :  4.9%us,  0.6%sy,  0.0%ni, 94.1%id,  0.0%wa,  0.0%hi,  0.4%si,  0.0%st
Cpu5  :  1.6%us,  0.4%sy,  0.0%ni, 76.9%id,  0.0%wa,  1.9%hi, 19.2%si,  0.0%st
Cpu6  :  1.4%us,  0.5%sy,  0.0%ni, 77.1%id,  0.0%wa,  1.9%hi, 19.1%si,  0.0%st
Cpu7  :  1.5%us,  0.3%sy,  0.0%ni, 76.9%id,  0.0%wa,  1.9%hi, 19.4%si,  0.0%st

ethtool -i eth0 
driver: igb (i82576)
version: 1.3.16-k2
firmware-version: 1.2-1

ethtool -i eth1
driver: igb (i82576)
version: 1.3.16-k2
firmware-version: 1.2-1

eth0      Link encap:Ethernet  HWaddr 00:1b:21:4f:26:6d
          RX packets:3344738895 errors:0 dropped:192 overruns:5945 frame:0
          TX packets:1878349725 errors:0 dropped:0 overruns:0 carrier:0
eth1      Link encap:Ethernet  HWaddr 00:1b:21:4f:26:6c
          RX packets:1940342182 errors:2 dropped:0 overruns:0 frame:1
          TX packets:2090350002 errors:0 dropped:0 overruns:0 carrier:0

полоса примерно по 800-850 Мбит в обе стороны (т.е. суммарно около 1,6-1,7Гбит)
пакетрейт 150-160кпс

sc list | wc -l
9928

нарезки скоростей от 256Кбит до 10Мбит

# cat /etc/sc/sc.conf

tc = /sbin/tc
iptables = /sbin/iptables
ipset = /usr/sbin/ipset

out_if = eth0
in_if = eth1

filter_method = u32

set_type = ipmap

set_size = 65536

chain = FORWARD

quiet = 0

colored = 1

joint = 0

 

u32 используется по причине того что юзерам выдаются IP из разных подсетей (т.е. если загнать в ipmap могут быть конфликты)

Edited by shicoy

Share this post


Link to post
Share on other sites

Решил попробовать данный скрипт. Начал с проверки конфига ядра (2.6.26-1-686).

В ридми указано CONFIG_NET_CLS_GACT, по факту:

 

#
# Classification
#
CONFIG_NET_CLS=y
<...>
CONFIG_NET_CLS_U32=m
CONFIG_CLS_U32_PERF=y
CONFIG_CLS_U32_MARK=y
<...>
CONFIG_NET_CLS_FLOW=m
<...>
CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=m
CONFIG_NET_ACT_GACT=m
CONFIG_GACT_PROB=y
<...>

 

Тамже указана команда для установки перл модулей для дебиана. В текущем stable пакет libpod-parser-perl - виртуальный, входит в состав perl-modules. Поэтому просто perl-modules вполне достаточно.

Edited by Gaspar

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now