1.- La llamada.

Los problemas de performance son un tema recurrente en la vida de un administrador de sistemas, normalmente suelen llegar en forma de incidencia bajo el eufemismo "lentitud en el sistema" o parecido, que en realidad significa "No tenemos ni idea de que está pasando".

Ante estas situaciones mis sentimientos son encontrados. Por un lado tienes la oportunidad de usar tus conocimientos e investigar el origen de una incidencia, lo cual no deja de ser atractivo. Los problemas empiezan cuando el diagnóstico no depende de ti solo, en realidad suele hacer falta la colaboración de la gente de comunicaciones, BB.DD., aplicaciones, etc. Invariablemente siempre te encuentras con algún personaje más interesado en pasar el marrón a otro que en colaborar para encontrar la solución.

arrow Los jefes

Hay otro elemento que todavía no he mencionado, tu jefe, o aun peor, el jefe de tu jefe. Normalmente las situaciones donde el performance se ve degradado suele venir acompañado de cierto nerviosismo por parte de las grandes esferas, en lo que a ti respeta se traduce en presión para resolver el problema lo antes posible.

Sin embargo un diagnóstico de este tipo suele llevar bastante tiempo, muchas veces es complicado dar con la causa raíz del problema. No obstante, es importante que sepas dar una primera valoración rápida de lo que esta ocurriendo en el equipo. Un prolongado silencio puede dar pie a teorías de lo más disparatadas por parte de tus colegas, que en el peor de los casos podrían ser creídas por tus responsables.

arrow Los problemas tienen un origen

Si, es un obviedad verdad? Cuando se produce una degradación del sistema siempre hay una causa. Algo que parece indiscutible es discutido muchas veces en el mundillo de la informática, cuantas veces habré escuchado frases del tipo, "Se habrá quedado algo colgado", "Habrá bloqueos", "Está pillado", etc. y después se suelen acompañarse de la sugerencia "reiniciemos el equipo".

Reiniciar vs no reiniciar

Salvo que tu puesto de trabajo corra peligro nunca reinicies un equipo sin haber tratado de realizar un diagnóstico antes, por suerte dispones de un sistema sumamente observable, es decir, tienes a tu mano una serie de herramientas que, junto con el conocimiento necesario, te permitirán determinar la causa del problema. Aunque un reinicio a priori puede solucionar las cosas en un elevado porcentaje de ocasiones, solo conseguirás que la incidencia reaparezca en unas horas o días y tu nivel de conocimiento de la causa seguirá siendo el mismo que antes, es decir, 0.

Créeme, aunque muchas veces tus responsables no sean conscientes, seguro que prefieren tener la producción degradada o incluso parada durante un rato a que la misma incidencia se reproduzca de forma cíclica. Si el problema es realmente crítico puedes obtar por generar un live core "

#savecore -L" y realizar un análisis posterior de la imagen del kernel. Ten en cuenta que en sistemas con mucha RAM el volcado puede demorar un rato.

arrow Primeras valoraciones

Lo que sigue no pretende ser una Biblia de los pasos a seguir, en ocasiones puede ser necesario un mayor grado de profundización antes de valorar la situación, otras veces el cuello de botella es tan evidente que puedes obviar muchos de los pasos aquí descritos.

Tanteo:

Mi primer comando a ejecutar suele ser #w. Es un comando ligero con el que obtienes información bastante útil, el uptime del equipo, su load average y los usuarios conectados junto al comando que están ejecutando.

root@box # w 9:28am up 135 day(s), 18:29, 3 users, load average: 3.96, 3.67, 3.91 User tty login@ idle JCPU PCPU what explot pts/1 8:15am 1 9:48 sqlplus /script oracle pts/2 8:39am 50 tail -25f /opt/oracle/app/oracle sistemas pts/3 9:05am -bash

El load average es un parámetro engañoso, su nombre puede llevar a confusión, parece ser un calculo de la carga del sistema. Sin embargo es la media del número de threads en las run queues, es decir, un elevado load average puede ser síntoma de saturación de cpu pero no tiene en cuenta otros aspectos como puede ser memoria, i/o, red, etc.

Comprobar recursos:

Uno de mis comandos preferidos es el vmstat, proporciona muchísima información a simple vista. Lo normal sería lanzar un #vmstat 5 y dejarlo un buen rato ejecutándose. La primera linea son estadísticas desde que se arrancó el sistema, por lo que en nuestro caso debe ser ignorada.

root@box # vmstat 5 kthr memory page disk faults cpu r b w swap free re mf pi po fr de sr 2m m0 m1 m2 in sy cs us sy id 1 0 0 42157120 7573496 585 2219 1920 7 9 0 6 44 2 1 1 19612 34991 12905 42 15 43 0 0 0 41882080 7348816 546 2233 2175 0 0 0 0 35 0 0 0 12435 29385 6561 32 9 59 0 0 0 41882512 7344728 584 2393 2162 0 0 0 0 36 20 19 19 10922 32580 7231 28 9 63 0 0 0 41884936 7342656 628 2809 2174 0 0 0 0 35 0 0 0 11673 43611 8204 31 9 60 [...]

