tcpdump aumenta o desempenho do udp

13

Estou executando um conjunto de testes de carga para determinar o desempenho da seguinte configuração:

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

Em resumo, o conjunto de testes node.js envia uma quantidade definida de métricas a cada x segundos para uma instância StatsD localizada em outro servidor. StatsD, por sua vez, libera as métricas a cada segundo para uma instância Graphite localizada no mesmo servidor. Então, vejo quantas métricas foram realmente enviadas pela suíte de testes e quantas foram recebidas pelo Graphite para determinar a perda de pacotes entre o conjunto de testes e o Graphite.

No entanto, notei que às vezes tenho taxas de queda de pacotes muito grandes (note que ele está sendo enviado com o protocolo UDP), variando de 20 a 50%. Então foi quando comecei a investigar onde esses pacotes estavam sendo descartados, já que poderia ser algum problema de desempenho com o StatsD. Então, comecei a registrar as métricas em todas as partes do sistema para rastrear onde essa queda ocorreu. E é aí que as coisas ficam estranhas.

Estou usando tcpdump para criar um arquivo de captura que inspeciono depois que o teste é executado. Mas sempre que executo os testes com o tcpdump em execução, a perda de pacotes é quase inexistente! Parece que o tcpdump está de alguma forma aumentando o desempenho dos meus testes e eu não consigo descobrir por que e como isso acontece. Estou executando o seguinte comando para registrar as mensagens do tcpdump no servidor e no cliente:

tcpdump -i any -n port 8125 -w test.cap

Em um caso de teste específico, estou enviando 40000 métricas / s. O teste durante a execução do tcpdump tem uma perda de pacotes de cerca de 4%, enquanto o teste sem uma perda de pacotes de cerca de 20%

Ambos os sistemas estão sendo executados como Xen VMs com a seguinte configuração:

  • Intel Xeon E5-2630 v2 a 2.60GHz
  • 2 GB de RAM
  • Ubuntu 14.04 x86_64

Coisas que eu já verifiquei para possíveis causas:

  • Aumentando o tamanho de recebimento / envio do buffer UDP.
  • carga da CPU afetando o teste. (carga máxima de 40-50%, do lado do cliente e do servidor)
  • Executando o tcpdump em interfaces específicas em vez de 'any'.
  • Executando o tcpdump com '-p' para desativar o modo promíscuo.
  • Executando o tcpdump apenas no servidor. Isso resultou na perda de 20% do pacote e parece não ter impacto nos testes.
  • Executando o tcpdump apenas no cliente. Isso resultou em aumento de desempenho.
  • Aumentando netdev_max_backlog e netdev_budget para 2 ^ 32-1. Isso não fez diferença.
  • Tentei todas as configurações possíveis do modo promíscuo em cada nic (servidor ligado e cliente desligado, servidor desligado e cliente ligado, ambos ligados, ambos desligados). Isso não fez diferença.
por Ruben Homs 30.04.2015 / 16:45

4 respostas

10

Quando o tcpdump está rodando, será bastante rápido para ler nos quadros de entrada. Minha hipótese é que as configurações do buffer de anel de pacote da NIC podem ser um pouco menores; Quando o tcpdump está sendo executado, ele é esvaziado de maneira mais rápida.

Se você é um assinante da Red Hat, então este artigo de suporte é muito útil Visão geral da recepção de pacotes . Tem algumas coisas que eu não acho que você tenha considerado ainda.

Considere como seu sistema está lidando com IRQs; considere aumentar o 'dev_weight' da interface de rede (significando mais pacotes lidos do NIC para o espaço do usuário); veja com que frequência o aplicativo lê o soquete (ele pode usar um thread dedicado, existem problemas / soluções conhecidos relacionados à escalabilidade).

Aumente o buffer de quadros NIC (usando o comando ethtool - veja os argumentos --set-ring etc.).

Veja 'receba dimensionamento de lado' e use pelo menos que muitos segmentos recebam para ler no tráfego.

Gostaria de saber se o tcpdump está fazendo algo legal, como usar o suporte do kernel para buffers de anel de pacote . Isso ajudaria a explicar o comportamento que você está vendo.

    
por 04.05.2015 / 12:33
2

Qual governador de energia você está usando? Eu vi comportamentos semelhantes com o governador "ondemand" ou "conservador".

Tente usar o governador "performance" e desabilitar quaisquer recursos que economizam energia no BIOS do servidor.

Isso muda alguma coisa?

    
por 04.05.2015 / 11:30
1

Outra maneira é ip_conntarck module, Você tem certeza que seu linux-box pode aceitar nova conexão? teste via:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Você tem que testar

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

se max == count, sua conexão máxima está cheia e sua caixa de entrada não aceita nova conexão.
Se você não tem ip_conntrack, você pode carregar facilmente via modprobe ip_conntrack

    
por 05.05.2015 / 06:42
1

Eu suspeito que o lado de recebimento simplesmente não é capaz de lidar com a taxa de pacotes e aqui está o porquê:

  1. usando tcpdump no cliente reduz os pacotes descartados: tcpdump está tornando o cliente mais lento e, portanto, o servidor está vendo uma taxa de empacotador muito menor que ainda pode ser parcialmente manipulada. Você deve ser capaz de confirmar essa hipótese verificando os contadores de pacotes RX / TX no cliente e no servidor

  2. você mencionou que aumentou o tamanho do recebimento / envio do buffer UDP, poderia detalhar como? É importante que no servidor você altere ambos rmem_max e rmem_default, exemplo: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

Testando suas configurações

Pare o statsd e o aplicativo do nó e, em seguida, com os sistemas ociosos, use iperf para testar a taxa de pacotes que a rede / kernel pode manipular . Se você pode transmitir 40k pacotes / s com iperf, mas não pode com statsd, então você deve concentrar seus esforços em ajustar statsd.

Outros ajustáveis

Lembre-se também de sintonizar net.core.netdev_max_backlog : número máximo de pacotes permitidos para fila quando uma interface em particular recebe pacotes mais rápido do que o kernel pode processá-los.

    
por 07.05.2015 / 10:24