Por que o desempenho do TCP accept () é tão ruim no Xen?

89

A taxa na qual meu servidor pode aceitar () novas conexões TCP de entrada é muito ruim no Xen. O mesmo teste em hardware bare metal mostra 3-5x acelerações.

  1. Por que isso é tão ruim sob o Xen?
  2. Você pode ajustar o Xen para melhorar o desempenho de novas conexões TCP?
  3. Existem outras plataformas de virtualização mais adequadas para esse tipo de caso de uso?

fundo

Ultimamente, tenho pesquisado alguns gargalos de desempenho de um servidor Java desenvolvido internamente, executando o Xen. O servidor fala HTTP e atende chamadas simples de conexão / solicitação / resposta / desconexão TCP.

Porém, mesmo ao enviar cargas de tráfego para o servidor, ele não pode aceitar mais do que ~ 7000 conexões TCP por segundo (em uma instância do EC2 de 8 núcleos, c1.xlarge executando o Xen). Durante o teste, o servidor também exibe um comportamento estranho, onde um núcleo (não necessariamente a CPU 0) fica muito carregado> 80%, enquanto os outros núcleos permanecem quase inativos. Isso me leva a pensar que o problema está relacionado ao kernel / virtualização subjacente.

Ao testar o mesmo cenário em uma plataforma não virtualizada bare metal, recebo resultados de testes mostrando taxas de aceitação de TCP () além de 35.000 / segundo. Isso em uma máquina Core i5 de 4 núcleos executando o Ubuntu com todos os núcleos quase totalmente saturados. Para mim, esse tipo de figura parece certa.

Na instância do Xen, tentei ativar / ajustar quase todas as configurações existentes no sysctl.conf. Incluindo a habilitação da Direção de recebimento de pacotes e Direção de fluxo de recebimento e fixação de threads / processos nas CPUs, mas sem ganhos aparentes.

Eu sei que o desempenho degradado é esperado ao executar virtualizado. Mas a este grau? Um servidor bare metal mais lento que o desempenho superior. 8-core por um fator de 5?

  1. Esse é realmente o comportamento esperado do Xen?
  2. Você pode ajustar o Xen para melhorar o desempenho de novas conexões TCP?
  3. Existem outras plataformas de virtualização mais adequadas para esse tipo de caso de uso?

Reproduzindo esse comportamento

Ao investigar mais sobre isso e identificar o problema, descobri que a ferramenta de teste de desempenho do netperf poderia simular o cenário semelhante que estou enfrentando. Usando o teste TCP_CRR do netperf, coletei vários relatórios de diferentes servidores (virtualizados e não virtuais). Se você deseja contribuir com algumas descobertas ou consultar meus relatórios atuais, consulte https://gist.github.com/985475

Como sei que esse problema não se deve a um software mal escrito?

  1. O servidor foi testado em hardware bare metal e quase satura todos os núcleos disponíveis.
  2. Ao usar conexões TCP keep-alive, o problema desaparece.

Por que isso é importante?

Na ESN (meu empregador), sou o líder do projeto do Beaconpush , um servidor Comet / Web Socket escrito em Java. Embora seja de alto desempenho e possa saturar quase toda a largura de banda fornecida em condições ideais, ainda é limitado à rapidez com que novas conexões TCP podem ser feitas. Ou seja, se você tem uma grande rotatividade de usuários onde os usuários vão e vêm com muita frequência, muitas conexões TCP terão que ser configuradas / desativadas. Tentamos mitigar isso mantendo as conexões vivas o maior tempo possível. Mas, no final, o desempenho accept () é o que impede nossos núcleos de girarem e não gostamos disso.


Atualização 1

Alguém postou esta pergunta no Hacker News , também há algumas perguntas / respostas. Mas tentarei manter essa pergunta atualizada com as informações que encontrar à medida que for avançando.