Varios son los datos interesantes para nuestra primera aproximación:

La columna r: es el número de procesos esperando en las

run queues, idealmente debería ser 0, lo que indicaría que cualquier thread en condiciones de ser ejecutado ha encontrado un procesador libre. Si el valor de r supera el número de procesadores de nuestro sistema estamos empezando a saturar, si lo duplica estamos ante una situación de saturación y la performance empieza a verse degradada.

La columna sr: es el número de veces que se ha ejecutado el

page scanner durante la muestra. Dado que este solo se ejecuta en casos de grabe escasez de memoria cualquier valor superior a 0 es preocupante.

La columna in: El número de interrupciones durante la muestra. Es complicado de valorar ya que un número elevado puede ser síntoma de muchas cosas, como mucho tráfico de red, elevada i/o, mal funcionamiento hardware, etc. En nuestra primera aproximación solo comprobaremos que no sea más elevado de lo habitual en nuestro sistema, si es así deberemos tener este dato en cuenta para seguir investigando.

La columna sy: Número total de

llamadas al sistema. Si es superior a lo que tenemos de media en condiciones normales puede ser un mal funcionamiento de alguna aplicación, normalmente irá acompañado de un porcentaje alto de tiempo en modo sistema. (Columna cpu/sy).

La columna cs: Los

cambios de contexto acontecidos en nuestro sistema durante la muestra. Si el valor es muy elevado puede ser síntoma de muchos threads compitiendo por recursos. Al igual que con la columna in deberemos tenerlo presente más adelante.

Las columnas us sy id: Es un porcentaje de los ciclos de cpu gastados en tiempo de usuario (us), de sistema (sy) y sin hacer nada (id). Para ver si hay saturación de cpu es mejor hacer caso a la columna r, sin embargo un elevado tiempo de sistema es sospecho. Generalmente suele ser alguna aplicación realizando muchas

llamadas al sistema. Igual que anteriormente será un dato a tener en cuenta para el futuro.

Mirar procesos:

El comando vmstat nos ha dado una idea general de los recursos de la máquina, ahora llega el momento de ver que demonios es lo que está ejecutando. Para ello echaremos mano del comando #prstat.

root@box # prstat PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP 29921 oracle 16G 16G cpu17 40 0 1:32:53 7.4% oracle/1 24722 oracle 16G 16G sleep 60 0 0:13:25 4.6% oracle/11 5669 oracle 16G 16G sleep 60 0 0:19:29 2.3% oracle/11 27688 oracle 16G 16G sleep 48 2 1:44:05 1.7% oracle/11 28286 oracle 16G 16G sleep 60 0 0:07:51 1.3% oracle/11 5828 oracle 16G 16G sleep 59 0 115:22:45 1.2% oracle/258 27687 oracle 26M 22M cpu18 48 2 1:42:58 1.0% exp/1 [..] Total: 340 processes, 3029 lwps, load averages: 2.73, 3.01, 3.30

Hay varios datos que son interesantes, el % de cpu (CPU) consumido por proceso, el número de threads de cada proceso (NLWP) y el total de procesos y threads. A veces es un único proceso el que está consumiendo toda la CPU, al ejecutar un prstat se mostrará en primer lugar.

Por otro lado, si en la salida del vmstat había muchos cambios de contexto y ahora tenemos un proceso con muchos threads (aka LWP), o bien muchos threads en total, puede ser que estos estén compitiendo entre ellos para conseguir los mismos recursos.

root@box # prstat -m PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP 29921 oracle 41 1.3 0.1 0.0 0.0 0.0 57 0.5 182 470 33K 0 oracle/1 27687 oracle 8.3 5.1 0.0 0.0 0.0 0.0 86 0.9 4K 120 13K 0 exp/1 5798 oracle 3.6 2.7 0.0 0.0 0.0 0.0 94 0.2 956 5 10K 8 oracle/1 5822 oracle 3.0 2.2 0.0 0.0 0.0 0.0 95 0.1 717 1 8K 3 oracle/1 6099 root 1.0 2.7 0.2 0.0 0.0 0.0 96 0.0 55 0 2K 0 sleep/1 5783 oracle 1.7 1.5 0.0 0.0 0.0 0.0 97 0.1 736 76 6K 198 oracle/1

Si al comando prstat le pasamos la opción -m nos muestra los microstados de cada uno de los procesos. La información aquí es mucho más detallada.

Datos interesantes para nuestra primera aproximación:

USR SYS: Porcentaje de tiempo empleado en modo usuario y modo sistema. Este dato lo podemos relacionar con la columna sy de la salida del vmstat, es decir nos puede proporcionar la pista para dar con un proceso que esté generando un número anormalmente alto de llamadas a sistema.

LCK: Porcentaje de tiempo esperado bloqueos a nivel de usuario. Podemos verificarlos con el comando

plockstat.

SLP: Porcentaje de tiempo que el proceso ha estado durmiendo, incluye los tiempo de espera de i/o. Que haya muchos procesos durmiendo no es sítoma de un problema, pueden estar esperando a algún dispositivo (tarjeta de red, disco duro), a la interacción de un usuario (una shell esperando que teclees algún comando), que deban hacer algo ( un servidor web o BBDD esperando que alguien les pida información), etc.

