Alto carico medio, basso utilizzo della CPU - perché?


78

Stiamo riscontrando enormi problemi di prestazioni in un'applicazione Web e stiamo cercando di trovare il collo di bottiglia. Non sono un amministratore di sistema, quindi ci sono alcune cose che non riesco a capire. Alcune indagini di base mostrano che la CPU è inattiva, molta memoria disponibile, nessuno scambio, nessun I / O, ma un carico medio elevato.

Lo stack di software su questo server è simile al seguente:

  • Solaris 10
  • Java 1.6
  • WebLogic 10.3.5 (8 domini)

Le applicazioni in esecuzione su questo server parlano con un database Oracle su un altro server.

Questo server ha 32 GB di RAM e 10 CPU (credo).

Correre prstat -Zdà qualcosa del genere:

   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

Capisco che la CPU è principalmente inattiva, ma la media del carico è alta, il che è abbastanza strano per me. La memoria non sembra essere un problema.

Correre vmstat 15dà qualcosa del genere:

 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

Capisco che la CPU è principalmente inattiva, nessun processo è in attesa di essere eseguito in coda, sta avvenendo poco scambio.

La corsa iostat 15dà questo:

   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

L'esecuzione netstat -i 15dà quanto segue:

    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

Cosa mi sto perdendo?


Non sono a casa con Solaris, quindi rimanderò a qualcun altro per questo, ma inizierei a guardare la configurazione del tuo server web. Forse qualcosa sta cancellando artificialmente le prestazioni in modo da lasciare molti thread nella coda di esecuzione. (Non sono sicuro di cosa potrebbe essere o anche se è possibile, però). Complimenti per una domanda ben scritta, però.
SmallClanger,

4
10 CPU (penso) è forse il problema. Dovresti sapere più precisamente quale hardware stai eseguendo prima di indagare ulteriormente. Utilizzare psrinfo -vper visualizzare il numero effettivo di CPU.
jlliagre,

Non ho mai sentito parlare di questo comando, ma durante l'esecuzione sembra che ci siano circa 250 processori virtuali. Ha senso? In tal caso, una media di carico di 50 sarebbe insignificante?
Spiff

Penso che ciò possa accadere anche quando il disco è pieno. L'ho avuto oggi con l'1% di spazio libero attivo /e il carico ha continuato ad aumentare fino 19.00alla fine senza motivo visibile. Rendere un po 'di spazio libero ha risolto il problema (poco dopo che è venuto giù); può anche essere una coincidenza però.
nh2

Risposte:


40

Con qualche ulteriore indagine, sembra che il problema delle prestazioni sia principalmente dovuto a un elevato numero di chiamate di rete tra due sistemi (Oracle SSXA e UCM). Le chiamate sono veloci ma abbondanti e serializzate, quindi il basso utilizzo della CPU (principalmente in attesa di I / O), la media del carico elevato (molte chiamate in attesa di essere elaborate) e soprattutto i tempi di risposta lunghi (accumulando piccoli tempi di risposta).

Grazie per la tua comprensione di questo problema!


4
come hai confermato e capito? Stiamo riscontrando lo stesso problema e vorremmo verificare se abbiamo lo stesso problema
hobgoblin

32

Quando dici "Media del carico elevato" presumo che intendi che prstat mostra "Media del carico" nella parte inferiore delle cifre di output di

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

Questi numeri sembrano simili a quelli forniti da top e probabilmente indicano la dimensione media della coda del processo in esecuzione. Questa non è la percentuale di tempo del processore utilizzata, ma quante "cose" stanno molestando la CPU perché il tempo funzioni. Certo, questi sembrano piuttosto alti ma tutto dipende dall'app che stai utilizzando; i processi potrebbero in realtà non fare molto quando ottengono il loro slot. Vedi qui per una bella spiegazione riguardo a top.

