Disciplinas de Enfileiramento Classful :: Admirável Mundo Novo




Muito Bem Vindo

Prezado Leitor, a proposta desse Blog é compartilhar conhecimento com as pessoas que trabalham com Linux, Asterisk, OpenSER, e com tecnologia de voz sobre a rede IP em geral, através de tutoriais, dicas, howto, notícias entre outros assuntos.

Atente para termo de uso do conteúdo do blog no rodapé da página.

quarta-feira, 7 de janeiro de 2009

Disciplinas de Enfileiramento Classful




9.5. Disciplinas de Enfileiramento Classful

As qdiscs Classful são muito úteis se você tiver diferentes tipos de tráfego que precisam de diferentes tratamentos. Uma das qdiscs classful é chamada de ‘CBQ’, ‘Class Based Queueing’ (Enfileiramento Baseado em Classes) e ela é, portanto, mencionada amplamente por aquelas pessoas que identifica enfileiramento baseado em classe sendo só o CBQ, mas esse não é o caso.

O CBQ é certamente o tipo mais antigo no bloco e também o mais complexo. Nem sempre ele pode fazer o que você deseja. Isso pode parece algo um tanto chocante a muitas pessoas que gostou do ‘efeito sendmail’, que nos ensinou que qualquer tecnologia complexa que não vir com a documentação, ela precisa ser a melhor disponível.

A seguir mais informações a respeito do CBQ e suas alternativas de forma sucinta.


9.5.1. Fluxo nas qdiscs classful & classes

Quando o tráfego entra em uma qdisc classful, ele precisa ser enviado a qualquer das classes internas – ele precisa ser ‘classificado’. Para determinar o que fazer com um pacote, os ‘filtros’, assim chamados, são consultados. É importante entender que os filtros são chamados de dentro de uma qdisc, e não feito de outra forma!

Os filtros associados aquela qdisc então retornam uma decisão, e a qdisc usa essa decisão para enfileirar o pacote em uma das classes. Cada subclasse pode testar outros filtros para verificar se aplicam instruções adicionais. Se não existir, a classe enfileira o pacote na qdisc que ela contém.

Além de conter outras qdiscs, muitas qdiscs classful também fazem shape. Isso é útil para executar tanto o escalonamento de pacote (com o SFQ, por exemplo) quanto para controlar a taxa de transmissão. Você precisa desse recurso nos casos onde você possui uma interface de alta velocidade (por exemplo, Ethernet) voltada para uma interface mais lenta de dispositivo (por exemplo, um Cable Modem).

Se você estivesse executando o SFQ, nada aconteceria, porque pacotes entram e deixam o seu roteador sem atraso: a interface de saída é muito mais rápida que a velocidade real do seu link. Então, nesse caso não há nenhum enfileiramento a fazer.


9.5.2. A família qdisc: roots, handles, siblings e parents

Cada interface possui o ‘root qdisc’ egress. Por padrão, é a disciplina de enfileiramento pfifo_fast classless mencionada anteriormente. A cada qdisc e classe são atribuídas um handle, que pode ser usado pelas instruções de configurações posteriores para se referir a essa qdisc. Além de uma qdisc egress, uma interface pode também ter uma qdisc ingress, que executa o policiamento do tráfego entrante.

Os handles dessas qdiscs consistem de duas partes, um número major e número minor: :. É costumeiro nomear a ‘root qdisc’ como ‘1:’, porque é o mesmo que ‘1:0’. O número minor de uma qdisc é sempre 0.

Classes precisam ter os mesmos números major iguais ao dos seus pais. Esse número major precisa ser único dentro de uma instalação egress ou ingress. O número minor precisa ser único dentro de uma qdisc e de suas classes.


9.5.2.1. Como filtros são usados para classificar tráfego

Recapitulando, uma hierarquia típica pode se parecer com:


1: root qdisc
|
1:1 child class
/ | \
/ | \
/ | \
/ | \
1:10 1:11 1:12 child classes
| | |
| 11: | leaf class
| |
10: 12: qdisc
/ \ / \
10:1 10:2 12:1 12:2 leaf classes


