A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Linux

Administração de Largura de Banda no Linux

Sex

20

Abr

2007


19:22

(5 votos, média 4.80 de 5) 


Nível avançado O Linux 2.2/2.4 tem um sistema parrudo de administração de largura de banda, comparável a sistemas dedicados topo de linha. Aliás, oferece muito mais recursos do que o Frame e o ATM.

Glossário

Quando comecei a ler textos sobre este tema, me embananei todinha com os termos que fui encontrando pelo caminho. Para tentar evitar que isto aconteça com você, começo este artigo com um pequeno glossário.

  • Queueing Discipline (qdisc) - Fila de Disciplina: Um algoritmo que manipula a fila de um dispositivo, seja a entrada (ingresso) ou a saída (egressão).
  • root qdisc - qdisc raiz: A qdisc raiz é a qdisc associada ao dispositivo.
  • Classless qdisc - qdisc sem classe: Uma qdisc sem subdivisões internas configuráveis.
  • Classful qdisc - qdisc com classe: Uma qdisc com classe contém várias classes. Algumas delas contém outras qdiscs, que podem ser com ou sem classe. De acordo com a definição estrita, pfifo_fast é uma qdisc com classe porque contém três bandas, estas sem classe. No entanto, do ponto de vista do usuário, ela é sem classe porque suas classes não podem ser tocadas com a ferramenta tc.
  • Classes: Uma qdisc com classe pode ter muitas classes, cada uma delas no interior da qdisc. Por outro lado, uma classe pode ter várias classes associadas. Desta forma, uma classe pode ter como pais uma qdisc ou outra classe. Uma classe folha é uma classe sem classes filhas - esta classe possui uma classe qdisc associada a ela. Esta qdisc é responsável pelo envio de dados desta classe. Quando você cria uma classe, uma qdisc fifo é anexada a ela. Quando você cria uma classe filha, esta qdisc é removida. Para uma classe folha, esta qdisc fifo pode ser substituída por outra qdisc mais apropriada. Você pode até substituir esta qdisc fifo por uma qdisc com classe para adicionar classes extras.
  • Classifier - Classificador: Toda qdisc com classe precisa determinar para qual classe ela deve enviar um pacote. Isto é feito através do classificador.
  • Filter - Filtro: A classificação pode ser feita através de filtros. Um filtro contém as condições que, se forem preenchidas, fazem o filtro funcionar.
  • Scheduling - Precedência: Uma qdisc pode, com a ajuda de um classificador, decidir que determinados pacotes precisam sair antes que outros. Este processo é chamado de Scheduling ou Precedência. A Precedência também é chamada de reordenamento, mas isto é um pouco confuso.
  • Shaping - Modelagem: O processo de retardar pacotes antes que eles saiam para confirmar o tráfego numa taxa máxima configurada. A modelagem é aplicada na saída (egresso). Coloquialmente, descartar pacotes para diminuir a velocidade do tráfego também é chamado de Modelagem.
  • Policing - Policiamento: Retardar ou descartar pacotes para manter o tráfego abaixo de uma determinada largura de banda. No Linux, o policiamento pode apenas descartar um pacote - não pode retardá-lo - porque não existe uma 'fila de ingresso'.
  • Work-Conserving - Conservação de Trabalho: Uma qdisc que conserva trabalho sempre entrega um pacote quando houver um disponível. Em outras palavras, nunca retarda um pacote se o adaptador de rede estiver pronto para enviar um (nos casos de qdisc de egresso).
  • non-Work-Conserving - Sem Conservação de Trabalho: Algumas filas, como por exemplo o Filtro Balde de Token (Token Bucket Filter), podem precisar reter um pacote por um certo período de tempo para limitar a largura de banda. Isto significa que algumas vezes estas filas se recusam a passar um pacote, mesmo que tenham um disponível.