LAT: Porcentaje de tiempo esperando una CPU libre. Obviamente puede ser sítoma de saturación en los procesadores, deberíamos verificarlo con la columna r de la salida del vmstat.

ICX: Número de

cambios de contexto involuntarios. Si los procesos se ven continuamente desalojados de la cpu puede ser señal de saturación o de competencia por los mismos recursos.

SCL: Llamadas a sistema, otra vez. Si es elevado deberíamos ver con más detalle que está haciendo este proceso. (dtruss, truss).

root@box # prstat -mL PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID 5425 root 31 59 8.6 0.0 0.0 0.0 0.0 2.2 0 1K 49K 0 prstat/1 29921 oracle 58 1.8 0.2 0.0 0.0 0.0 39 1.0 232 934 43K 0 oracle/1 5669 oracle 23 2.3 0.1 0.0 0.0 0.0 74 0.4 508 363 26K 2 oracle/1

Si añadimos la opción -L se nos mostrará la misma información pero por thread en lugar de por proceso.

Los discos

No está de más comprobar la i/o a disco de nuestro sistema, con un iostat nos bastará para hacernos una idea global, especialmente nos fijaremos en el % de busy en busca de datos elevados, también verificaremos el throughput de escritura y lectura.

root@box # iostat -xn 5 extended device statistics r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device 19.5 24.1 1161.9 1360.0 0.0 0.2 0.0 3.8 0 8 2/md110 0.7 1.0 13.7 1.2 0.0 0.0 2.4 20.9 0 1 d0 0.3 1.0 6.9 1.2 0.0 0.0 0.0 22.6 0 1 d1 0.3 1.0 6.9 1.2 0.0 0.0 0.0 22.3 0 1 d2

La red

Los problemas de red suelen ser competencia de la gente de comunicaciones, sin embargo nosotros podemos percibir sus síntomas. Una rápida comprobación puede ser hacer un ping a nuestro router por defecto y a un equipo de fuera de nuestra red, comprobaremos que no se pierdan paquetes y que los tiempos de respuesta esten dentro de lo normal.

También miraremos las estadísticas de red y comprobaremos que no haya errores de RX TX, hay que tener en cuenta que son contadores desde el arranque del sistema, por lo que debemos verificar que estén aumentando actualmente.

root@box # netstat -ni Name Mtu Net/Dest Address Ipkts Ierrs Opkts Oerrs Collis Queue lo0 8232 127.0.0.0 127.0.0.1 76861912 0 76861912 0 0 0 ce0 1500 192.168.103.0 192.168.103.56 149068395 0 364477655 0 0 0 ce2 1500 10.0.0.0 10.10.1.1 0 0 0 0 0 0 ce3 1500 172.16.0.128 172.16.0.130 2640701017 18 3331003982 0 0 0 ce5 1500 10.27.0.0 10.27.0.1 238843876 10 248360337 0 0 0 ce7 1500 172.16.1.0 172.16.1.2 3703162800 4 2341304790 0 0 0 eri0 1500 192.168.103.0 192.168.103.84 1767612057 0 4287819140 6 0 0

Finalmente podemos ejecutar un netstat -na para ver el número de sockets en uso de nuestro sistema y su estado.

root@box # netstat -na | awk ' { print $7 } ' | sort | uniq -c 1 32/32 2 BOUND 1 CLOSE_WAIT 223 ESTABLISHED 30 IDLE 76 LISTEN 1 Remote 3 Rwind 4 TIME_WAIT

Estos datos por si solos no suelen significar nada, es bueno tener la posibilidad de compararlos con un histórico.

Revisar los logs

Normalmente los problemas de rendimiento no suelen dejar trazas en los logs, sin embargo no está de más echar un vistazo para asegurarnos que no nos saltamos nada interesante, así pues revisa el fichero de messages y ejecuta un dmesg en busca de errores.

arrow Primera conclusión

Seguir los pasos anteriores no debería tomarte más de 10 - 15 minutos.

Después de revisar todos estos datos muy probablemente sigas sin tener ni idea de cual es la causa raíz del problema de rendimiento, sin embargo si deberías tener claro cuales son sus consecuencias y empezar a descartar algunas posibilidades, por ejemplo:

  • Hay saturación en las CPUs?
  • Alguna aplicación se ha salido de su patrón de carga habitual?
  • Falta de memoria?
  • Hay problemas de competencia por un mismo recurso?
  • Existen problemas de acceso a disco?
  • Hay problemas de red?
Lógicamente puedes tener más de un síntoma a la vez.

Necesitas investigar más, sin embargo puede ser un buen momento para proporcionar un primer feedback a tus responsables y a tus colegas, piensa que no solo debes saber diagnosticar bien, además la gente debe pensar que sabes diagnosticar bien, mantenerles informados es la mejor forma de hacerlo, de paso también atajarás las posibles especulaciones sin argumentos del típico suelta marrones que tengas cerca.

Profundizaremos en cada uno de los puntos en los siguientes artículos.

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.