Понимание tc qdisc и iperf

15

Я пытаюсь ограничить пропускную способность tcи проверить результаты с iperf. Я начал так:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35213 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   830 MBytes   696 Mbits/sec

Два экземпляра напрямую связаны через Ethernet.

Затем я установил htb qdiscкласс с одним классом по умолчанию, чтобы ограничить пропускную способность до 1 Мбит / с:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit

Но я не понимаю, чего ожидаю:

# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 35217 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-12.8 sec   768 KBytes   491 Kbits/sec

Если я удвою скорость, измеренная пропускная способность не изменится. Что мне не хватает? Почему измеренная пропускная способность не соответствует 1 Мбит из rateпараметра? Какие параметры мне нужно установить, чтобы ограничить полосу пропускания точной заданной скоростью?

Тем не менее, на manстранице написано, что tbfдолжен быть qdiscвыбор для этой задачи:

Token Bucket Filter подходит для замедления трафика до точно настроенной скорости. Хорошо масштабируется для большой пропускной способности.

tbfтребует параметров rate, burstи ( limit| latency). Поэтому я попробовал следующее, не понимая, как burstи ( limit| latency) влияет на доступную пропускную способность:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k

Это дало мне измеренную пропускную способность 113 кбит / с. Игра с этими параметрами не сильно изменилась, пока я не заметил, что добавление значения для mtuрадикально меняет ситуацию:

# tc qdisc add dev bond0 root tbf rate 1mbit limit 10k burst 10k mtu 5000

в результате измеренная пропускная способность составляет 1,00 Мбит / с.

Какие параметры мне нужно установить, чтобы ограничить полосу пропускания точной заданной скоростью?

Должен ли я использовать для этого дисциплину htbили tbfочередь?

РЕДАКТИРОВАТЬ :

Основываясь на этих ресурсах, я сделал несколько тестов:

Я попробовал следующие настройки.

На физической машине

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
bridge_ports eth0

Измерение с помощью iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.4 port 51804 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Тогда как iperfсервер рассчитал другую пропускную способность:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.4 port 51804
[  4]  0.0-13.7 sec  1.62 MBytes   993 Kbits/sec

На виртуальной машине без склеивания

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

Измерение с помощью iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.7 port 34347 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.3 sec  1.62 MBytes  1.21 Mbits/sec

Тогда как iperfсервер рассчитал другую пропускную способность:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.7 port 34347
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

На виртуальной машине с привязкой (tc настроен на eth0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Измерение с помощью iperf:

# tc qdisc add dev eth0 root handle 1: htb default 12
# tc class add dev eth0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49054 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-11.9 sec  1.62 MBytes  1.14 Mbits/sec

Тогда как iperfсервер рассчитал другую пропускную способность:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49054
[  4]  0.0-14.0 sec  1.62 MBytes   972 Kbits/sec

На виртуальной машине с привязкой (tc настроен на bond0)

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
allow-bond0 eth0
iface eth0 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto eth1
allow-bond0 eth1
iface eth1 inet manual
    bond-master bond0
    bond-primary eth0 eth1

auto bond0
iface bond0 inet dhcp
    bond-slaves none
    bond-mode 1
#    bond-arp-interval 250
#    bond-arp-ip-target 192.168.2.1
#    bond-arp-validate 3

Измерение с помощью iperf:

# tc qdisc add dev bond0 root handle 1: htb default 12
# tc class add dev bond0 parent 1: classid 1:12 htb rate 1mbit
# iperf -c 192.168.2.1
------------------------------------------------------------
Client connecting to 192.168.2.1, TCP port 5001
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.9 port 49055 connected with 192.168.2.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-13.3 sec   768 KBytes   475 Kbits/sec

Тогда как iperfсервер рассчитал другую пропускную способность:

[  4] local 192.168.2.1 port 5001 connected with 192.168.2.9 port 49055
[  4]  0.0-14.1 sec   768 KBytes   446 Kbits/sec

Результат не изменится, если я удалю eth1(пассивный интерфейс) из связи.

Вывод

Управление трафиком на интерфейсе связи не работает или, по крайней мере, не так, как ожидалось. Мне придется расследовать дальше.

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

Матиас Э. Фернандес
источник
Как ни странно, похоже, это сработало для этого парня: blog.tinola.com/?e=22
Матиас Э. Фернандес
1
Я думаю, что с htb, вы должны использовать, tc filterчтобы поместить пакеты в классы. Вам также может понадобиться изменить некоторые параметры htb (настроить его так же, как tbf). Я предлагаю заглянуть tcng, который является интерфейсом к tc. (Это быстрые указатели ...)
Дероберт
Я не видел никаких фильтров в вашем посте. Какие команды вы используете, чтобы соответствовать трафику, чтобы он мог быть ограничен по скорости?

Ответы:

2

Когда вы не уверены в том, как работает tc, вы все равно можете отслеживать tc и смотреть, как проходят пакеты? Вы можете использовать мой скрипт для мониторинга tc, и вам нужно запустить его в терминале с поднятыми привилегиями. Вы можете изменить wlan0 на другой интерфейс, а также вам нужны grep и awk:

      #!/bin/sh
      INTERVAL=15
      while sleep $INTERVAL
      do
             /usr/sbin/tc -s -d class show dev wlan0

             uptime
             more /proc/meminfo | grep MemFree | grep -v grep
             echo cache-name num-active-objs total-objs obj-size
             SKBUFF=`more /proc/slabinfo | grep skbuff | grep -v grep | awk 
             '{print $2} {print $3} {print $4}'`

             echo skbuff_head_cache: $SKBUFF
      done
Gigamegs
источник
0

Попробуйте увеличить burst/ limitзначения. В Token Bucket алгоритмы масштабирования хорошо, но имеют ограниченную точность соотношение / скорость.

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

rateПараметр дает среднюю скорость , которая не должна быть превышена, то burstили limitпараметры дают размер окна усреднения. Поскольку отправка пакета с линейной скоростью превышает установленную скорость для времени, когда пакет передается, окно усреднения должно быть по меньшей мере достаточно большим, чтобы при отправке одного пакета не превышалось ограничение всего окна; если в окно помещается больше пакетов, у алгоритма будет больше шансов точно попасть в цель.

Саймон Рихтер
источник
0

выполните это, прежде чем добавить дисциплину очереди в интерфейс соединения (в данном случае bond0)

ipconfig bond0 txqueuelen 1000

это не работает, потому что программное виртуальное устройство, такое как интерфейс соединения, не имеет очереди по умолчанию.

Вентилятор
источник
0

Поскольку bondустройства не имеют определенной очереди, установка qdiscразмера явно устраняет проблему для меня.

Вот пример использования листа qdiscпод HTBструктурой: tc qdisc add dev $dev parent $parent handle $handle pfifo limit 1000

SagiLow
источник