Número ideal de processos unicórnio por CPU

16

Estamos executando um aplicativo da web Ruby on Rails no Unicorn. Nosso aplicativo não é estritamente vinculado à CPU (temos um sistema Xeon E5645 duplo com 12 núcleos e um valor médio de carga de pico é de cerca de 6). Inicialmente, começamos com 40 funcionários do Unicorn, mas a pegada de memória do aplicativo aumentou com o tempo. Então, agora temos que diminuir o número de processos do trabalhador. Eu pensei que a fórmula padrão (número de núcleos de CPU + 1) também se aplica ao Unicorn, mas meu colega tentou me convencer de que deveríamos reservar mais instâncias do Unicorn por CPU e fornecia esse link . No entanto, não sei exatamente por que precisamos gastar tanta memória em processos ociosos do Unicorn.

Minha pergunta é: qual o motivo de ter mais de uma instância do Unicorn por núcleo de CPU? É devido a alguma peculiaridade arquitetônica do Unicorn? Estou ciente de que os processos ocupados do Unicorn não podem aceitar novas conexões (estamos usando soquetes de domínio UNIX para se comunicar com as instâncias do Unicorn BTW), mas achei que a lista de pendências foi introduzida exatamente para resolver isso. É possível superar essas 2 a 8 instâncias Unicorn por regra de CPU?

Alex
fonte

Respostas:

17

Ok, eu encontrei a resposta finalmente. O número ideal de trabalhadores do Unicorn não está diretamente conectado ao número de núcleos da CPU, depende da carga e da estrutura / capacidade de resposta do aplicativo interno. Basicamente, usamos o perfilador de amostragem para determinar o estado dos trabalhadores, tentamos manter os trabalhadores 70% ociosos e 30% realizando o trabalho real. Portanto, 70% das amostras devem estar "aguardando a chamada select () para obter uma solicitação do servidor front-end". Nossa pesquisa mostrou que existem apenas três estados efetivos dos trabalhadores: 0-30% das amostras estão ociosas, 30-50% das amostras estão ociosas e 50-70% das amostras estão ociosas (sim, podemos obter mais amostras ociosas, mas existem não é um ponto real porque a capacidade de resposta do aplicativo não muda significativamente). Consideramos 0-30% da situação uma "zona vermelha" e 30-50% da situação uma "zona amarela".

Alex
fonte
11
Você pode explicar como está amostrando o estado desses trabalhadores?
quer
6

Você está certo sobre N + 1 para trabalhos vinculados à CPU.

Por outro lado, o unicórnio não usa threads, portanto, todas as operações de IO. bloqueia o processo e outro processo pode ativar e analisar cabeçalhos HTTP, concatenar seqüências de caracteres e executar todas as tarefas intensivas em CPU necessárias para atender o usuário (fazendo isso antes para reduzir a latência de solicitações).

E você pode querer ter mais threads / processos do que núcleos. Imagine a seguinte situação: req. A leva dez vezes mais que o req. B, você tem várias solicitações A simultâneas e a solicitação B rápida é enfileirada aguardando a conclusão do A-req. Portanto, se você puder prever o número de solicitações pesadas, poderá usar esse número como outra diretriz para ajustar o sistema.

darkk
fonte
11
Bom ponto, vamos supor que as solicitações sejam distribuídas mais ou menos igualmente e sejam bem leves (na verdade, temos solicitações pesadas, mas elas são tratadas por outro pool de unicórnios). Se todas as solicitações ficarem subitamente pesadas (por exemplo, no caso de falta de E / S em um nó do banco de dados), ficaremos inativos, independentemente do número de instâncias da CPU, suponho. Bem, provavelmente a melhor maneira de saber a verdade é realizar algum tipo de teste de carga.
22412 Alex
Sim, o teste irá lhe dizer. Ou, se você já iniciou, pode grep logs e procurar o número máximo de solicitações simultâneas. Tenho certeza de que você registra o tempo de solicitação e o tempo de resposta do back-end. O Nginx será seu amigo se não o fizer. :)
darkk