Média de carga alta, baixo uso da CPU - por quê?

78

Estamos vendo enormes problemas de desempenho em um aplicativo Web e estamos tentando encontrar o gargalo. Eu não sou um administrador de sistemas, então há algumas coisas que não entendo direito. Algumas investigações básicas mostram que a CPU está ociosa, muita memória disponível, sem troca, sem E / S, mas com uma carga média alta.

A pilha de software neste servidor tem a seguinte aparência:

  • Solaris 10
  • Java 1.6
  • WebLogic 10.3.5 (8 domínios)

Os aplicativos em execução neste servidor conversam com um banco de dados Oracle em um servidor diferente.

Este servidor tem 32 GB de RAM e 10 CPUs (eu acho).

Correr prstat -Zdá algo assim:

   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
  3836 ducm0101 2119M 2074M cpu348  58    0   8:41:56 0.5% java/225
 24196 ducm0101 1974M 1910M sleep   59    0   4:04:33 0.4% java/209
  6765 ducm0102 1580M 1513M cpu330   1    0   1:21:48 0.1% java/291
 16922 ducm0102 2115M 1961M sleep   58    0   6:37:08 0.0% java/193
 18048 root     3048K 2440K sleep   59    0   0:06:02 0.0% sa_comm/4
 26619 ducm0101 2588M 2368M sleep   59    0   8:21:17 0.0% java/231
 19904 ducm0104 1713M 1390M sleep   59    0   1:15:29 0.0% java/151
 27809 ducm0102 1547M 1426M sleep   59    0   0:38:19 0.0% java/186
  2409 root       15M   11M sleep   59    0   0:00:00 0.0% pkgserv/3
 27204 root       58M   54M sleep   59    0   9:11:38 0.0% stat_daemon/1
 27256 root       12M 8312K sleep   59    0   7:16:40 0.0% kux_vmstat/1
 29367 root      297M  286M sleep   59    0  11:02:13 0.0% dsmc/2
 22128 root       13M 6768K sleep   59    0   0:10:51 0.0% sendmail/1
 22133 smmsp      13M 1144K sleep   59    0   0:01:22 0.0% sendmail/1
 22003 root     5896K  240K sleep   59    0   0:00:01 0.0% automountd/2
 22074 root     4776K 1992K sleep   59    0   0:00:19 0.0% sshd/1
 22005 root     6184K 2728K sleep   59    0   0:00:31 0.0% automountd/2
 27201 root     6248K  344K sleep   59    0   0:00:01 0.0% mount_stat/1
 20964 root     2912K  160K sleep   59    0   0:00:01 0.0% ttymon/1
 20947 root     1784K  864K sleep   59    0   0:02:22 0.0% utmpd/1
 20900 root     3048K  608K sleep   59    0   0:00:03 0.0% ttymon/1
 20979 root       77M   18M sleep   59    0   0:14:13 0.0% inetd/4
 20849 daemon   2856K  864K sleep   59    0   0:00:03 0.0% lockd/2
 17794 root       80M 1232K sleep   59    0   0:06:19 0.0% svc.startd/12
 17645 root     3080K  728K sleep   59    0   0:00:12 0.0% init/1
 17849 root       13M 6800K sleep   59    0   0:13:04 0.0% svc.configd/15
 20213 root       84M   81M sleep   59    0   0:47:17 0.0% nscd/46
 20871 root     2568K  600K sleep   59    0   0:00:04 0.0% sac/1
  3683 ducm0101 1904K 1640K sleep   56    0   0:00:00 0.0% startWebLogic.s/1
 23937 ducm0101 1904K 1640K sleep   59    0   0:00:00 0.0% startWebLogic.s/1
 20766 daemon   5328K 1536K sleep   59    0   0:00:36 0.0% nfsmapid/3
 20141 daemon   5968K 3520K sleep   59    0   0:01:14 0.0% kcfd/4
 20093 ducm0101 2000K  376K sleep   59    0   0:00:01 0.0% pfksh/1
 20797 daemon   3256K  240K sleep   59    0   0:00:01 0.0% statd/1
  6181 root     4864K 2872K sleep   59    0   0:01:34 0.0% syslogd/17
  7220 ducm0104 1268M 1101M sleep   59    0   0:36:35 0.0% java/138
 27597 ducm0102 1904K 1640K sleep   59    0   0:00:00 0.0% startWebLogic.s/1
 27867 root       37M 4568K sleep   59    0   0:13:56 0.0% kcawd/7
 12685 ducm0101 4080K  208K sleep   59    0   0:00:01 0.0% vncconfig/1