Hardware / plataformas Eu testei isso em:

  • EC2 com tipos de instância c1.xlarge (8 núcleos, 7 GB de RAM) e cc1.4xlarge (2x Intel Xeon X5570, 23 GB de RAM). As AMIs utilizadas foram ami-08f40561 e ami-1cad5275, respectivamente. Alguém também apontou que os "Grupos de Segurança" (ou seja, o firewall do EC2s) também podem afetar. Mas para esse cenário de teste, tentei apenas no host local para eliminar fatores externos como esse. Outro boato que ouvi é que instâncias do EC2 não podem enviar mais do que 100k PPS.
  • Dois servidores virtualizados particulares executando o Xen. Um deles tinha carga zero antes do teste, mas não fez diferença.
  • Servidor Xen dedicado dedicado na Rackspace. Sobre os mesmos resultados lá.

Estou no processo de reexecutar esses testes e preencher os relatórios em https://gist.github.com/985475 Se você quiser ajudar, contribua com seus números. É fácil!

(O plano de ação foi movido para uma resposta consolidada separada)

cgbystrom
fonte
3
Excelente trabalho para identificar um problema, mas acredito que você seria atendido muito melhor em uma lista de discussão específica do Xen, em um fórum de suporte ou mesmo no site de relatório de erros da xensource . Acredito que isso possa ser um bug do agendador - se você pegar seu número de 7.000 conexões * 4 núcleos / carga de CPU de 0,80, obterá exatamente 35.000 - o número que você receberia quando 4 núcleos ficariam totalmente saturados.
the-wabbit
Ah, e mais uma coisa: tente uma versão diferente (talvez mais recente) do kernel para o seu convidado, se puder.
the-wabbit
@ syneticon-dj Obrigado. Eu tentei em um cc1.4xlarge no EC2 com o kernel 2.6.38. Vi cerca de 10% de aumento se não me engano. Mas é mais provável devido ao hardware mais robusto desse tipo de instância.
Cgbystrom 22/05
6
obrigado por manter isso atualizado com as respostas do HN, é uma ótima pergunta. Sugiro que você mova o plano de ação para uma resposta consolidada, possivelmente - pois essas são todas as respostas possíveis para o problema.
Jeff Atwood
@jeff Mova o plano de ação, verifique.
Cgbystrom 22/05

Respostas:

27

No momento: o desempenho de pequenos pacotes é péssimo no Xen

(passou da própria pergunta para uma resposta separada)

De acordo com um usuário no HN (um desenvolvedor de KVM?), Isso se deve ao desempenho de pequenos pacotes no Xen e também no KVM. É um problema conhecido com a virtualização e, segundo ele, o ESX da VMWare lida com isso muito melhor. Ele também observou que a KVM está trazendo alguns novos recursos projetados para aliviar isso ( postagem original ).

Esta informação é um pouco desanimadora se estiver correta. De qualquer forma, tentarei as etapas abaixo até que algum guru do Xen venha com uma resposta definitiva :)

Iain Kay, da lista de discussão xen-users, compilou este gráfico: gráfico netperf Observe as barras TCP_CRR, compare "2.6.18-239.9.1.el5" vs "2.6.39 (com o Xen 4.1.0)".

Plano de ação atual com base nas respostas / respostas aqui e no HN :

  1. Envie esse problema para uma lista de discussão específica do Xen e o bugzilla do xensource, conforme sugerido por syneticon-dj Uma mensagem foi postada na lista de usuários do xen , aguardando resposta.

  2. Crie um caso de teste patológico simples no nível do aplicativo e publique-o.
    Um servidor de teste com instruções foi criado e publicado no GitHub . Com isso, você poderá ver um caso de uso mais real comparado ao netperf.

  3. Tente uma instância de convidado do Xen do PV Xen de 32 bits, pois 64 bits pode estar causando mais sobrecarga no Xen. Alguém mencionou isso no HN. Não fez diferença.

  4. Tente ativar o net.ipv4.tcp_syncookies no sysctl.conf, conforme sugerido por abofh no HN. Aparentemente, isso pode melhorar o desempenho, pois o aperto de mão ocorre no kernel. Não tive sorte com isso.

  5. Aumente o atraso de 1024 para algo muito mais alto, também sugerido por abofh no HN. Isso também pode ajudar, já que o convidado pode aceitar () mais conexões durante sua fatia de execução fornecida pelo dom0 (o host).

  6. Verifique novamente se o conntrack está desativado em todas as máquinas, pois pode reduzir pela metade a taxa de aceitação (sugerida por deubeulyou). Sim, foi desativado em todos os testes.

  7. Verifique se há "excesso de fila de escuta" e "excesso de buckets de sincronização" no netstat -s "(sugerido por mike_esspe no HN).

  8. Divida a manipulação de interrupções entre vários núcleos (o RPS / RFS que tentei ativar anteriormente deve fazer isso, mas pode valer a pena tentar novamente). Sugerido por adamt no HN.

  9. Desativando o descarregamento da segmentação TCP e a aceleração de dispersão / coleta, conforme sugerido por Matt Bailey. (Não é possível em hosts EC2 ou VPS similares)