Non ho familiarità con WebLogic ma ho notato che, in genere, con Apache Tomcat è possibile generare contemporaneamente molti thread Java per quelle che sembrano non molte richieste. Potrebbe essere questo a causare quei numeri di carico medio elevato. Assicurati di utilizzare il pool di connessioni, se del caso, per connetterti al back-end e considera di aumentare il numero di thread inattivi disponibili per la tua app per gestire le connessioni (non sei sicuro di come lo fai su WebLogic; Tomcat ha un pool di thread per connettore o un pool di thread dell'esecutore generale). In caso contrario, potrebbero essere generati nuovi thread per elaborare le richieste.

Per quanto riguarda le prestazioni, devi definire quale parte della tua app sta soffrendo. È l'elaborazione che sta avvenendo nel lato WebLogic / Java delle cose, l'accesso al database, le ricerche DNS (se vengono eseguite per qualche motivo ...), problemi di rete o qualcosa sul sistema operativo.

Il 99% delle volte sarà il tuo codice e il modo in cui comunica con il database che sta trattenendo le cose. Quindi sarà la configurazione dell'app Web. Passato questo punto, lavorerai per spremere gli ultimi millisecondi dalla tua app o per cercare di offrire una maggiore concorrenza con lo stesso hardware. Per questa regolazione delle prestazioni granulosa più fine sono necessarie metriche.

Per Java suggerirei di installare Java Melody . Può fornire molte informazioni su ciò che sta facendo il tuo programma e aiutare a restringere il tempo impiegato. L'ho usato solo con Tomcat, ma dovrebbe funzionare benissimo con qualsiasi contenitore / servlet Java EE.

Esistono diversi modi per ottimizzare Java, quindi dai un'occhiata alle loro linee guida sulle prestazioni (sono sicuro che probabilmente lo hai fatto) e assicurati di impostare la dimensione heap corretta ecc. Adatta al tuo programma. Java Melody può aiutarti a rintracciare le dimensioni dell'heap di Java che stai consumando, nonché la potenza del garbage collector / la frequenza con cui interrompe il programma per cancellare gli oggetti.

Spero sia stato utile. Se fornisci ulteriori informazioni, potrei essere in grado di aggiornare questa risposta e perfezionarla in base alle tue esigenze.


1
Grazie per la tua risposta, se il mio rappresentante fosse abbastanza alto lo voterei. In base alla mia esperienza, il codice o le query SQL sono in genere i colpevoli. Ho fatto alcune prove di profilazione e non sono riuscito a trovare alcun punto caldo, motivo per cui ho iniziato a guardare a fattori più fondamentali. Investigherò un po 'di più e aggiornerò la domanda man mano che troverò di più.
Spiff

4
Vorrei anche controllare l'output di 'mpstat 1 5' per visualizzare le statistiche per processore e guardare le colonne "csw" e "syscl". Dal tuo vmstat sopra sembra che tu stia facendo un sacco di chiamate di sistema e cambi di contesto, il che sembrerebbe convalidare il sospetto di webtoe che tu abbia molti thread (Solaris li chiama LWPs-LightWeight Processes) molestando costantemente la CPU. Nessuno di loro sta facendo molto quando è in esecuzione, ma molti trascorrono del tempo in attesa di esecuzione, quindi le medie di carico elevato.
eirescot

25

Come nota a margine, il carico medio include anche le cose in attesa di attività del disco (cioè molestare il disco) così come quelle in attesa di CPU, è una somma di entrambi ... quindi potresti avere problemi nell'uno o nell'altro.

Vedi http://en.wikipedia.org/wiki/Load_(computing) "Linux include anche [nella sua media di carico] processi in stati di sonno ininterrotti (di solito in attesa di attività del disco)"

Come nota a margine, il problema particolare che ho riscontrato è che avevo un elevato carico medio, ma anche un sacco di CPU inattiva e un basso utilizzo del disco.

Sembra che, almeno nel mio caso, a volte i thread / processi in attesa di I / O vengano visualizzati nella media del carico, ma non causino un aumento della colonna "wait". Ma sono ancora associati all'I / O.

Puoi dire che questo è il caso con il seguente codice, se lo esegui in jruby (fa solo 100 thread con molti I / O ciascuno):

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

Che dà un risultato superiore come questo:

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

Quindi puoi vedere che ha un sacco di CPU inattiva, 0,0% wa, ma una media di carico molto alta.

allo stesso modo iostat mostra il disco come sostanzialmente inattivo:

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

vedi anche http://linuxgazette.net/141/misc/lg/tracking_load_average_issues.html

Come ulteriore nota a margine, ciò implica anche che (almeno in questo caso - con CentOS in esecuzione) la media del carico include ogni thread separatamente nel totale.


2
"load average include anche cose in attesa di attività del disco" su Linux , mentre questa domanda era originariamente su Solaris, che sembra includere solo le attività in esecuzione e eseguibili (ovvero in attesa di CPU) nella media del carico . Una versione Linux di questa domanda è questa .
Nickolay,

7

Ho avuto lo stesso problema oggi. Dopo alcune ricerche e diagnosi mi sono reso conto che il mio piccolo VPS stava esaurendo il disco .

In shell / prompt (Linux / Unix) digitare

df -h

per vedere il disco libero sul tuo computer. Se stai esaurendo il disco, questo può essere il problema / problema.


mi scambiavi allora, presumo, quindi questo lo stava causando?
rogerdpack,

4

Un altro strumento utile che aiuterà in questa situazione è normale.

Include una varietà di modi per visualizzare gli stessi dati presentati dagli altri strumenti, in un piccolo pacchetto.

Se si tratta di contenuto che non può essere memorizzato nella cache, consiglierei di posizionare più server dietro un bilanciamento del carico come haproxy in modalità tcp per distribuire il carico.


2

Solo per aggiungere a ciò, alcuni strumenti specifici di Solaris che non sono stati menzionati e che sono utili nel debug di tali problemi sono "intrstat", "mpstat" e "lockstat". Avendo riscontrato un problema simile in precedenza su un host che eseguiva pesanti carichi ETL, mpstat ha rivelato un'elevata quantità di interruzioni che si occupano di un sacco di I / O che hanno suggerito il problema.

All'epoca, su un T4-4 con mpstat abbiamo visto vcpus consegnare oltre 30000 interruzioni nel breve ciclo di monitoraggio, dopo di che le prestazioni hanno iniziato a risentirne. In questo caso, l'unica soluzione consisteva nel lanciare più CPU, tuttavia il lavoro veniva successivamente svolto per migliorare il codice.

Brendan Gregg ha scritto molto sulle prestazioni, in particolare sull'I / O nel corso degli anni e merita una ricerca se vuoi saperne di più.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.