ZONEID    NPROC  SWAP   RSS MEMORY      TIME  CPU ZONE
    42      135   22G   19G    59%  87:27:59 1.2% dsuniucm01

Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11

Entendo que a CPU está praticamente ociosa, mas a média de carga é alta, o que é bastante estranho para mim. A memória não parece ser um problema.

Correr vmstat 15dá algo assim:

 kthr      memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr s0 s1 s4 sd   in   sy   cs us sy id
 0 0 0 32531400 105702272 317 1052 126 0 0 0 0 13 13 -0 8 9602 107680 10964 1 1 98
 0 0 0 15053368 95930224 411 2323 0 0 0 0 0 0  0  0  0 23207 47679 29958 3 2 95
 0 0 0 14498568 95801960 3072 3583 0 2 2 0 0 3 3  0 21 22648 66367 28587 4 4 92
 0 0 0 14343008 95656752 3080 2857 0 0 0 0 0 3 3  0 18 22338 44374 29085 3 4 94
 0 0 0 14646016 95485472 1726 3306 0 0 0 0 0 0 0  0  0 24702 47499 33034 3 3 94

Entendo que a CPU está ociosa, não há processos aguardando na fila para serem executados, pouca troca está acontecendo.

A corrida iostat 15oferece isso:

   tty        sd0           sd1           sd4           ssd0           cpu
 tin tout kps tps serv  kps tps serv  kps tps serv  kps tps serv   us sy wt id
   0  676 324  13    8  322  13    8    0   0    0  159   8    0    1  1  0 98
   1 1385   0   0    0    0   0    0    0   0    0    0   0    0    3  4  0 94
   0  584  89   6   24   89   6   25    0   0    0  332  19    0    2  1  0 97
   0  296   0   0    0    0   0    0    0   0    0    0   0    0    2  2  0 97
   1 1290  43   5   24   43   5   22    0   0    0  297  20    1    3  3  0 94

A corrida netstat -i 15fornece o seguinte:

    input   aggr26    output       input  (Total)    output
packets errs  packets errs  colls  packets errs  packets errs  colls
1500233798 0     1489316495 0     0      3608008314 0     3586173708 0     0
10646   0     10234   0     0      26206   0     25382   0     0
11227   0     10670   0     0      28562   0     27448   0     0
10353   0     9998    0     0      29117   0     28418   0     0
11443   0     12003   0     0      30385   0     31494   0     0

o que estou perdendo?

Spiff
fonte
Não estou em casa com o Solaris, por isso vou adiar outra pessoa por isso, mas começaria a olhar para a configuração do servidor da web. Talvez algo esteja afetando artificialmente o desempenho de maneira a deixar muitos encadeamentos na fila de execução. (Não tenho certeza do que poderia ser ou mesmo se é possível). Parabéns por uma pergunta bem escrita, no entanto.
SmallClanger
4
10 CPUs (eu acho) é possivelmente o problema. Você deve saber com mais precisão qual hardware está executando antes de investigar mais. Use psrinfo -vpara exibir o número real de CPUs.
Jlliagre #
Nunca ouvi falar desse comando, mas ao executá-lo, parece que existem cerca de 250 processadores virtuais. Isso faz algum sentido? Nesse caso, uma carga média de 50 seria insignificante?
Spiff
Eu acho que isso também pode acontecer quando seu disco está cheio. Eu tive isso hoje com 1% de espaço livre /e a carga continuou aumentando até terminar 19.00sem motivo visível. Liberar um pouco de espaço resolveu o problema (logo depois que ele desceu); também pode ser uma coincidência.
nh2 19/03/16

Respostas:

40

Com alguma investigação adicional, parece que o problema de desempenho se deve principalmente a um grande número de chamadas de rede entre dois sistemas (Oracle SSXA e UCM). As chamadas são rápidas, mas abundantes e serializadas, daí o baixo uso da CPU (principalmente aguardando E / S), a alta média de carga (muitas chamadas aguardando processamento) e, especialmente, os longos tempos de resposta (por acúmulo de pequenos tempos de resposta).

