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.
Ruben Homs
fonte
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.

Cameron Kerr
fonte
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?

shodanshok
fonte
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
Aqui você vai #
Ruben Homs
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

PersianGulf
fonte
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.

unicoletti
fonte