Entendendo tc qdisc e iperf


15

Estou tentando limitar a largura de banda tce verificar os resultados com iperf. Comecei assim:

# 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

As duas instâncias são conectadas diretamente através da Ethernet.

Em seguida, configurei um htb qdisccom uma classe padrão para limitar a largura de banda a 1mbit / s:

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

Mas não recebo o que espero:

# 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

Se eu dobrar a taxa, a largura de banda medida não será alterada. o que estou perdendo? Por que a largura de banda medida não corresponde ao 1mbit do rateparâmetro? Quais parâmetros eu preciso definir para limitar a largura de banda a uma taxa exata exata?

No entanto, a manpágina diz que tbfdeve ser a qdiscescolha para esta tarefa:

O Token Bucket Filter é adequado para diminuir a velocidade do tráfego para uma taxa configurada com precisão. Escala bem para grandes larguras de banda.

tbfrequer parâmetros rate, burste ( limit| latency). Então, tentei o seguinte sem entender como burste ( limit| latency) afetam a largura de banda disponível:

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

Isso me proporcionou uma largura de banda medida de 113 Kbits / s. Brincar com esses parâmetros não mudou muito até que notei que adicionar um valor para mtumudar as coisas drasticamente:

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

resultou em uma largura de banda medida de 1,00 Mbits / s.

Quais parâmetros eu precisaria definir para limitar a largura de banda a uma taxa exata exata?

Devo usar a disciplina htbou tbffila para isso?

EDIT :

Com base nesses recursos, fiz alguns testes:

Eu tentei as seguintes configurações.

Em uma máquina física

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto br0
iface br0 inet dhcp
bridge_ports eth0

Medição com 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

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  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

Em uma máquina virtual sem ligação

/etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

Medição com 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

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  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

Em uma máquina virtual com ligação (tc configurado em 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

Medição com 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

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  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

Em uma máquina virtual com ligação (tc configurado em 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

Medição com 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

Enquanto o iperfservidor calculou uma largura de banda diferente:

[  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

O resultado não muda se eu remover eth1(a interface passiva) do vínculo.

Conclusão

O controle de tráfego em uma interface de vínculo não funciona, ou pelo menos não como o esperado. Vou ter que investigar mais.

Como solução alternativa, pode-se adicionar as disciplinas de enfileiramento diretamente às interfaces pertencentes ao vínculo.


Curiosamente, isso parece ter funcionado para esse cara: blog.tinola.com/?e=22
— Matías E. Fernández

1
Eu acho que com o htb, você precisa usar tc filterpara colocar os pacotes em classes. Você também pode precisar alterar alguns dos parâmetros htb (ajuste-o exatamente como tbf). Sugiro pesquisar tcng, que é um front-end para o tc. (Estes são ponteiros rápidos ...)
— derobert

Não vi nenhum filtro na sua postagem. Quais comandos você está usando para corresponder ao tráfego para que ele possa ter uma taxa limitada?

Respostas:


2

Quando você não tem certeza de como o tc funciona, você ainda pode monitorar o tc e ver como os pacotes fluem? Você pode usar meu script para monitorar o tc e precisar executá-lo em um terminal com privilégios elevados. Você pode mudar o wlan0 para outra interface e também precisa de grep e 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

0

Tente aumentar os valores burst/ limit. Os algoritmos do bucket de tokens escalam bem, mas têm uma relação precisão / velocidade limitada.

A precisão é alcançada usando um pequeno balde, aumentando a velocidade do tamanho dos tokens. Tokens grandes significam que a taxa na qual eles são reabastecidos diminui (tokens por segundo = bytes por segundo / bytes por token).

O rateparâmetro fornece a taxa média que não deve ser excedida, os parâmetros burstou limitfornecem o tamanho da janela de média. Como o envio de um pacote na velocidade da linha excede a taxa definida para o tempo em que o pacote é transferido, a janela de média precisa ser pelo menos grande o suficiente para que o envio de um único pacote não empurre a janela inteira acima do limite; se mais pacotes caberem na janela, o algoritmo terá mais chances de atingir exatamente o alvo.


0

execute isso antes de adicionar disciplina de fila na interface de ligação (bond0 neste caso)

ipconfig bond0 txqueuelen 1000

não funciona porque o dispositivo virtual de software, como a interface de ligação, não possui fila padrão.


0

Como os bonddispositivos não têm fila definida, a definição do qdisctamanho corrige explicitamente o problema para mim.

Aqui está um exemplo para uma folha qdisca ser usada sob HTBestrutura: tc qdisc add dev $dev parent $parent handle $handle pfifo limit 1000

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.