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. O StatsD, por sua vez, libera as métricas a cada segundo para uma instância do Graphite localizada no mesmo servidor. Depois, analiso quantas métricas foram realmente enviadas pelo conjunto 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 recebia taxas muito grandes de queda de pacotes (observe que ele está sendo enviado com o protocolo UDP), variando de 20 a 50%. Foi então que comecei a investigar onde esses pacotes estavam sendo descartados, pois poderia haver 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 o tcpdump para criar um arquivo de captura que inspeciono após a execução do teste. Mas sempre que eu executo os testes com o tcpdump em execução, a perda de pacotes é quase inexistente! Parece que o tcpdump está aumentando o desempenho dos meus testes e não consigo descobrir por que e como isso acontece. Estou executando o seguinte comando para registrar as mensagens 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 apresenta 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 executando como VMs do Xen com a seguinte configuração:

  • Intel Xeon E5-2630 v2 a 2.60GHz
  • 2GB 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 que afeta 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 pacotes de 20% e parece não afetar os testes.
  • Executando o tcpdump apenas no cliente. Isso resultou em maior 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 todos os nichos (servidor ativado e cliente desativado, servidor desativado e cliente ativado, ambos ativados, ambos desativados). Isso não fez diferença.

3
Uma coisa que o tcpdump faz por padrão é colocar sua interface de rede no modo promíscuo. Você pode querer passar a -popção de pular isso para ver se faz alguma diferença.
Zoredache

Então você está executando o tcpdump no cliente e no servidor, e a taxa de perda de pacotes cai? O que acontece se você executá-lo apenas no cliente e o que acontece se você executá-lo apenas no servidor? (E, sim, também tentar transformar o modo promíscuo fora, e talvez também tentar capturar na interface de rede específica utilizada para o teste em vez de "qualquer" dispositivo, para ver se que faz a diferença.)

Obrigado por seus comentários. Tentei as duas recomendações e editei minha pergunta para refletir o que tentei, mas isso não afetou o problema.
Ruben Homs

A colocação de placas de rede em ambas as máquinas no modo promíscuo tem o mesmo efeito que a execução do tcpdump? ifconfig eth0 promiscativa e ifconfig eth0 -promiscdesativa o modo promíscuo em eth0. Se isso fizer diferença, tente comparar as 4 combinações possíveis de promisc ativadas / desativadas nas duas máquinas. Isso pode ajudar a identificar a fonte dos problemas.
Fox

@ Fox Obrigado pela resposta! Eu tentei todas as combinações possíveis para todos os nichos, mas sem diferença nos resultados. Atualizei minha pergunta para refletir isso.
Ruben Homs

Respostas:


10

Quando o tcpdump estiver em execução, será bastante rápido ler os quadros recebidos. Minha hipótese é que as configurações do buffer de anel de pacote da NIC podem ser um pouco menores; Quando o tcpdump está em execução, ele é esvaziado de maneira mais oportuna.

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

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

Aumente o buffer do quadro da NIC (usando o ethtoolcomando - veja os --set-ringargumentos etc.).

Observe 'redimensionamento lateral de recebimento' e use pelo menos muitos segmentos de recebimento para ler no tráfego.

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


Como esse é um ambiente Xen, você provavelmente deve fazer (pelo menos alguns) isso no host Xen.
Cameron Kerr #

Isso é algo que eu nunca tinha pensado antes, coisas muito interessantes, obrigado! Vou tentar isso assim que tiver acesso ao host Xen e informaremos como isso acontece.
Ruben Homs

2

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

Tente usar o governador de "desempenho" e desativar todos os recursos que economizam energia no BIOS do servidor.

Isso muda alguma coisa?


Estou tendo problemas para descobrir qual governador de poder estou usando. Tentei correr, cpufreq-infomas recebi uma mensagem dizendo no or unknown cpufreq driver is active on this CPU. Também ao usá- cpupower frequency-infolo retorna no or unknown cpufreq driver is active on this CPU. Embora eu não posso confirmar isso no momento, o site do fabricante VM me leva a acreditar que está em execução no modo "performance" desde que eu tenho uma CPU Intel ..
Ruben Homs

Você pode mostrar a saída dos seguintes comandos? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
shodanshok 4/15


1

Outra maneira é o ip_conntarckmódulo: Você tem certeza que sua caixa Linux pode aceitar uma 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 Linux não pode aceitar nova conexão.
Se você não possui o ip_conntrack, pode carregar facilmente viamodprobe ip_conntrack


2
E, se for esse o caso, você deve examinar o destino NOTRACK na tabela 'bruta' para impedir o rastreamento de conexão. Fiz isso recentemente para um servidor DNS ocupado e ele removeu o iptables de ser o gargalo e causar tempos limite de resolução de DNS.
Cameron Kerr #

E aqui está um exemplo de como usei as regras NOTRACK para que o IPTables não execute nenhum rastreamento de conexão para o DNS UDP. distracted-it.blogspot.co.nz/2015/05/...
Cameron Kerr

1

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

  1. o uso do tcpdump no cliente reduz os pacotes descartados: o tcpdump está diminuindo a velocidade do cliente e, portanto, o servidor está vendo uma taxa de empacotador muito menor com a qual ainda pode lidar parcialmente. Você deve poder confirmar esta hipótese verificando os contadores de pacotes RX / TX no cliente e no servidor

  2. você mencionou que aumentou o tamanho de recebimento / envio do buffer UDP, poderia detalhar como? É importante que no servidor você altere 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, com o sistema inativo, use o iperf para testar a taxa de pacotes que a rede / kernel pode manipular. Se você pode transmitir 40K pacotes / s com o iperf, mas não com o statsd, concentre seus esforços no ajuste do statsd.

Outros ajustáveis

Lembre-se também de ajustar net.core.netdev_max_backlog : número máximo de pacotes que podem enfileirar quando uma interface específica recebe pacotes mais rapidamente do que o kernel pode processá-los.

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.