Com a terminologia definida, vamos ver onde ficam todas estas coisas.


                Programas no espaço do usuário
                     ^
                     |
     +---------------+-----------------------------------------+
     |               Y                                         |
     |    -------> Pilha IP                                    |
     |   |              |                                      |
     |   |              Y                                      |
     |   |              Y                                      |
     |   ^              |                                      |
     |   |  / ----------> Redespacho ->                        |
     |   ^ /                           |                       |
     |   |/                            Y                       |
     |   |                             |                       |
     |   ^                             Y          /-qdisc1-\   |
     |   |                        Classificador  /--qdisc2--\  |
  --->->Qdisc de                  de Egressão    ---qdisc3---- | ->
     |  Ingresso                                 \__qdisc4__/  |
     |                                            \-qdiscN_/   |
     |                                                         |
     +---------------------------------------------------------+

Representação ASCII de Jamal Hadi Salim.

O bloco grande representa o kernel. A seta mais à esquerda representa o tráfego que entra na máquina vindo da rede. Ele alimenta a Qdisc de Ingresso que pode aplicar Filtros a um pacote e decidir descartá-lo. Isto é chamado de 'Policiamento'.

Isto acontece num estágio muito precoce, antes que o pacote tenha contato com a maior parte do kernel. É, portanto, um ponto muito bom para descartar tráfego precocemente sem consumir muito processamento da CPU.

Se o pacote tiver permissão para continuar, ele pode ser destinado para um aplicativo local. Neste caso, ele entra na Pilha IP para ser processado e entregue a um programa no espaço do usuário. O pacote também pode ser despachado sem entrar num aplicativo. Neste caso ele é destinado para egressão (saída). Programas no espaço do usuário também podem entregar dados que são examinados e redespachados para o Classificador de Egressão.

O Classificador de Egressão investiga o pacote e o coloca na fila de uma das várias qdiscs. No caso default (não configurado) há apenas uma qdisc de egressão instalada, a pfifo_fast, que sempre recebe o pacote. Isto é chamado de 'enfileirar' (enqueueing).

O pacote agora está na qdisc, esperando que o kernel o chame para transmiti-lo através da interface de rede. Isto é chamado de 'desenfileirar' (dequeueing).

Esta figura também é válida quando existir apenas um adaptador de rede - as setas que entram e saem do kernel não devem ser consideradas muito literalmente. Cada adaptador de rede possui ganchos de ingresso e de egressão.


Filas e Disciplinas

Com as filas pode-se determinar o modo como os dados são ENVIADOS e é importante ressaltar que não podemos modelar todos os dados, só os que enviamos. Do modo como a Internet funciona, não é possível controlar o que as pessoas nos enviam. A situação se parece um pouco com uma caixa de correio (a que fica no portão de casa): não tem como influenciar o que é jogado dentro dela.

Acontece que a Internet se baseia principalmente em TCP/IP, o que pode nos ajudar um pouco. O TCP/IP não tem como determinar a capacidade de uma rede entre dois hosts, por isto começa a enviar dados cada vez mais depressa ("slow start" - largada lenta) e, quando os pacotes começam a ser perdidos por falta de espaço para enviá-los, diminui a velocidade da transmissão. Na verdade a coisa é um pouco mais elaborada, mas falaremos disto mais tarde.

Se você possui um roteador e quiser prevenir que certos hosts da sua rede façam downloads muito rápidos, então será preciso mexer na interface *interna* do seu roteador, na que envia dados para os seus computadores.

Você também precisa se certificar de que está controlando os gargalos do link. Se você tiver uma NIC de 100 Mbits e um roteador pendurado num link de 256 Kbits, então você precisa garantir que o roteador não receba mais dados do que pode aguentar. Se você bobear, o roteador acaba controlando o link e será ele que mandará na largura de banda disponível. O jeito é "tomar posse da fila" e obrigá-lo a ser o link mais lento - por sorte, isto não só é possível como também fácil.

Filas de Disciplina simples sem classe

Com disciplinas de fila podemos mudar o modo como os dados são enviados. Disciplinas de fila sem classe são as que aceitam dados sem restrições e apenas os descartam, atrasam ou refazem seu planejamento.

As disciplinas podem ser usadas para modelar o tráfego para uma interface sem quaisquer subdivisões. É extremamente importante que você entenda as características destas filas antes de encarar as filas com classe de qdisc-contendo-qdiscs.