Mas não deixe essa árvore lhe enganar! Você *não* deve imaginar o kernel estando no vértice da árvore e a rede na base, porque isso não é precisamente o caso. Pacotes são enfileirados e des-enfileirados na root qdisc, que é a única coisa que o kernel conhece.

Um pacote pode ser classificado em um encadeamento como:

1: -> 1:1 -> 1:12 -> 12: -> 12:2

O pacote agora está em uma fila numa qdisc atrelada a classe 12:2. Nesse exemplo, um filtro foi associado a cada ‘nó’ na árvore, cada um escolhendo um ramo para prosseguir seqüencialmente. Isso pode fazer sentido. No entanto, isso também é possível:

1: -> 12:2

Nesse caso, um filtro associado a ‘root qdisc’ decidiu enviar o pacote diretamente para 12:2.


9.5.2.2. Como pacotes são des-enfileirados pelo hardware

Quando o kernel decidir que ele precisa extrair pacotes para enviar a interface, a root qdisc ‘1:’ recebe um pedido para remover da fila, esse pedido então é repassado a 1:1, que na seqüência é repassado ao 10:, 11: e 12:, cada qual faz consulta a suas irmãs (siblings), e tenta remover da fila a partir delas. Nesse caso, o kernel precisa caminhar a árvore inteira, porque somente a qdisc 12:2 contém um pacote.

Em resumo, classes aninhadas SOMENTE conversam com as qdiscs pais, nunca com uma interface. O kernel pode somente remover pacotes da fila na ‘root qdisc’!

O resultado disso é que classes nunca podem ser removidas da fila mais rápidas do que seus pais permitiriam. E isso é exatamente o que queremos: dessa forma podemos ter o SFQ em uma classe interna, que não executa qualquer shape-agem, somente escalonamento, e que tenha uma qdisc externa para shape-ar, aquela que faz a shape-agem.


9.5.3. A qdisc PRIO

A qdisc PRIO realmente não executa shape-agem, ela somente subdivide o tráfego baseado em como você configurou seus filtros. Você pode considerar a qdisc PRIO como um tipo de pfifo_fast mais poderoso, através do qual cada banda é uma classe separada em vez de uma fila FIFO simples.

Quando um pacote é enfileirado na qdisc PRIO, a classe é escolhida baseada nos comandos do filtro que você forneceu. Por padrão, três classes são criadas. Essas classes por padrão contêm qdiscs FIFO puramente sem nenhuma estrutura, mas você pode substituí-las por qualquer qdisc que você tenha disponível.

Sempre que um pacote precisar ser removido da fila, a classe ‘:1’ é testada primeiro. Classes mais altas somente são usadas se todas as bandas inferiores não fornecerem um pacote.

Essa qdisc é muito útil no caso de você desejar priorizar certos tipos de tráfego sem fazer uso tão somente dos flags TOS, mas usando toda a potência dos filtros tc. Você também pode adicionar uma outra qdisc as 3 classes predefinidas, já que a pfifo_fast é limitada a qdiscs FIFO simples.

Como ela realmente não atrasa e nem descarta, igual aviso serve também para filas SQF: use-a somente se o seu link físico estiver realmente cheio ou se for empacotá-lo dentro de uma outra qdisc classful que não faz shape. As últimas alimentam quase todos os dispositivos Cable Modem e ADSL.

Formalmente, a qdisc PRIO é um escalonador Work-Conserving.


9.5.3.1. Parâmetros PRIO & Uso

Os parâmetros seguintes são reconhecidos pelo comando tc:

bands

Número de bandas a criar. Cada banda é de fato uma classe. Se você alterar esse número, você precisa alterar também:



priomap

Se você não fornecer filtros tc para classificar tráfego, a qdisc PRIO examina a prioridade TC_PRIO para decidir como enfileirar o tráfego. Isso funciona exatamente igual a qdisc pfifo_fast mencionada antes, veja lá para um monte de detalhes.



As bandas são classes, e são chamadas de major:1 a major:3 por padrão, assim se sua qdisc PRIO for chamado na qdisc '12:', o comando tc filtra o tráfego na classe '12:1' para lhe dar maior prioridade.

