Estou criando um pacote de análise e os requisitos do projeto afirmam que preciso suportar 1 bilhão de acessos por dia. Sim, "bilhões". Em outras palavras, não menos que 12.000 acessos por segundo foram mantidos, e de preferência algum espaço para explodir. 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".
No momento, tenho a parte de rastreamento de hits concluída e bem otimizada. Eu praticamente salvo as solicitações diretamente no Redis (para processamento posterior com o Hadoop). O aplicativo é Python / Django com um gunicorn para o gateway.
Meu servidor Rackspace Ubuntu 10.04 de 2 GB (não uma máquina de produção) pode servir cerca de 1200 arquivos estáticos por segundo (comparado com o Apache AB com um único ativo estático). Para comparar, se eu trocar o link do arquivo estático pelo 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 2 mais lento que atender ao mesmo ativo estático repetidamente.
No entanto, quando comparo com milhões de hits, percebo algumas coisas -
- Sem uso de disco - isso é esperado, porque eu desliguei todos os logs do Nginx e meu código personalizado não faz nada além de salvar os detalhes da solicitação no Redis.
- Uso de memória não constante - Presumivelmente, devido ao gerenciamento de memória do Redis, meu uso de memória aumenta gradualmente e diminui novamente, mas nunca foi o meu gargalo.
- A carga do sistema fica em torno de 2 a 4, o sistema ainda é responsivo até mesmo nos meus benchmarks mais pesados e ainda posso visualizar manualmente http://mysite.com/tracking/pixel com pouco atraso visível enquanto meu (outro) servidor executa 600 solicitações por segundo.
- Se eu executar um teste curto, digamos 50.000 acessos (leva cerca de 2m), recebo 600 solicitações constantes e confiáveis por segundo. Se eu executar um teste mais longo (até 3,5 m até agora), meu r / s diminui para cerca de 250.
Minhas perguntas --
uma. Parece que eu estou atingindo o máximo do servidor ainda? O desempenho do nginx dos arquivos estáticos de 1.200 / s é comparável ao que outros experimentaram?
b. Existem ajustes comuns do nginx para aplicativos de alto volume? Eu tenho threads de trabalho definidas como 64 e threads de trabalho gunicorn definidas como 8, mas ajustar esses valores não parece me ajudar ou prejudicar muito.
c. Existem configurações no nível do linux que podem estar limitando minhas conexões de entrada?
d. O que poderia causar a degradação do meu desempenho para 250r / s em testes de longa duração? Novamente, a memória não está atingindo o limite máximo durante esses testes, e o uso do HD é nulo.
Agradecemos antecipadamente, todos :)
EDIT Aqui está a minha configuração do nginx - http://pastie.org/1450749 - é principalmente baunilha, com gordura aparada aparada.
fonte
Respostas:
Você está abusando dos worker_threads do Nginx. Não há absolutamente nenhuma necessidade de administrar tantos trabalhadores. Você deve executar quantos trabalhadores tiver CPUs e encerrar o dia. Se você estiver executando o gunicorn no mesmo servidor, provavelmente deverá limitar os trabalhadores do nginx a dois. Caso contrário, você só irá debater as CPUs com toda a alternância de contexto necessária para gerenciar todos esses processos.
fonte
Eu usei o nginx para servir 5K solicitando um segundo para conteúdo estático. Você pode aumentar o número de conexões de trabalho atualmente definidas para 1024.
O cálculo de max_client seria o seguinte.
O worker_connections e worker_proceses da seção principal permite calcular 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
http://wiki.nginx.org/EventsModule#worker_connections
O cálculo das conexões máximas de funcionários é fácil quando você conhece a capacidade de sua configuração. A capacidade total / número de núcleos é o máximo de conexões do trabalhador. Para calcular a capacidade total, existem várias maneiras.
Se o método acima não funcionar, tente os métodos abaixo. Estou fazendo suposições amplas, ignorando a RAM e o IO, elas também serão consideradas, mas elas fornecerão pontos de partida e você poderá fazer ajustes a partir daí.
Supondo que a largura de banda seja o gargalo, considere o tamanho médio do objeto que o nginx está exibindo e divida sua largura de banda com isso e você obterá o máximo de qps suportados.
Na segunda hipótese, CPU é o gargalo. Nesse caso, meça o tempo de solicitação e divida 1 por ele e multiplique pelo número de núcleos em seu sistema. Isso fornecerá o número de solicitações por segundo que o nginx pode manipular.
fonte