A disciplina mais utilizada é a pfifo_fast qdisc - aliás, é a default. Cada uma das disciplinas possui suas virtudes e suas fraquezas, mas explicam porque estas características avançadas são tão robustas - elas nada mais são do que "apenas outra fila".

pfifo_fast

Esta fila é o que o seu nome diz: First In, First Out (o primeiro a entrar é o primeiro a sair). Isto significa que nenhum pacote recebe um tratamento especial. Esta fila possui 3 "bandas" e a regra FIFO é aplicada a cada uma delas. No entanto, enquanto houver pacotes esperando na banda 0, a banda 1 não será processada. O mesmo vale para a banda 1 e para a banda 2.

O kernel respeita a chamada flag Type of Service (Tipo de Serviço) dos pacotes e se empenha em colocar os pacotes com "minimum dalay" (retardo mínimo) na banda 0.

Não confunda esta qdisc simples sem classe com a PRIO com classe! Apesar de serem parecidas, a pfifo_fast não tem classe e você não pode adicionar outra qdiscs a ela com o comando tc.

Não é possível configurar a qdiscs pfifo_fast porque ela é a default. Sua configuração é a seguinte:

priomap: determina como as prioridades do pacote, determinados pelo kernel, são mapeados
para as bandas. O mapeamento se baseia no octeto TOS do pacote que tem o seguinte aspecto:

       0     1     2     3     4     5     6     7
    +-----+-----+-----+-----+-----+-----+-----+-----+
    |                 |                       |     |
    |   PRECEDENCE    |          TOS          | MBZ |
    |                 |                       |     |
    +-----+-----+-----+-----+-----+-----+-----+-----+


Os quatro bits do TOS (o 'campo TOS') são definidos como:

    Binário Decimal  Significado
    ---------------------------------------------------------------------------
    1000      8      Minimizar o retardo (minimize dalay - md)
    0100      4      Maximizar a passagem (maximize throughput - mt)
    0010      2      Maximizar a confiabilidade (maximize reliability - mr)
    0001      1      Minimizar o custo monetário (minimize monetary cost - mmc)
    0000      0      Serviço Normal

Como existe 1 bit à direita destes 4 bits, o valor do campo TOS é o dobro do valor dos bits TOS. Um tcpdump -v -v mostra o valor do campo TOS completo e não apenas dos 4 bits. É o valor da primeira coluna da tabela a seguir:

    TOS     Bits  Significa                Prioridade Linux    Banda
    ----------------------------------------------------------------
    0x0     0     Normal Service           0 Best Effort       1
    0x2     1     Minimize Monetary Cost   1 Filler            2
    0x4     2     Maximize Reliability     0 Best Effort       1
    0x6     3     mmc+mr                   0 Best Effort       1
    0x8     4     Maximize Throughput      2 Bulk              2
    0xa     5     mmc+mt                   2 Bulk              2
    0xc     6     mr+mt                    2 Bulk              2
    0xe     7     mmc+mr+mt                2 Bulk              2
    0x10    8     Minimize Delay           6 Interactive       0
    0x12    9     mmc+md                   6 Interactive       0
    0x14    10    mr+md                    6 Interactive       0
    0x16    11    mmc+mr+md                6 Interactive       0
    0x18    12    mt+md                    4 Int. Bulk         1
    0x1a    13    mmc+mt+md                4 Int. Bulk         1
    0x1c    14    mr+mt+md                 4 Int. Bulk         1
    0x1e    15    mmc+mr+mt+md             4 Int. Bulk         1

Viiixi... um monte de números! A segunda coluna mostra o valor do quatro bits TOS e, a seguinte, o significado dos valores. Por exemplo, 15 significa um pacote com Custo Monetário Mínimo, Máximo de Confiabilidade, Máximo de Passagem e Retardo Mínimo. Este pacote deve ser do "irlandês pão-duro" smile

A quarta coluna lista o modo como o kernel do Linux interpreta os bits TOS e lhes atribui a prioridade.

A última coluna mostra o resultado do priomap (mapa de prioridades). Na linha de comando, o priomap default se mostra como:

1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1

Isto significa que a prioridade 4, por exemplo, é mapeada para a banda 1. O priomap também permite listar prioridades maiores (> 7) que não correspondem a mapeamentos TOS mas são determinadas através de outros meios.

A tabela a seguir, copiada da RFC 1349, nos mostra como aplicativos podem determinar seus bits TOS:

TELNET                   1000           (minimizar retardo)

FTP
        Controle         1000           (minimizar retardo)
        Dados            0100           (maximizar passagem)

TFTP                     1000           (minimizar retardo)

SMTP
        Fase de Comando  1000           (minimizar retardo)
        Fase de DADOS    0100           (maximizar passagem)

Domain Name Service (DNS)
    	UDP Query        1000           (minimizar retardo)
    	TCP Query        0000
    	Zone Transfer    0100           (maximizar passagem)

NNTP                     0001           (minimizar custo monetário)

ICMP
    	Erros            0000
    	Solicitações     0000 (a maioria)
    	Respostas         (a maioria)

txqueuelen: o comprimento desta fila é obtido através da configuração da interface, a qual pode ser vista e determinada com o ifconfig e o ip. Para determinar o comprimento da fila em 10, execute ifconfig eth0 txqueuelen 10. Não é possível determinar o valor deste parâmetro com tc!


Filtro Balde de Token

O Token Bucket Filter (TBF) - Filtro Balde de Token - é uma qdisc simples que só passa pacotes que chegam numa taxa que não ultrapassa uma taxa determinada administrativamente, mas com a possibilidade de permitir rompimentos curtos quando houver excessos.

O TBF é muito preciso e não sobrecarrega nem a rede e nem o processador. Deveria ser a sua primeira escolha se você quiser tornar uma interface mais lenta!

A implementação do TBF consiste num buffer (o balde - bucket) que é constantemente preenchido com alguns pedaços de informação virtual chamados de tokens, numa taxa específica (a token rate). O parâmetro mais importante do balde é o seu tamanho, que é o número de tokens que ele pode armazenar.

Cada um dos tokens que chega pega um pacote de dados entrante na fila de dados e depois é deletado do balde. A associação deste algoritmo com os dois fluxos (o de tokens e o de dados) pode resultar em três cenários diferentes:

  • Os dados chegam no TBF numa taxa igual à taxa de tokens entrantes. Neste caso, cada pacote entrante possui seu token correspondente e passa pela fila sem qualquer retardo (delay).
  • Os dados chegam no TBF numa taxa que é menor que a taxa dos tokens. Apenas uma parte dos tokens são deletados quando cada um dos pacotes de dados sair da fila de modo que os tokens se acumulam e acabam lotando o balde. Os tokens que não foram usados podem ser usados para enviar dados numa velocidade que ultrapassa a taxa de token padrão, ou seja, ocorre uma rápida explosão de dados.
  • Os dados chegam no TBF numa taxa maior do que a taxa de tokens. Isto significa que o balde se esvazia rapidamente, o que faz com que o TBF fique estrangulado por um tempo. Esta é a chamada "situação acima do limite" (overlimit situation). Se os pacotes continuam entrando, eles começam a ser descartados.

O último cenário é muito importante porque permite modelar administrativamente a largura de banda disponível para atender os dados que passam pelo filtro.

O acúmulo de tokens permite que uma explosão rápida de dados acima do limite faça com que passem sem perdas, mas um excesso de carga prolongado causa atrasos persistentes nos pacotes e estes acabam sendo descartados.

É importante saber que na implementação atual do TBF, os tokens correspondem a bytes e não a pacotes.

