Dicas para maximizar pedidos de Nginx / s?

15

Estou criando um pacote de análise e os requisitos do projeto indicam que preciso dar suporte a 1 bilhão de acessos por dia. Sim, "bilhões". Em outras palavras, nada menos que 12.000 acessos por segundo sustentados e, de preferência, algum espaço para estourar. Eu sei que precisarei de vários servidores para isso, mas estou tentando obter o máximo desempenho de cada nó antes de "lançar mais hardware nele".

Neste momento, tenho a parte de acompanhamento de cliques concluída e bem otimizada. Eu praticamente apenas salvei os pedidos diretamente no Redis (para processamento posterior com o Hadoop). A aplicação é Python / Django com um gunicorn para o gateway.

Meu servidor Ubuntu 10.04 Rackspace de 2 GB (não uma máquina de produção) pode atender cerca de 1200 arquivos estáticos por segundo (comparados usando o Apache AB com um único ativo estático). Para comparar, se eu trocar o link de arquivo estático com meu link de rastreamento, ainda recebo cerca de 600 solicitações por segundo - acho que isso significa que meu rastreador está bem otimizado, porque é apenas um fator de 2 mais lento do que servir o mesmo ativo estático repetidamente.

No entanto, quando faço benchmark com milhões de acessos, percebo algumas coisas -

  1. Não há uso de disco - isso é esperado, porque eu desativei todos os logs do Nginx e meu código personalizado não faz nada, exceto salvar os detalhes da solicitação no Redis.
  2. Uso de memória não constante - Presumivelmente, devido ao gerenciamento de memória do Redis, meu uso de memória aumentará gradualmente e, em seguida, voltará para baixo, mas nunca foi meu gargalo.
  3. A carga do sistema está em torno de 2 a 4, o sistema ainda é responsivo durante os meus benchmarks mais pesados, e ainda posso ver manualmente o link com pouco atraso visível enquanto meu (outro) servidor realiza 600 solicitações por segundo.
  4. Se eu fizer um teste curto, digamos 50.000 acessos (demora cerca de 2m), recebo 600 solicitações por segundo constantes e confiáveis. Se eu executar um teste mais longo (tentei até 3.5m até o momento), meus r / s serão reduzidos para cerca de 250.

Minhas perguntas -

a. Parece que estou maximizando este servidor ainda? O desempenho nginx de arquivos estáticos de 1.200 / s é comparável ao que outros experimentaram?

b. Há afinações nginx comuns para aplicativos de alto volume? Tenho threads de trabalho definidos para 64 e threads de trabalho de gunicorn definidos como 8, mas ajustar esses valores não parece me ajudar ou prejudicar muito.

c. Há alguma configuração no nível do Linux que possa limitar minhas conexões de entrada?

d. O que poderia causar meu desempenho para degradar a 250r / s em testes de longa duração? Mais uma vez, a memória não está maximizando durante esses testes, e o uso do HDD é nulo.

Obrigado antecipadamente, todos:)

EDITAR Aqui está o meu nginx config - link - é principalmente baunilha, com óbvia gordura aparada.

    
por linkedlinked 11.01.2011 / 22:32

2 respostas

8

Você está abusando do worker_threads do Nginx. Não há absolutamente nenhuma necessidade de executar muitos trabalhadores. Você deve executar quantos trabalhadores tiver CPUs e chamá-las por dia. Se você estiver executando o gunicorn no mesmo servidor, provavelmente deverá limitar os trabalhadores do nginx a dois. Caso contrário, você apenas vai agitar as CPUs com toda a alternância de contexto necessária para gerenciar todos esses processos.

    
por 12.01.2011 / 01:19
2

Eu usei o nginx para servir 5K por segundo para conteúdo estático. Você pode aumentar o número de worker_connections que estão atualmente configurados para 1024.

O cálculo max_client seria o seguinte.

O worker_connections and worker_proceses da seção principal permite que você calcule o valor de maxclients:

max_clients = worker_processes * worker_connections

Em uma situação de proxy reverso, max_clients se torna

max_clients = worker_processes * worker_connections / 4

link

O cálculo das conexões máximas do trabalhador é fácil quando você conhece a capacidade da sua configuração. A capacidade total / número de núcleos é de conexões máximas de trabalho. Para calcular a capacidade total, existem várias maneiras.

  1. Sugiro que você tente e faça um benchmark de sua configuração que fornecerá os números mais realistas. Você pode usar ferramentas como cerco, pummel, banco de apache, etc., lembre-se de medir o uso de recursos do sistema durante o teste.

Se o método acima não funcionar, tente os métodos abaixo. Eu estou fazendo suposições amplas ignorando RAM e IO, eles também irão fatorar, mas estes darão pontos de partida e você pode fazer ajustes a partir daí.

  1. Suponha que a largura de banda é o gargalo, pegue o tamanho médio do objeto que o nginx está servindo e divida sua largura de banda com isso e você obterá o máximo de qps suportados.

  2. Na segunda suposição, a CPU é o gargalo. Nesse caso, meça o tempo de solicitação e divida 1 por ele e múltiplo com o número de núcleos em seu sistema. Isso fornecerá o número de solicitações por segundo que o nginx pode manipular.

por 12.01.2011 / 02:57