Obrigado pela sua compreensão sobre este problema!

Spiff
fonte
4
como você confirmou e descobriu isso? Estamos vendo o mesmo problema e gostaríamos de verificar se temos o mesmo problema
hobgoblin
32

Quando você diz 'Média de carga alta', presumo que você queira dizer que o prstat mostra 'carga média' na parte inferior dos números de saída de

Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11

Esses números são parecidos com os que mais fornecem e provavelmente significam o tamanho médio da fila do processo em execução. Essa não é a porcentagem de tempo do processador em uso, mas quantas 'coisas' estão assediando a CPU durante o tempo de execução. É certo que eles parecem bastante altos, mas tudo depende do aplicativo que você está executando; os processos podem não estar realizando muito assim que obtêm seu slot. Veja aqui uma boa explicação sobre o topo.

Não estou familiarizado com o WebLogic, mas notei que, geralmente, com o Apache Tomcat, muitos threads Java podem ser gerados simultaneamente para o que parece não haver muitos pedidos. Pode ser isso que está causando esses altos números médios de carga. Verifique se você está usando o pool de conexões, quando apropriado, para conectar-se ao back-end e considere aumentar o número de threads ociosos disponíveis para o seu aplicativo para lidar com conexões (não saiba como fazer isso no WebLogic; o Tomcat possui um pool de threads por conector ou um conjunto de encadeamentos do executor geral). Se você não fizer isso, poderão ser gerados novos threads para processar solicitações.

Quanto ao desempenho, você precisa determinar qual parte do seu aplicativo está sofrendo. É o processamento que está acontecendo no lado WebLogic / Java, o acesso ao banco de dados, as pesquisas de DNS (se estiverem sendo feitas por algum motivo ...), problemas de rede ou algo no sistema operacional.

99% do tempo, será o seu código e como ele se comunica com o banco de dados que está atrasando as coisas. Em seguida, será a configuração do aplicativo Web. Após esse ponto, você estará trabalhando para extrair os últimos milissegundos do aplicativo ou procurando fornecer maior simultaneidade com o mesmo hardware. Para esse ajuste de desempenho mais refinado, você precisa de métricas.

Para Java, sugiro instalar o Java Melody . Ele pode fornecer muitas informações sobre o que seu programa está fazendo e ajudar a restringir onde está gastando tempo. Eu o usei apenas com o Tomcat, mas deve funcionar bem com qualquer coisa de contêiner / servlet Java EE.

Existem várias maneiras de ajustar o Java, portanto, dê uma olhada nas diretrizes de desempenho (tenho certeza que você provavelmente o possui) e verifique se está definindo o tamanho correto da pilha, etc. adequado para o seu programa. O Java Melody pode ajudá-lo a rastrear o tamanho da pilha de Java que você está consumindo, bem como a força do coletor de lixo trabalhando / com que frequência interrompe seu programa para limpar objetos.

Espero que tenha sido útil. Se você fornecer mais informações, talvez eu possa atualizar esta resposta e aprimorá-la mais para suas necessidades.

webtoe
fonte
1
Obrigado pela sua resposta, se meu representante fosse alto o suficiente, eu o votaria. Pela minha experiência, o código ou as consultas SQL geralmente são os culpados. Fiz algumas execuções de criação de perfil e não consegui encontrar nenhum ponto ativo, e foi por isso que comecei a examinar fatores mais fundamentais. Vou investigar um pouco mais e atualizar a pergunta à medida que descobrir mais.
Spiff
4
Eu também verificaria a saída do 'mpstat 1 5' para visualizar as estatísticas por processador e examinar as colunas "csw" e "syscl". A partir do vmstat acima, parece que você está fazendo muitas chamadas de sistema e alternâncias de contexto, o que parece validar a suspeita de que você tenha muitos threads (o Solaris os chama de LWPs-LightWeight Processes) constantemente assediando a CPU. Nenhum deles está fazendo muito quando está em execução, mas muitos estão gastando tempo esperando para executar, daí as médias de carga elevadas.
eirescot
25

Como observação lateral, a média de carga também inclui coisas que aguardam atividade do disco (ou seja, assediar o disco), bem como aqueles que aguardam a CPU, é uma soma de ambos ... portanto, você pode ter problemas em um ou outro.