Normalmente a configuração do TBF não precisa ser alterada, mas, mesmo assim, esta possibilidade é oferecida através dos seus parâmetros:

  • limit ou latency: Limit (limite) é o número de bytes que podem entrar na fila para esperar até que haja tokens disponíveis. Pode-se especificar isto "ao contrário" alterando o parâmetro latency (latência), o qual especifica o tempo máximo que um pacote pode ficar no TBF. Este cálculo leva em consideração o tamanho do balde, a taxa e, se estiver especificada, a taxa de pico (peakrate).
  • burst/buffer/maxburst: Tamanho do balde em bytes. Esta é a quantidade máxima de bytes para os quais deve haver tokens disponíveis instantaneamente. Em geral, taxas mais altas requerem um buffer maior. Para 10mbit/s em processadores Intel será preciso um buffer de, no mínimo, 10kbyte para suportar a taxa configurada!
    Se o buffer for muito pequeno, os pacotes podem ser descartados porque chegam mais tokens do que cabem no buffer por ciclo de timer.
  • mpu: Um pacote de tamanho zero também usa largura de banda. Para uma Ethernet, nenhum pacote usa menos do que 64 bytes. A Minimum Packet Unit - Unidade de Pacote Mínima determina a utilização de token mínima para um pacote.
  • rate: O acelerador. Veja os comentários acima sobre limites!

Se o balde contiver tokens e tiver permissão para ser esvaziado, ele faz isto numa velocidade infinita por default. Se isto não for aceitável, use os seguintes parâmetros:

  • peakrate (taxa de pico): Se chegarem pacotes e houver tokens disponíveis, por default os pacotes são despachados instantaneamente - por assim dizer, na "velocidade da luz". Isto pode não ser o que você deseja, especialmente se o balde for grande.
    A taxa de pico pode ser usada para especificar a velocidade permitida de esvaziamento do balde. Se fizermos tudo de acordo com o manual, isto pode ser obtido liberando um pacote e depois esperar um certo tempo para liberar o seguinte. Se calculamos as esperas, então é só enviar na taxa de pico.
    Entretanto, devido à resolução default de 10ms do timer no Unix, com pacotes de 10.000 bits em média estaremos limitados a uma taxa de pico de 1mbit/s!
  • mtu/minburst: A taxa de pico de 1mbit/s não serve para muita coisa se a taxa normal for mais alta. Uma taxa de pico mais alta torna possível despachar mais pacotes por ciclo do timer (timertick), o que, na realidade, significa a criação de um segundo balde!
    O segundo balde serve para apenas um pacote, o que não chega a ser um balde.
    Para calcular a taxa de pico mais alta possível, multiplique a mtu configurada por 100 (ou, mais corretamente, HZ, que é 100 no Intel e 1024 no Alpha).

Exemplo de configuração

Uma configuração *muito* simples mas muito útil é:

# tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540

Muito bem, porque isto é útil? Se você tiver um dispositivo de rede com uma fila grande (por exemplo um modem DSL ou modem a cabo) e quiser "falar" com ele através de um dispositivo rápido (uma interface Ethernet, por exemplo), vai descobrir que o upload destrói toda a interatividade.

Isto acontece porque o upload vai entupir a fila do modem. Esta fila provavelmente é gigantesca para permitir um bom fluxo de dados para o upload. Mas não é isto o que queremos, o que desejamos é uma fila menor para preservar a interatividade e poder realizar outras tarefas enquanto enviamos dados.

A linha acima diminui a velocidade de envio para uma taxa que não aciona a fila no modem - a fila estará no Linux, onde podemos controlá-la limitando seu tamanho.

Altere a velocidade efetiva do seu uplink para 220kbit menos uma pequena porcentagem. Se você tiver um modem realmente rápido, aumente um pouco o 'burst'.


Fila Stochastic Fairness

Stochastic Fairness Queueing (SFQ) é uma implementação simples da família de algoritmos de fila solidários. É menos preciso que outros, mas precisa de menos cálculos e continua bastante solidário.

A palavra chave na SFQ é conversação (ou fluxo), que, na maior parte das vezes, corresponde a uma sessão TCP ou a um fluxo UDP. O tráfego é dividido num número relativamente grande de filas FIFO, uma para cada conversação. O tráfego é então enviado para uma ciranda (round robin), onde a cada volta todas as sessões têm a chance de enviar dados.

Isto faz com que o comportamento seja solidário e impede que uma conversação afogue as outras. SFQ é chamada de 'Estocástica' porque ela, na verdade, não aloca uma fila para cada sessão - ela possui um algoritmo que divide o tráfego num número limitado de filas usando um algoritmo de hash.

