Cómo saber si tu servidor (compartido) está saturado

Autor: Armonth | El sábado 28 de abril del 2007 @ 23:16.

A menudo los que usamos un servidor compartido tenemos un problema de fondo: si la compañía de hosting abusa a la hora de "apiñar gente" en una misma máquina a la larga acabará saturada.

Otro problema de usar servidores compartidos es que si bien los planes para controlar el consumo pueden ser "razonables" siempre puede aparecer un usuario que por desconocimiento (o malicia...) sature el servidor con algún script mal optimizado o algo similar.

En general yo puedo decir que con Dreamhost aunque esté en un compartido estoy muy contento. Sé que a algunas personas no les ha ido bien pero a la mayoría que conozco no les ha dado ningún problema.

El caso es que normalmente los servidores ocultan los procesos ejecutándose actualmente que no son tuyos (los procesos se pueden ver con -- por ejemplo -- el comando ps -ax). Esto aparte de ser una medida de seguridad es una comodidad: es de locos buscar entre cientos de procesos los tuyos (aunque bien es cierto que siempre podríamos usar top + u para ver sólo los de un usuario).

Vamos a ver las formas más habituales de mirar la saturación de una máquina, principalmente en GNU/Linux.

A nivel de CPU

Una forma interesante de ver la carga de tu servidor es con uptime un "clásico" de los comandos que ya de paso te dice el tiempo que la máquina lleva encendida, veamos el de mi servidor:

11:27:21 up 43 days, 22:39, 6 users, load average: 5.61, 5.39, 5.25

Cabe aclarar que la "carga de tu servidor" no es el % de CPU usándose en ese momento, si no el número de procesos en la cola de procesos listos para ejecutar.

Según ese uptime lleva 43 días, 22 horas y 39 segundos online. Los valores son en el último minuto 5.61 de carga, en los últimos 5 minutos 5.39 y en los últimos 15 minutos 5.25.

Podemos decir que una carga de 0 a 4 es razonable, de 4 a 6 moderada y 6 o más es alta. También hay que aclarar que son valores totales o al menos creo que en GNU/Linux y BSD es así (tengo entendido que en algunos Unix varía) por lo que si tenemos más de una CPU hay que dividir la carga por el número de procesadores.

Ahí también tengo la duda de que si eso incluye los DualCore ya que son 1 microprocesador con doble núcleo, al menos la máquina donde estoy alojado en Dreamhost es un AMD Opteron (Dual Core) por lo que en teoría la carga sería 5.61 / 2 = 2.80.

La forma de ver la CPU es leyendo el fichero /proc/cpuinfo por ejemplo con cat /proc/cpuinfo y nos saldrá el número de microprocesadores que "encuentra" con toda la información, si es un microprocesador simple pues saldrá información de un microprocesador, si es DualCore o un Pentium 4 con HyperThreading saldrán dos (y seguramente idénticos) o más si ya hablamos de algo más potente.

Apuntes sacados a Ricardo Galli: depende del tipo de carga, si es por muchas aperturas de sockets aguanta mucho más que por E/S. El Apache cuando se sobrecarga genera cargas muy altas por la cantidad de cambios de contexto que genera.

Varía en lo que hace, si tienes 200 de carga (un valor aparentemente alto) y Apache sólo sirve ficheros estáticos, aguantará bien aunque sea alto, si es dinámico y BBDD estará hecho una mierda.

El Load average de por sí no sirve para saber si "está bien", es sólo orientativo, hay que mirar otras cosas, por ejemplo el tiempo de espera (wait) y el uso real de la CPU, ambas se pueden ver en el top o en el vmstat.

Valores altos de waits significa que se está perdiendo mucho tiempo esperando por E/S, por ejemplo una bbdd mal diseñada o sobrecargada y el wait hace subir exponencialmente los procesos apaches, que a su vez hacen subir la carga.

A nivel de memoria (RAM)

Está es fácil: con "free" aunque mejor todavía ejecutar free -m para verlo en megabytes. Aquí lo único que hay que tener en cuenta es que no hay que mirar la memoria libre.