cgbystrom
fonte
2
+1 Poste definitivamente os resultados de desempenho quando descobrir!
Chrisaycock #
Alguém me cutucou no Twitter sobre essa questão. Infelizmente, parece que esses problemas persistem. Eu não investi muita pesquisa desde o ano passado. O Xen PODE ter melhorado durante esse período, não sei. O desenvolvedor do KVM também mencionou que estava abordando questões como esta. Pode valer a pena perseguir. Além disso, outra recomendação que ouvi é tentar o OpenVZ em vez do Xen / KVM, pois adiciona menos ou nenhuma camada / interceptação de syscalls.
cgbystrom
21

Curiosamente, descobri que desativar a aceleração de hardware da NIC melhora muito o desempenho da rede no controlador Xen (também verdadeiro para o LXC):

Aceleração de coleta de dispersão:

/usr/sbin/ethtool -K br0 sg off

Transferência de segmentação TCP:

/usr/sbin/ethtool -K br0 tso off

Onde br0 é sua ponte ou dispositivo de rede no host do hipervisor. Você precisará configurá-lo para desativá-lo a cada inicialização. YMMV.

Matt Bailey
fonte
Eu segundo isso. Eu tinha um servidor Windows 2003 em execução no Xen que sofreu alguns problemas terríveis de perda de pacotes sob condições de alto rendimento. O problema foi embora quando eu desativado offload segmento TCP
rupello
Obrigado. Atualizei o "plano de ação" na pergunta original com suas sugestões.
Cgbystrom #
3

Talvez você possa esclarecer um pouco - você executou os testes no Xen em seu próprio servidor ou apenas em uma instância do EC2?

Accept é apenas mais um syscall, e novas conexões são apenas diferentes, pois os primeiros pacotes terão alguns sinalizadores específicos - um hipervisor como o Xen definitivamente não deve ver nenhuma diferença. Outras partes da sua instalação podem: no EC2, por exemplo, não ficaria surpreso se os Grupos de Segurança tivessem algo a ver com isso; Também é relatado que o conntrack reduz pela metade novas taxas de aceitação de conexões (PDF) .

Por fim, parece haver combinações de CPU / Kernel que causam estranhos usos / interrupções da CPU no EC2 (e provavelmente no Xen em geral), como publicado recentemente por Librato .

deubeulyou
fonte
Atualizei a pergunta e esclareci em que hardware eu tentei isso. A abofh também sugeriu aumentar a lista de pendências além de 1024 para acelerar o número possível de accept () s durante uma fatia de execução para o convidado. Em relação ao conntrack, eu definitivamente deveria verificar se essas coisas estão desativadas, obrigado. Eu li o artigo Liberato, mas, dada a quantidade de hardware diferente em que experimentei, não deve ser o caso.
Cgbystrom 22/05
0

Certifique-se de ter desabilitado o iptables e outros ganchos no código de ponte no dom0. Obviamente, isso só se aplica à configuração em ponte da rede Xen.

echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables

Depende do tamanho do servidor, mas os menores (processador de 4 núcleos) dedicam um núcleo de CPU ao Xen dom0 e o fixam. Opções de inicialização do hipervisor:

dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>

Você tentou passar o dispositivo PCI físico Ethernet para o domU? Deve haver um bom aumento de desempenho.

Kupson
fonte