Reiterando, a banda 0 segue com o número minor 1! A banda 1 com o número minor 2, etc.


9.5.3.2. Configuração Exemplo

Nós iremos criar essa árvore:


1: root qdisc
/ | \
/ | \
/ | \
1:1 1:2 1:3 classes
| | |
10: 20: 30: qdiscs qdiscs
sfq tbf sfq
band 0 1 2


O tráfego pesado seguirá pela qdisc ‘30:’, o tráfego interativo pela qdisc ‘20:’ ou pela qdisc ‘10:’.
Linhas de Comando:

# tc qdisc add dev eth0 root handle 1: prio
## Isso *instantaneamente* criar as classes 1:1, 1:2, 1:3

# tc qdisc add dev eth0 parent 1:1 handle 10: sfq
# tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000
# tc qdisc add dev eth0 parent 1:3 handle 30: sfq


Agora vejamos o que criamos:

# tc -s qdisc ls dev eth0
qdisc sfq 30: quantum 1514b
Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms
Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

qdisc sfq 10: quantum 1514b
Sent 132 bytes 2 pkts (dropped 0, overlimits 0)

qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 174 bytes 3 pkts (dropped 0, overlimits 0)

Como você pode ver, a banda 0 já teve algum tráfego, e um pacote foi enviado enquanto executávamos esse comando!

Agora faremos alguma transferência pesada de dados com uma ferramenta que define o flag TOS apropriadamente, dê outra olhada:

# scp tc ahu@10.0.0.11:./
ahu@10.0.0.11's password:
tc 100% |*****************************| 353 KB 00:00
# tc -s qdisc ls dev eth0
qdisc sfq 30: quantum 1514b
Sent 384228 bytes 274 pkts (dropped 0, overlimits 0)

qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms
Sent 2640 bytes 20 pkts (dropped 0, overlimits 0)

qdisc sfq 10: quantum 1514b
Sent 2230 bytes 31 pkts (dropped 0, overlimits 0)

qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 389140 bytes 326 pkts (dropped 0, overlimits 0)


Como você pode ver, todo tráfego foi para handle ‘30:’, que é a banda de mais baixa prioridade, exatamente como tencionado. Agora para verificar que o tráfego interativo vai para as bandas de alta prioridade, nós geraremos algum tráfego interativo:

# tc -s qdisc ls dev eth0
qdisc sfq 30: quantum 1514b
Sent 384228 bytes 274 pkts (dropped 0, overlimits 0)

qdisc tbf 20: rate 20Kbit burst 1599b lat 667.6ms
Sent 2640 bytes 20 pkts (dropped 0, overlimits 0)

qdisc sfq 10: quantum 1514b
Sent 14926 bytes 193 pkts (dropped 0, overlimits 0)

qdisc prio 1: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 401836 bytes 488 pkts (dropped 0, overlimits 0)


Tudo funcionou – todo tráfego adicional seguiu pela qdisc ‘10:’, que é a nossa qdisc de alta prioridade. Nenhum tráfego foi enviado com prioridade mais baixa, aquela qdisc que anteriormente recebeu todo o nosso tráfego scp.











Autores Originais dos textos:

Bert Hubert (Netherlabs BV)
bert.hubert@netherlabs.nl

Thomas Graf (Autor de Seção)
tgraf@suug.ch

Gregory Maxwell (Autor de Seção)
greg@linuxpower.cx

Remco van Mook (Autor de Seção)
remco@virtu.nl

Martijn van Oosterhout (Autor de Seção)
kleptog@cupid.suninternet.com

Paul B Schroeder (Autor de Seção)
paulsch@us.ibm.com

Jasper Spaans (Autor de Seção)
jasper@spaans.ds9a.nl

Pedro Larroy (Autor de Seção)
piotr@member.fsf.org







Nenhum comentário:




Creative Commons License
Admirável Mundo Novo: Tudo Sobre Asterisk, OpenSER, Linux e Tecnologias de Voz sobre IP
by Cléviton Mendes de Araújo is licensed under a Creative Commons Atribuição 2.5 Brasil License.