Este é mais um artigo da série sobre o OpenWRT.
O problema de QoS foi tratado em dois posts anteriores. No primeiro, mostrando o problema e no segundo configurando uma solução com o qos-scripts. Este artigo é uma alternativa ao uso do qos-scripts, utilizando o sqm-scripts.
O SQM surgiu do projeto CeroWRT (fork do OpenWRT), que tem como principal objetivo atacar o excesso de buffer nos equipamentos de rede (o bufferbloat), que geram grandes latências quando o enlace está sobre carga. As melhorias deste projeto retornaram para o OpenWRT (versão BB ou posterior) e para o Linux em geral.
Vamos rever alguns conceitos: podemos avaliar um enlace por três parâmetros:
O SQM surgiu do projeto CeroWRT (fork do OpenWRT), que tem como principal objetivo atacar o excesso de buffer nos equipamentos de rede (o bufferbloat), que geram grandes latências quando o enlace está sobre carga. As melhorias deste projeto retornaram para o OpenWRT (versão BB ou posterior) e para o Linux em geral.
Vamos rever alguns conceitos: podemos avaliar um enlace por três parâmetros:
- A taxa de transmissão (vulgarmente conhecido como "velocidade");
- A latência (duração da viagem de um pacote até seu destino);
- E o jitter (variação na latência).
Contratamos internet sempre pelo primeiro parâmetro (taxa de transmissão) mas dificilmente olhamos os demais. Os "speedtests" focam no primeiro, que é quantos dados você pode receber/enviar em um determinado tempo. Este é o fator determinante de quanto tempo o download de um arquivo vai levar ou se sua conexão vai aguentar assistir aquele filme do Netflix sem engasgar.
Os outros dois parâmetros (latência e jitter) são mais importantes para aplicações "em tempo real", como videoconferência, voz (VoIP), sessão remota (VNC, RDP, etc) e jogos online com interação imediata (FPS, MMORPG, RTS, etc, mas não o poker). A latência determina em quanto tempo o inimigo do Battefield que entrou na sua frente vai aparecer no seu computador e também quanto tempo o seu tiro vai levar para chegar ao servidor. Se a latência for muito grande, até seu tiro chegar ao servidor, seu inimigo mirou na sua cabeça, pensou duas vezes e atirou umas três vez. No "mundo virtual", você estava morto antes de tê-lo visto. Mesmo na navegação Web, a latência importa pois se ela estiver em algo como 1s, um clique em uma página vai levar uns 6 segundos para começar a carregar. É o clássico "a internet está lenta hoje", mas ao baixar um arquivo, a taxa de transmissão não está tão ruim. Já o jitter é a variação deste atraso. Se for significativo, os pacotes começarão a chegar fora de ordem e não serão úteis para aplicações em tempo real. Para minimizar isto, foram criadas filas (buffers) que reorderam os pacotes enquanto aguardam serem enviados. O problema é que atualmente se exagera no tamanho nesta fila, gerando o problema do bufferbloat.
Quando o enlace estiver sobrando, não existem filas e não existe problema. Agora, quando você tem alguém enchendo a fila dos roteadores no seu caminho (que ocorre quando você baixa ou sobe qualquer coisa na velocidade do seu enlace), o excesso de buffer gera uma fila longa e aumenta da latência). Para testar isto, faça um ping a um equipamento fora da sua rede (ex: 8.8.8.8 do google) e inicie um download ou upload (ou ambos) grande para um local que consiga usar toda a sua conexão. A latência do ping irá fatalmente aumentar. Esta diferença no tempo antes e depois do download/upload é um indicativo do tempo que um pacote leva para passar na fila dos seus roteadores. Você também pode fazer isto por alguns provedores de "testes de velocidade", como o http://www.dslreports.com/speedtest (não foque na velocidade ou na latência, que pode ser pequena/grande pela distância, mas no bufferbloat). O ideal seria que a latência mesmo quando o enlace estiver com carga (download ou upload) deveria ser apenas um pouco maior do que a situação quando o enlace está ocioso. Outra forma de testar é pelo script betterspeedtest do projeto CeroWrt. Funciona em qualquer Linux ou de dentro do OpenWRT (basta instalar o netperf).
E como resolver o bufferbloat? Deixe as filas menores para que, quando cheias, novos pacotes sejam descartados, informando ao emissor que ele precisa "pegar leve". Em conjunto, você pode dividir seu tráfego em filas para casos distintos (similar aos caixas-rápidos do supermercado que limitam o atendimento a clientes com até 20 produtos).
No OpenWRT, existem duas propostas para solucionar este problema: o qos-scripts (mais antigo) e o sqm-scripts (mais novo), que trabalham em conjunto com o escalonador de pacotes padrão fq_codel (também focado no problema do bufferbloat). O primeiro faz algumas classificações automáticas (pelo volume de tráfego e alguns sabidamente urgentes) mas deixa a parte pesada da classificação na mão do operador. Já o segundo utiliza inteligência para classificar o tráfego automaticamente, sem parametrização (SQM significa "Smart Queue Management". A inteligência está parte "Smart"). Neste artigo vou tratar de como configurar a segunda proposta.
Tanto para o qos-scripts como para o sqm-scripts, o parâmetro determinante para o seu funcionamento é a taxa de transmissão do enlace. Para controlar a fila, o roteador tem que fazer a fila da conexão fica nele, seja para subir ou descer pacotes. E para a fila ocorrer no roteador, este tem que limitar o tráfego a um valor menor do que a sua conexão com a internet pode aguentar. Assim, não serão feitas filas significativas nos equipamentos da sua provedora de internet, apenas no seu roteador. Por isto, o valor de download/upload configurado deve ser menor do que o contratado. Falam de algo entre 85% a 95% da taxa de transmissão real. Se este parâmetro for maior do que a taxa de transmissão real (real, não a contratada), os controles não atuarão e o QoS não será efetivo.
O sqm-scripts e o qos-scripts são mutualmente exclusivos. Se estava usando o qos-scripts e quer usar o sqm-scripts, remova-o antes de iniciar o processo.
A instalação do sqm-scripts é bem simples e parecida com o qos-scripts:
# opkg update
# opkg install sqm-scripts
Se quiser a interface Luci (web):
# opkg install luci-app-sqm
O arquivo de configuração fica em /etc/config/sqm, que pode ser alterado sem problemas pelo Luci em "Rede/SQM Qos". A configuração mínima se limita a:
- Habilitar a configuração;
- Definir a interface WAN, normalmente eth1 ou eth0.2. Esta pode ser identificada na página de interfaces ou mesmo em "Estado/Visão Geral";
- Configurar os valores de download e upload para algo entre 85% a 95% da taxa de transmissão real.
Depois é só habilitar e disparar o serviço sqm pela interface Luci ou pelo SSH:
/etc/init.d/sqm enable
/etc/init.d/sqm start
Feito! Só testar a sua conexão. Para efeitos de testes, eu usei o script betterspeedtest que mencionei acima diretamente no roteador.
Inicialmente, sem o SQM:
root@router.lan3:~# sh betterspeedtest.sh
2015-09-30 01:27:05 Testing against netperf.bufferbloat.net (ipv4) with 5 simultaneous sessions while pinging gstatic.com (60 seconds in each direction)
..............................................................
Download: 5.14 Mbps
Latency: (in msec, 62 pings, 0.00% packet loss)
Min: 16.616
10pct: 485.537
Median: 762.117
Avg: 751.026
90pct: 963.462
Max: 970.820
.................................................................
Upload: 0.63 Mbps
Latency: (in msec, 62 pings, 0.00% packet loss)
Min: 10.778
10pct: 840.844
Median: 1006.490
Avg: 971.260
90pct: 1115.123
Max: 1151.302
A taxa de transmissão corresponde a contratada (até mais) mas a latência do download/upload, respectivamente, sobe de 16/10 milissegundos em "repouso" para, em média, 762/1006 milissegundos quando em carga. Isto significa que, sobre carga, tudo que dependa de resposta rápida vai "engasgar" em torno de um segundo antes de chegar ao seu destino. E isto é multiplicado para protocolos que exigem negociação/confirmação, como o TCP. Se você já sentiu sua internet lenta quando está anexando um documento grande em um email vai saber do que eu falo.
Agora ativando o SQM:
root@router.lan3:~# sh betterspeedtest.sh
2015-09-30 01:40:12 Testing against netperf.bufferbloat.net (ipv4) with 5 simultaneous sessions while pinging gstatic.com (60 seconds in each direction)
.............................................................
Download: 4.61 Mbps
Latency: (in msec, 61 pings, 0.00% packet loss)
Min: 10.860
10pct: 12.388
Median: 18.495
Avg: 20.443
90pct: 27.702
Max: 57.228
..............................................................
Upload: 0.5 Mbps
Latency: (in msec, 60 pings, 0.00% packet loss)
Min: 11.078
10pct: 12.813
Median: 25.371
Avg: 26.920
90pct: 42.409
Max: 54.265
Agora o aumento na latência foi bem menor! A média subiu apenas para 18/25, respectivamente. Em contrapartida, a taxa de transmissão foi menor pois estou podando ela antes de atingir o limite que a operadora me oferta.
Mas o valor ainda subiu muito! Olhe o valor máximo! O SQM tem um certo volume de carência em função da taxa de transmissão configurada. No início da conexão, ele permite que a fila aumente pois ainda não conhece o comportamento desta conexão. No speedtest pelo navegador que mencionei anteriormente, é possível observar este comportamento. Quando esta apresentar um volume maior, ela vai ser reclassificada. Outro motivo é para aproveitar melhor as rajadas de tráfego (seu provedor, por exemplo, pode liberar uma maior taxa de transmissão para os primeiros kbytes para tornar a resposta de coisas leves como navegação em páginas mais fluída). Se podar ainda mais sua conexão, ou fazer um teste mais longo, a média tende a ser menor.
Brinque, teste variações na configuração na velocidade de upload e download. Avalie quando o QoS se tornou efetivo. Compare com o qos-scripts. Avalie a usabilidade da internet. Compartilhe sua experiência com o sqm-scripts no fórum deste blog.
Até a próxima.