Estamos nos deparando com um comportamento estranho em que vemos alta utilização da CPU, mas média de carga bastante baixa.
O comportamento é melhor ilustrado pelos gráficos a seguir do nosso sistema de monitoramento.
Por volta das 11h57, a utilização da CPU passa de 25% para 75%. A média de carga não é significativamente alterada.
Executamos servidores com 12 núcleos com 2 hyper threads cada. O sistema operacional vê isso como 24 CPUs.
Os dados de utilização da CPU são coletados executando a /usr/bin/mpstat 60 1
cada minuto. Os dados da all
linha e da %usr
coluna são mostrados no gráfico acima. Tenho certeza de que isso mostra a média por dados da CPU, não a utilização "empilhada". Embora vejamos 75% de utilização no gráfico, vemos um processo mostrando o uso de cerca de 2.000% da CPU "empilhada" em top
.
O valor médio da carga é obtido a /proc/loadavg
cada minuto.
uname -a
dá:
Linux ab04 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux
distribuição Linux éRed Hat Enterprise Linux Server release 6.3 (Santiago)
Executamos alguns aplicativos da Web Java sob carga bastante pesada nas máquinas, pense em 100 solicitações/s por máquina.
Se eu interpretar corretamente os dados de utilização da CPU, quando tivermos 75% de utilização da CPU, isso significa que nossas CPUs estão executando um processo 75% do tempo, em média. No entanto, se nossas CPUs estiverem ocupadas 75% do tempo, não deveríamos ver uma média de carga mais alta? Como as CPUs podem estar 75% ocupadas enquanto temos apenas 2 a 4 tarefas na fila de execução?
Estamos interpretando nossos dados corretamente? O que pode causar esse comportamento?
Pelo menos no Linux, a média de carga e a utilização da CPU são, na verdade, duas coisas diferentes. A média de carga é uma medida de quantas tarefas estão esperando em uma fila de execução do kernel (não apenas o tempo da CPU, mas também a atividade do disco) durante um período de tempo. A utilização da CPU é uma medida de quão ocupada a CPU está agora. A maior carga que um único encadeamento de CPU fixado em 100% por um minuto pode "contribuir" para a média de carga de 1 minuto é 1. Uma CPU de 4 núcleos com hyperthreading (8 núcleos virtuais) em 100% por 1 minuto contribuiria com 8 para a média de carga de 1 minuto.
Muitas vezes, esses dois números têm padrões que se correlacionam, mas você não pode pensar neles como iguais. Você pode ter uma carga alta com quase 0% de utilização da CPU (como quando você tem muitos dados de E/S presos em um estado de espera) e pode ter uma carga de 1 e 100% da CPU, quando você tem um único processo encadeado em execução inclinação total. Além disso, por curtos períodos de tempo, você pode ver a CPU próxima a 100%, mas a carga ainda está abaixo de 1 porque as métricas médias ainda não foram "alcançadas".
Eu vi um servidor com uma carga de mais de 15.000 (sim, realmente não é um erro de digitação) e uma % de CPU próxima a 0%. Isso aconteceu porque um compartilhamento do Samba estava tendo problemas e muitos e muitos clientes começaram a ficar presos em um estado de espera de E/S. As chances são de que, se você estiver vendo um número alto de carregamento regular sem nenhuma atividade de CPU correspondente, você está tendo algum tipo de problema de armazenamento. Em máquinas virtuais, isso também pode significar que existem outras VMs competindo fortemente por recursos de armazenamento no mesmo host de VM.
A carga alta também não é necessariamente uma coisa ruim, na maioria das vezes significa apenas que o sistema está sendo utilizado em sua capacidade máxima ou talvez esteja além de sua capacidade de acompanhar (se o número de carga for maior que o número de núcleos do processador). Em um lugar onde eu era administrador de sistema, eles tinham alguém que observava a média de carga em seu sistema primário mais de perto do que o Nagios. Quando a carga estava alta, eles me ligavam 24 horas por dia, 7 dias por semana, mais rápido do que você poderia dizer SMTP. Na maioria das vezes, nada estava realmente errado, mas eles associavam o número da carga a algo errado e observavam como um falcão. Após a verificação, minha resposta geralmente era que o sistema estava apenas fazendo seu trabalho. Claro que este foi o mesmo lugar onde a carga subiu para mais de 15.000 (embora não seja o mesmo servidor), então às vezes isso significa que algo está errado. Você tem que considerar o propósito do seu sistema. Se for um burro de carga, espere que a carga seja naturalmente alta.
Carga é um número muito enganador. Leve-o com um grão de sal.
Se você gerar muitas tarefas em uma sucessão muito rápida que são concluídas muito rapidamente, o número de processos na fila de execução é muito pequeno para registrar a carga para eles (o kernel conta a carga uma vez a cada cinco segundos).
Considere este exemplo, em meu host que possui 8 núcleos lógicos, este script python registrará um grande uso de CPU no topo (cerca de 85%), mas quase nenhuma carga.
Outra implementação, esta evita
wait
em grupos de 8 (o que distorceria o teste). Aqui, o pai sempre tenta manter o número de filhos no número de CPUs ativas, de modo que seja muito mais ocupado do que o primeiro método e, com sorte, mais preciso.A razão para esse comportamento é que o algoritmo gasta mais tempo criando processos filhos do que executando a tarefa real (contando até 10.000). Tarefas ainda não criadas não podem contar para o estado 'executável', mas ocuparão %sys em tempo de CPU à medida que forem geradas.
Portanto, a resposta pode realmente estar no seu caso: qualquer trabalho que esteja sendo feito gera um grande número de tarefas em rápida sucessão (threads ou processos).
Se a média de carga não aumentar muito, isso significa apenas que suas especificações de hardware e a natureza das tarefas a serem processadas resultam em um bom rendimento geral, evitando que elas fiquem empilhadas na fila de tarefas por algum tempo.
Se houvesse um fenômeno de contenção porque, por exemplo, a complexidade média da tarefa é muito alta ou o tempo médio de processamento da tarefa leva muitos ciclos de CPU, então sim, a média de carga aumentaria.
ATUALIZAR :
Pode não estar claro na minha resposta original, então estou esclarecendo agora:
A fórmula exata de cálculo da carga média é:
loadvg = tasks running + tasks waiting (for cores) + tasks blocked
.Você pode definitivamente ter um bom rendimento e chegar perto de uma média de carga de 24, mas sem penalizar o tempo de processamento das tarefas. Por outro lado, você também pode ter 2-4 tarefas periódicas que não são concluídas com rapidez suficiente, então você verá o número de tarefas em espera (para ciclos de CPU) crescendo e, eventualmente, atingirá uma alta média de carga. Outra coisa que pode acontecer é ter tarefas executando operações de E/S síncronas pendentes e, em seguida, bloqueando um núcleo, diminuindo a taxa de transferência e fazendo com que a fila de tarefas em espera cresça (nesse caso, você pode ver a
iowait
mudança da métrica)Embora a resposta de Matthew Ife tenha sido muito útil e nos levado na direção certa, não foi exatamente o que causou o comportamento em nosso caso. No nosso caso, temos um aplicativo Java multiencadeado que usa pool de encadeamentos, por isso nenhum trabalho é feito na criação das tarefas reais.
No entanto, o trabalho real que os threads fazem é de curta duração e inclui esperas de E/S ou esperas de sincronização. Como Matthew menciona em sua resposta, a média de carga é amostrada pelo sistema operacional, portanto, tarefas de curta duração podem ser perdidas.
Eu fiz um programa Java que reproduziu o comportamento. A classe Java a seguir gera uma utilização de CPU de 28% (650% empilhada) em um de nossos servidores. Ao fazer isso, a média de carga é de cerca de 1,3. A chave aqui é o sleep() dentro do thread, sem ele o cálculo da carga está correto.
Para resumir, a teoria é que os encadeamentos em nossos aplicativos ficam muito ociosos e, em seguida, executam um trabalho de curta duração, por isso as tarefas não são amostradas corretamente pelo cálculo da média de carga.
A média de carga inclui tarefas que estão bloqueadas no disco IO, para que você possa facilmente ter utilização de CPU zero e uma média de carga de 10 apenas por ter 10 tarefas tentando ler de um disco muito lento. Assim, é comum que um servidor ocupado comece a debulhar o disco e toda a procura causa muitas tarefas bloqueadas, aumentando a média de carga, enquanto o uso da CPU cai, já que todas as tarefas estão bloqueadas no disco.
A média de carga é o número médio de processos na fila da CPU. É específico de cada sistema, não dá para dizer que um LA é genericamente alto em todos os sistemas e outro é baixo. Então você tem 12 núcleos, e para LA aumentar significativamente o número de processos deve ser muito alto.
Outra questão é o que significa o gráfico "CPU Usage". Se for retirado do SNMP, como deveria ser, e sua implementação do SNMP for
net-snmp
, então apenas empilha a carga da CPU de cada uma das 12 CPUs. Portanto,net-snmp
a quantidade total de carga da CPU é de 1200%.Se minhas suposições estiverem corretas, o uso da CPU não aumentou significativamente. Assim, LA não aumentou significativamente.
O cenário aqui não é particularmente inesperado, embora seja um pouco incomum. O que Xavier aborda, mas não desenvolve muito, é que, embora o Linux (por padrão) e a maioria dos tipos de Unix implementem multitarefa preventiva, em uma máquina saudável, as tarefas raramente serão antecipadas. Cada tarefa recebe uma fatia de tempo para ocupar a CPU, ela só é antecipada se exceder esse tempo e houver outras tarefas aguardando para serem executadas (observe que load informa o número médio de processos na CPU e aguardando para executar) . Na maioria das vezes, um processo cederá em vez de ser interrompido.
(em geral, você só precisa se preocupar com a carga quando ela se aproxima do número de CPUs - ou seja, quando o escalonador começa a antecipar tarefas).
É tudo sobre o padrão de atividade, claramente o aumento da utilização da CPU por algumas tarefas (provavelmente uma pequena minoria) não estava tendo um efeito adverso no processamento de outras tarefas. Se você pudesse isolar as transações sendo processadas, eu esperaria que você visse um novo grupo surgindo durante a desaceleração, enquanto o conjunto de tarefas existente não foi afetado.
atualizar
Um cenário comum em que a alta CPU pode ocorrer sem um grande aumento na carga é quando uma tarefa aciona uma (ou uma sequência) de outras tarefas, por exemplo, ao receber uma solicitação de rede, o manipulador encaminha a solicitação para um thread separado, o thread separado em seguida, faz algumas chamadas assíncronas para outros processos .... a amostragem do runqueue faz com que a carga relatada seja menor do que realmente é - mas não aumenta linearmente com o uso da CPU - a cadeia de tarefas triggerred não teria sido executada sem o evento inicial, e por ocorrerem (mais ou menos) sequencialmente a fila de execução não é inflada.
Antes de tudo, a resposta curta para a pergunta: é óbvio que das 12h às 12h05 os processos que eram processados pela CPU demoravam mais para serem processados do que antes.
Das 11h às 11h55, todos os processos do sistema operacional levaram 25ms (por exemplo) de tempo de CPU.
Das 12h00 às 12h05 cada processo do SO levou 75ms.
É por isso que a média de carga não mudou, mas o uso da CPU mudou muito.
A resposta longa: o uso da CPU e a média de carga descrevem o estado de duas criaturas muito diferentes.
O uso da CPU descreve a integridade da CPU
Média de carga não tem nada em comum com CPU.
Portanto, é bastante inapropriado quando a média de carga é usada para descobrir a ocupação ou ociosidade de uma CPU.
É como tentar descobrir quanto dinheiro uma pessoa ganha por meio da previsão do tempo.
A média de carga descreve os processos no sistema operacional Linux, não o estado da CPU
O uso da CPU descreve quanto tempo a CPU estava fazendo algo em vez de não fazer nada durante algum período de tempo, digamos para simplificar por 1 segundo.
Se o uso da CPU = 85% significa que 85ms a CPU estava ocupada e 15ms estava ociosa. É isso.
O uso da CPU é bastante semelhante à característica de tempo ocupado do HDD.
Média de carga = 125 por 1 segundo significa que 125 processos foram processados pela CPU ou aguardados para serem processados ou aguardados pelo sistema de disco rígido.
É complicado, então é fácil entender o ponto de pensar que 125 processos foram processados pela CPU. o ponto é que não sabemos quanto tempo cada processo estava rodando na CPU. nós apenas sabemos que eles estavam funcionando por algum tempo desconhecido.
Portanto, na minha opinião, a média de carga causa muita confusão e dano quando tentamos entender o desempenho, em vez de fazer algo útil.
Quando olhamos para o gráfico inicial, podemos ver que não há correlação entre o uso da CPU e a carga média durante todo o período de tempo. É como tentar encontrar a correlação entre a previsão do tempo e a cor da sua xícara de chá.