Alto promedio de carga, bajo uso de CPU, ¿por qué?

78

Estamos viendo grandes problemas de rendimiento en una aplicación web y estamos tratando de encontrar el cuello de botella. No soy un administrador de sistemas, así que hay algunas cosas que no entiendo. Algunas investigaciones básicas muestran que la CPU está inactiva, mucha memoria disponible, sin intercambio, sin E / S, pero con una carga promedio alta.

La pila de software en este servidor se ve así:

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

Las aplicaciones que se ejecutan en este servidor hablan con una base de datos Oracle en un servidor diferente.

Este servidor tiene 32 GB de RAM y 10 CPU (creo).

Correr prstat -Zda algo como esto:

   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

Entiendo que la CPU está inactiva en su mayoría, pero el promedio de carga es alto, lo cual es bastante extraño para mí. La memoria no parece ser un problema.

Correr vmstat 15da algo como esto:

 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

Entiendo que la CPU está inactiva en su mayoría, no hay procesos esperando en la cola para ejecutarse, está ocurriendo un pequeño intercambio.

Correr iostat 15da esto:

   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

Correr netstat -i 15da lo siguiente:

    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

¿Qué me estoy perdiendo?

Spiff
fuente
No estoy en casa con Solaris, así que me referiré a otra persona para esto, pero comenzaría a mirar la configuración de su servidor web. Tal vez algo es el rendimiento artificial de manera tal que deja muchos hilos en la cola de ejecución. (Sin embargo, no estoy seguro de qué podría ser o incluso si es posible). Felicitaciones por una pregunta bien escrita, sin embargo.
SmallClanger
44
10 CPU (creo) es posiblemente el problema. Debe saber con mayor precisión qué hardware está ejecutando antes de investigar más a fondo. Se usa psrinfo -vpara mostrar el número real de CPU.
jlliagre
Nunca he oído hablar de este comando, pero cuando lo ejecuto parece que hay alrededor de 250 procesadores virtuales. ¿Eso tiene sentido? En ese caso, una carga promedio de 50 sería insignificante?
Spiff
Creo que esto también puede suceder cuando su disco está lleno. Hoy tuve esto con un 1% de espacio libre /y la carga siguió aumentando hasta que terminó 19.00sin ninguna razón visible. Hacer un poco de espacio libre resolvió el problema (poco después de que se redujera); Sin embargo, también puede ser una coincidencia.
nh2

Respuestas:

40

Con un poco más de investigación, parece que el problema de rendimiento se debe principalmente a una gran cantidad de llamadas de red entre dos sistemas (Oracle SSXA y UCM). Las llamadas son rápidas pero abundantes y serializadas, de ahí el bajo uso de CPU (principalmente esperando E / S), el alto promedio de carga (muchas llamadas en espera de ser procesadas) y especialmente los largos tiempos de respuesta (por acumulación de pequeños tiempos de respuesta).

¡Gracias por su comprensión de este problema!

Spiff
fuente
44
¿Cómo confirmaste y descubriste esto? Estamos viendo el mismo problema y nos gustaría comprobar si tenemos el mismo problema
hobgoblin
32

Cuando dice 'Promedio de carga alta', supongo que quiere decir que prstat se muestra para 'promedio de carga' en la parte inferior de las cifras de salida de

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

Estos números, son similares a los que proporciona Top y probablemente significan el tamaño promedio de la cola del proceso en ejecución. Este no es el porcentaje de tiempo de procesador utilizado, sino cuántas 'cosas' están acosando a la CPU por el tiempo de ejecución. Es cierto que estos parecen bastante altos, pero todo depende de la aplicación que esté ejecutando; los procesos pueden no estar haciendo mucho una vez que obtienen su ranura. Vea aquí para una buena explicación con respecto a la parte superior.

No estoy familiarizado con WebLogic, pero he notado que, en general, con Apache Tomcat se pueden generar muchos hilos Java simultáneamente para lo que parece que no hay muchas solicitudes. Podría ser esto lo que está causando esos altos números de carga promedio. Asegúrese de que está utilizando la agrupación de conexiones cuando sea apropiado para conectarse al backend y considere aumentar la cantidad de subprocesos inactivos que están disponibles para que su aplicación maneje las conexiones (no estoy seguro de cómo hacerlo en WebLogic; Tomcat tiene una agrupación de subprocesos por conector o un grupo de subprocesos de ejecutor general). Si no hace esto, se pueden generar nuevos hilos para procesar las solicitudes.

En cuanto al rendimiento, debe precisar qué parte de su aplicación está sufriendo. ¿Es el procesamiento lo que está sucediendo en el lado de WebLogic / Java, el acceso a la base de datos, las búsquedas de DNS (si se realizan por alguna razón ...), problemas de red o algo en el sistema operativo.

El 99% del tiempo será su código y cómo se comunica con la base de datos que está reteniendo las cosas. Luego será la configuración de la aplicación web. Pasado este punto, trabajará para exprimir los últimos milisegundos de su aplicación o buscará proporcionar una mayor concurrencia con el mismo hardware. Para este ajuste de rendimiento más fino, necesita métricas.