Devido a este hash, várias sessões podem acabar no mesmo balde, o que dá chance a cada uma delas de enviar pacotes, mas acaba dividindo a velocidade efetiva disponível. Para prevenir que esta situação se torne perceptível, a SFQ muda seu algoritmo de hash com alguma frequência, de modo que quaisquer colisões entre duas sessões durem só por alguns poucos segundos.

É importante notar que a SFQ só é útil quando a interface de saída estiver realmente lotada! Se não estiver, também não existirá uma fila na máquina Linux e a SFQ não terá efeito. Mais adiante será descrito como combinar a SFQ com outras qdiscs para obter o melhor resultado. Mais especificamente, configurar uma SFQ na interface Ethernet ligada ao modem a cabo ou ao roteador DSL não faz sentido se esta configuração não for acompanhada por configurações adicionais!

A configuração da SFQ é praticamente automática:

  • perturb: Reconfigura o hash uma vez a cada tantos segundos. Se não estiver configurado, o hash nunca será reconfigurado, o que não é recomendado. 10 segundos é provavelmente um bom valor.
  • quantum: A quantidade de bytes que um fluxo pode tirar da fila antes que chegue a vez da próxima fila. O default é um pacote de tamanho máximo (do tamanho da MTU). Não configure com valor menor que a MTU!
  • limit: O número total de pacotes que entrarão na fila por esta SFQ (depois disto, os pacotes começam a ser descartados).

Se você tem um dispositivo que tenha uma velocidade de link e taxa de disponibilidade idênticas, como um modem de linha discada, esta configuração vai ajudar a promover a solidariedade:

# tc qdisc add dev ppp0 root sfq perturb 10
# tc -s -d qdisc ls
qdisc sfq 800c: dev ppp0 quantum 1514b limit 128p flows 128/1024 perturb 10sec 
 Sent 4812 bytes 62 pkts (dropped 0, overlimits 0) 

O número 800c: é o número de manipulação designado automaticamente, limit significa que 128 pacotes podem esperar nesta fila. Há 1024 baldes de hash (hashbuckets) disponíveis, dos quais 128 podem estar ativos simultaneamente (mais nenhum pacote cabe na fila!). A cada 10 segundos os hashes são reconfigurados.


Escolhendo filas: quais e quando

Resumindo, estas são as filas simples que atualmente coordenam o tráfego reordenando, tornando mais lentos ou descartando pacotes:

  • Para apenas tornar mais lento o tráfego de saída, use o Filtro Balde de Token (Token Bucket Filter). Ele funciona com larguras de banda muito grandes se o balde tiver o tamanho apropriado.
  • Se o link for realmente full e você quiser garantir que nenhuma sessão domine a largura de banda de saída, use a Fila Stochastical Fairness (SFQ).
  • Se o backbone for grande se você souber o que está fazendo, considere usar o Random Early Drop.
  • Para 'modelar' o tráfego de entrada que você não estiver redespachando, use o Ingress Policer. Modelar a entrada é chamado de 'policiamento' e não de 'modelagem'.
  • Se você estiver redespachando, use TBF na interface que recebe os dados que devem ser redespachados, a não ser que você queira modelar o tráfego para sair através de várias interfaces. Neste caso, o único fator comum é a interface de entrada e você deve usar o Ingress Policer.
  • Se você não quiser modelar, apenas ver se a sua interface está tão carregada que precisa de uma fila, use a fila pfifo (não a pfifo_fast).
  • Finalmente, você também pode fazer uma "modelagem social". Nem sempre é possível usar a tecnologia para alcançar o que deseja. Os usuários costumam encarar limitações técnicas como algo hostil. Uma palavra gentil também pode ajudar na divisão correta da largura de banda (coisa do tipo, "Que tal fazer seus downloads de mp3 de madrugada? Os outros usuários do prédio ficariam muito gratos smile )

Fonte de Referência

отзывы казино онлайнкупить сотейник качественныйооо полигон украинавнедрение сэдбюджетный игровойwobs.ua оставить отзыв

Informações adicionais