GNU/Linux (y supongo que el resto de Unix más o menos igual) usan toda la memoria RAM posible y mantienen datos "en cache". Por ejemplo si abrimos un programa y lo cerramos se mantendrá en memoria RAM "cacheado" y si lo vuelves a abrir en lugar de volver a acceder al disco duro lo abrirá desde RAM.

Si una aplicación de repente necesita más RAM de la disponible pues el sistema liberará la memoria usada para datos cacheados "por si se vuelven a usar" y llegado a cierto punto empezará a "raspar" memoria SWAP (memoria de intercambio) es decir usará una partición o un fichero del disco duro como si fuera más memoria RAM.

La forma correcta de ver la memoria es viendo el valor buffers/cache, un ejemplo en mi máquina (PC de trabajo):

             total       used       free     shared    buffers     cached
Mem:           504        494          9          0         12        313
-/+ buffers/cache:        169        335
Swap:            0          0          0

Medio GB de RAM. Se ha usado casi todo pero 313MB están cacheados, "en uso" realmente están 169.

En el caso de la máquina de Dreamhost obviamente está bastante más cargada: 4GB de ellos 2GB cacheados, 1.6GB en buffers y 170MB libres (y raspa de swap pero no mucho: máximo 500MB).

Escrituras I/O a dispositivos

El mayor cuello de botella en un PC doméstico para acceder a Internet suele ser la conexión y la tarjeta ethernet pero para ejecutar aplicaciones es la lectura a disco. En un servidor no es tan raro que debido a algunas operaciones (aún estando bien de CPU, RAM y ancho de banda) el rendimiento caiga por tener que esperar a operaciones de I/O (input/output) o en cristiano: esperar para poder acceder al dispositivo, en este caso el disco duro.

Para ello tenemos iostat (forma parte del paquete "sysstat" en Debian/Gentoo) que nos da mucha información:

avg-cpu:  %user   %nice    %sys %iowait   %idle
          56.75    1.25   10.80    0.00   31.21

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              15.99        43.91       314.65  167088814 1197432548
sda1              0.43         6.40         1.14   24337978    4331616
sda3             12.30        35.72       244.97  135949674  932259906
sda5              0.08         1.63         1.79    6185976    6803424
sda6              0.00         0.00         0.00          8          0
sda7              0.00         0.00         0.00          8          0
sda8              3.18         0.16        66.75     615130  254037602

Los datos ordenados por dispositivos, sinceramente y con todas las palabras no tengo ni puta idea de qué significan (o mejor dicho: qué valores son normales). Pero lo interesante es la parte avg-cpu: nos dice el % de CPU usado en procesos en espacio de aplicación (%user), en espacio de aplicación pero con valores "nice" para darles mayor o menor prioridad (%nice), en espacio de kernel (%sys) y los que nos interesan:

  • %iowait: porcentaje de procesos que están esperando a una operación I/O. Cuanto más bajo mejor. Si es un valor alto continuamente (que pase esporádicamente es normal sobretodo con los picos de tráfico) tenemos un cuello de botella ahí: toca meter otro disco duro más rápido, un segundo disco duro o incluso una máquina adicional para hacer balanceo de carga.

  • %idle: el % de la CPU que está en espera por una razón que no tenga que ver con exceso de peticiones I/O. Tener un porcentaje alto de idle no es malo ya que habitualmente significa "CPU libre", por ejemplo mi CPU ahora mismo marca un 90% Idle.

Cualquier cosa a añadir/mejorar, correcciones, dudas y demás comentarios como siempre son bien recibidos. Por otro lado este artículo bien se podría haber llamado "Cómo saber si una máquina con GNU/Linux está saturada... y dónde están sus cuellos de botella" o incluso más génerico, que muchos Unix tienen comandos iguales o similares.

PD: Si tu hosting es tan receloso que ni siquiera te permite ver datos tan inocuos pero interesantes como los devueltos por /proc/cpuinfo, free, iostat, etcétera, mejor cambiate de hosting ;).

Comentarios