Para Java, sugeriría instalar Java Melody . Puede proporcionar mucha información sobre lo que está haciendo su programa y ayudar a reducir dónde está pasando el tiempo. Solo lo he usado con Tomcat, pero debería funcionar bien con cualquier cosa de contenedor / servlet Java EE.

Hay varias formas de ajustar Java, así que eche un vistazo a sus pautas de rendimiento (estoy seguro de que probablemente lo haya hecho) y asegúrese de establecer el tamaño correcto de almacenamiento dinámico, etc. adecuado para su programa. Java Melody puede ayudarlo a rastrear el tamaño del montón de Java que está consumiendo, así como qué tan duro está trabajando el recolector de basura / con qué frecuencia está interrumpiendo su programa para limpiar objetos.

Espero que te haya sido útil. Si proporciona más información, puedo actualizar esta respuesta y perfeccionarla más según sus necesidades.

Webtoe
fuente
1
Gracias por su respuesta, si mi representante fuera lo suficientemente alto, lo votaría. Desde mi experiencia, el código o las consultas SQL suelen ser los culpables. Hice algunas ejecuciones de creación de perfiles y no pude encontrar ningún punto caliente, por eso comencé a buscar factores más fundamentales. Investigaré un poco más y actualizaré la pregunta a medida que encuentre más.
Spiff
44
También verificaría la salida de 'mpstat 1 5' para ver las estadísticas por procesador y mirar las columnas "csw" y "syscl". Desde su vmstat anterior, parece que está haciendo muchas llamadas al sistema y cambios de contexto, lo que parece validar la sospecha de webtoe de que tiene muchos hilos (Solaris los llama Procesos LWP-LightWeight) constantemente acosando a la CPU. Ninguno de ellos está haciendo mucho cuando están corriendo, pero muchos pasan tiempo esperando para correr, de ahí los altos promedios de carga.
eirescot
25

Como nota al margen, el promedio de carga también incluye cosas que esperan la actividad del disco (es decir, hostigar el disco), así como las que esperan la CPU, es una suma de ambos ... por lo que puede tener problemas en uno u otro.

Consulte http://en.wikipedia.org/wiki/Load_(computing) "Linux también incluye [en su promedio de carga] procesos en estados de suspensión ininterrumpida (generalmente esperando actividad del disco)"

Como nota al margen, el problema particular que encontré fue que tenía un promedio de carga alto, pero también mucha CPU inactiva y bajo uso de disco.

Parece que, al menos en mi caso, a veces los subprocesos / procesos que esperan E / S se muestran en el promedio de carga, pero no causan un aumento en la columna "esperar". Pero todavía están vinculados a E / S.

Puede decir que este es el caso con el siguiente código, si lo ejecuta en jruby (solo hace 100 hilos con muchas E / S cada uno):

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

Lo que da una salida 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

Entonces puede ver que tiene mucha CPU inactiva, 0.0% wa, pero un promedio de carga muy alto.

iostat muestra de manera similar el disco como básicamente inactivo:

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

ver también http://linuxgazette.net/141/misc/lg/tracking_load_average_issues.html

Como nota adicional, esto también parece implicar que (al menos en este caso, ejecutar CentOS) el promedio de carga incluye cada subproceso por separado en el total.

rogerdpack
fuente
2
"promedio de carga también incluye cosas que esperan actividad de disco" en Linux , mientras que esta pregunta era originalmente sobre Solaris, que parece incluir solo tareas en ejecución y ejecutables (es decir, esperando CPU) en promedio de carga . Una versión de Linux de esta pregunta es esta .
Nickolay
7

Tuve el mismo problema hoy. Después de algunas investigaciones y diagnósticos, me di cuenta de que mi pequeño VPS se estaba quedando sin disco .

En tipo shell / prompt (Linux / Unix)

df -h

para ver el disco libre en tu máquina. Si se está quedando sin disco, ese puede ser el problema.

PJunior
fuente
¿Estabas intercambiando entonces, supongo, así que eso lo estaba causando?
rogerdpack
4

Otra herramienta útil que ayudará en esta situación es nmon.

Incluye una variedad de formas de ver los mismos datos presentados por las otras herramientas, en un pequeño paquete.

Si este es un contenido que no se puede almacenar en caché, recomendaría colocar varios servidores detrás de un equilibrador de carga como haproxy en modo tcp para distribuir la carga.

Daniel Baker
fuente
2

Solo para agregar a esto, algunas herramientas específicas de Solaris que no se han mencionado y que son útiles para depurar estos problemas son "intrstat", "mpstat" y "lockstat". Después de haber experimentado un problema similar antes en un host que ejecutaba cargas pesadas de ETL, mpstat reveló una gran cantidad de interrupciones relacionadas con muchas E / S que insinuaban el problema.

En ese momento, en un T4-4 con mpstat vimos que vcpus entregaba más de 30000 interrupciones durante un ciclo de monitoreo corto, después de lo cual el rendimiento comenzó a sufrir. En este caso, la única solución era lanzarle más CPU; sin embargo, posteriormente se trabajó para mejorar el código.

Brendan Gregg ha escrito mucho sobre el rendimiento, especialmente en torno a E / S a lo largo de los años, y vale la pena buscarlo si desea obtener más información.

Rowley
fuente