Veja http://en.wikipedia.org/wiki/Load_(computing) "O Linux também inclui [na sua média de carga] processos em estados inativos ininterruptos (geralmente aguardando atividade do disco)"

Como uma observação lateral, o problema em particular que encontrei foi que eu tinha alta média de carga, mas também muita CPU ociosa e baixo uso de disco.

Parece que, pelo menos no meu caso, algumas vezes os threads / processos que aguardam E / S aparecem na média de carga, mas não causam um aumento na coluna "aguardar". Mas eles ainda estão vinculados à E / S.

Você pode dizer que esse é o caso do código a seguir, se você o executar no jruby (apenas 100 threads com muita E / S cada):

100.times { Thread.new { loop { File.open('big', 'w') do |f| f.seek 10_000_000_000; f.puts 'a'; end}}}

O que fornece uma saída superior como esta:

top - 17:45:32 up 38 days,  2:13,  3 users,  load average: 95.18, 50.29, 23.83
Tasks: 181 total,   1 running, 180 sleeping,   0 stopped,   0 zombie
Cpu(s):  3.5%us, 11.3%sy,  0.0%ni, 85.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32940904k total, 23239012k used,  9701892k free,   983644k buffers
Swap: 34989560k total,        0k used, 34989560k free,  5268548k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
31866 packrd    18   0 19.9g  12g  11m S 117.0 41.3   4:43.85 java
  912 root      11  -5     0    0    0 S  2.0  0.0   1:40.46 kjournald

Assim, você pode ver que ele possui muitos processadores ociosos, 0,0% wa, mas uma média de carga muito alta.

O iostat mostra o disco como basicamente ocioso:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
       9.62    0.00    8.75    0.00    0.00   81.62

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00    49.00  0.00  6.40     0.00   221.60    69.25     0.01    0.81   0.66   0.42
sda1              0.00    49.00  0.00  6.40     0.00   221.60    69.25     0.01    0.81   0.66   0.42
sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00

consulte também http://linuxgazette.net/141/misc/lg/tracking_load_average_issues.html

Como uma observação adicional, isso também parece implicar que (pelo menos neste caso - executando o CentOS) a média de carga inclui cada thread separadamente no total.

rogerdpack
fonte
2
"load average também inclui coisas que aguardam atividade do disco" no Linux , enquanto essa pergunta era originalmente sobre Solaris, que parece incluir apenas tarefas em execução e executáveis ​​(por exemplo, aguardando CPU) na média de carga . Uma versão Linux desta pergunta é essa .
Nickolay 12/09
7

Teve o mesmo problema hoje. Após algumas pesquisas e diagnósticos, percebi que meu pequeno VPS estava ficando sem disco .

No tipo shell / prompt (Linux / Unix)

df -h

para ver o disco livre em sua máquina. Se você estiver ficando sem disco, esse pode ser o problema / questão.

PJunior
fonte
você estava trocando, presumo, então isso estava causando isso?
Rogerdpack 19/07/2013
4

Outra ferramenta útil que ajudará nessa situação é o nmon.

Ele inclui várias maneiras de visualizar os mesmos dados apresentados pelas outras ferramentas, em um pequeno pacote.

Se este é um conteúdo que não pode ser armazenado em cache, recomendo colocar vários servidores atrás de um balanceador de carga, como haproxy no modo tcp, para distribuir a carga.

Daniel Baker
fonte
2

Apenas para adicionar isso, algumas ferramentas específicas do Solaris que não foram mencionadas e úteis na depuração de tais problemas são "intrstat", "mpstat" e "lockstat". Tendo experimentado um problema semelhante antes em um host executando algumas cargas pesadas de ETL, o mpstat revelou uma grande quantidade de interrupções ao lidar com muitas E / S, o que sugeria o problema.

Na época, em um T4-4 com mpstat, vimos vcpus entregando mais de 30000 interrupções em um curto ciclo de monitoramento, após o qual o desempenho começou a sofrer. Nesse caso, a única solução alternativa era lançar mais CPU nele, no entanto, o trabalho foi realizado posteriormente para melhorar o código.

Brendan Gregg escreveu muito sobre desempenho, principalmente sobre E / S ao longo dos anos e vale a pena pesquisar se você quiser descobrir mais.

Rowley
fonte