El óptimo desempeño de un sistema es una tarea muy importante para su correcto funcionamiento, pero sin dudas no es algo muy fácil de lograr. En este artículo, nos propondremos revisar y analizar cómo detectar problemas de rendimiento en nuestros sistemas GNU/Linux y así poder lograr que nuestro sistema se aproveche al máximo.
Por Jorge Emanuel Capurro
El hardware en conjunto con el software, conforman las piezas fundamentales e indispensables de un Sistema Informático. Como bien sabemos, el hardware, actúa en sintonía en todo momento con el software. Por esta razón básica, de nada sirve tener buen hardware si nuestro sistema operativo posee problemas ajenos a éste, como pueden ser los cuellos de botella, sobrecarga de procesos en relación a la memoria disponible, poco espacio en disco a razón de una mala administración de las cuotas, etc. Es por ello que es de suma importancia aprender a monitorizar nuestro sistema en busca de problemas y sus posibles soluciones, para poder así hacer que nuestro sistema funcione de manera eficiente y eficaz.
Pruebas de Rendimiento
Para poder lograr todo lo anteriormente descripto, es necesario realizar lo que se conoce como pruebas de rendimiento. Como su nombre lo indica, las pruebas de rendimiento son aquellas que tratan de probar un determinado comportamiento de un sistema bajo condiciones demandantes. Las pruebas de rendimiento realizadas en un lapso de tiempo nos dan la pauta de que estamos considerando distintos instantes y variaciones del estado actual de un sistema, el cual nos proveerá un flujo de información más homogénea a la hora de analizar. A estas pruebas de rendimiento también se las suele denominar, de manera indistinta, como pruebas de stress.
Las condiciones demandantes básicas que afectan de manera directa a la ejecución y tiempo de respuesta de los recursos del sistema son las siguientes:
CPU: Tiempo consumido en el procesado de datos sobre el o los CPU(s) de una máquina.
Memoria: Tiempo consumido en lectura y escritura para y proveniente de la memoria real.
Entrada/Salida: Tiempo consumido en lectura y escritura para y proveniente de la unidad de almacenamiento.
Redes: Tiempo consumido en lectura y escritura para y proveniente de la red.
Principios a tener en cuenta
Para analizar de manera objetiva el resultado de las pruebas de rendimiento y así poder mejorar las prestaciones de un sistema, es conveniente tener en cuenta una serie de factores.
Conocer el Entorno de Ejecución: es conveniente saber qué es lo que realmente hace el sistema. Es decir, conocer qué servicios tiene activados, qué procesos arrancan en conjunto con el sistema, para qué sirven y se utilizan. No es necesario saber absolutamente todo, pero sí una vaga noción del entorno donde estaremos realizando las pruebas, así a la hora de encontrar problemas, nos sea más fácil identificar la raíz de los mismos.
Conocer cómo buscar el Equilibrio: este concepto es directo. El lema básico es “Lo que se le da a uno, se le resta a otro” (ver cuadro “El Efecto Burbuja”). Por ejemplo, si mejoramos la prioridad de ejecución de un determinado proceso, estaremos empeorando la de otros. Encontrar el equilibrio junto entre las partes es una de las grandes virtudes de los sistemas correctamente optimizados.
Conocer básicamente el hardware a optimizar: para mejorar algo es primordialmente necesario saber si es susceptible de mejora. Cuando se realicen las pruebas de rendimiento, el encargado de las mismas deberá conocer básicamente el hardware subyacente (CPU, Memorias, Cache, I/O, etc.) y su interconexión para poder determinar dónde están sus problemas.
Herramientas Empleadas
Para realizar las pruebas de rendimiento, en este artículo utilizaremos particularmente la herramienta sar (System Activity Report). Esta herramienta nos permite mostrar una gran cantidad de información estadística de rendimiento de nuestro equipo, como por ejemplo el uso de las distintas CPUs, la carga del sistema, el uso de memoria, I/I, redes, etc. Para ello tendremos que definir los parámetros que queremos monitorizar, el período entre cada muestra y el número de muestras que vamos a tomar.
Esta herramienta forma parte del paquete sysstat que es una colección de herramientas de monitorización de rendimiento. Esta suite nos proporciona herramientas que nos pueden mostrar datos instantáneos de rendimiento, así como almacenarlos como históricos para nuestra futura referencia. Especialmente en entornos de servidor, sus datos nos proporcionan información muy valiosa sobre las posibles carencias y cuellos de botella de nuestro sistema.
En particular, haremos especial enfoque sobre la herramienta sar, que es la más completa de todas e incluso nos proporciona la misma información que nos brindan otras herramientas en conjunto.
El encargado de realizar las pruebas deberá conocer muy bien esta herramienta, ya que le permitirá evaluar los niveles de utilización de los recursos del sistema.
Instalación y Archivos de Configuración
En muchos sistemas comerciales, el paquete sysstat viene instalado por defecto. En distribuciones como Debian y derivados, solamente tendremos que ejecutar el comando sudo apt-get install sysstat y listo. El archivo binario se encuentra en /usr/bin/sar. Vale aclarar que este paquete suele trabajar en conjunto con el comando cron, por lo cual se recomienda tener instalada dicha dependencia.
Una vez finalizada la instalación, poseeremos los siguientes archivos de configuración:
/etc/default/sysstat: archivo básico de configuración Entre otras cosas, este archivo es el encargado de habilitar el modo real.
/usr/lib/sysstat/sadc: recoge los datos relacionados con la actividad del sistema, y construye con ellos un registro en formato binario. En otras palabras, es usado como backend para sar.
/usr/lib/sysstat/sa1: script que recopila y almacena datos binarios en el fichero de datos diario de actividad del sistema. El mismo utiliza a sadc para su función.
/usr/lib/sysstat/sa2: script encargado de escribir un informe resumido de actividad diaria. Está preparado para ser ejecutado con cron. Como segunda tarea, se encarga de eliminar los archivos de estadística del sistema que superan el máximo establecido por el archivo de configuración.
/etc/cron.d/sysstat: tabla cron, la cual es llamada mediante el script sa2, siempre y cuando esté configurada su activación de antemano.
/var/log/sysstat/saXX: archivo en formato binario, el cual es creado y escrito por la información recogida desde sadc, donde XX indica el día del mes en curso.
/etc/sysstat/sysstat.ioconf: archivo de configuración encargado de suministrarle a sadc información acerca de la configuración de los dispositivos de entrada y salida de nuestro sistema. No debe modificarse.
Seguramente muchos de los archivos anteriores contenían conceptos todavía no vistos. ¡No se preocupe! Todos estos archivos y conceptos nuevos los veremos en la práctica de este artículo, con su correspondiente explicación.
Como último punto, vale la pena aclarar que al instalar la herramienta sar, también se instalan todas las demás herramientas correspondientes al paquete sysstat.
La herramienta sar
Básicamente, sar posee dos modos bien definidos para su funcionamiento, éstos se denominan modo estático y modo real. En el modo estático, sar recolecta información sobre el rendimiento del sistema previamente configurado en un horario en particular, lo más interesante de este modo es la posibilidad de recoger periódicamente datos y guardarlos en ficheros históricos estadísticos. Al contrario, el modo real se encarga de obtener estadísticas del sistema al instante, brindándonos datos estadísticos en el instante justo donde se está llevando a cabo la prueba de rendimiento. Sin lugar a dudas, los dos modos son de mucha utilidad, y tienen prestaciones bien marcadas.
Antes de empezar a utilizar la herramienta sar en la práctica y realizar un par de ejercicios, nada mejor que entender realmente cómo funciona internamente y qué es lo que realmente está haciendo esta maravillosa herramienta. El secreto de sar se remite básicamente a la razón del sistema de archivos virtual en /proc. Este sistema de archivos lo veremos como un directorio, pero en la realidad no existe sobre el disco y es el kernel el que lo crea en memoria. Este directorio se utiliza para proveer al usuario o administrador información sobre el sistema. En un principio, solamente se proveía información sobre procesos (de ahí el origen de su nombre), pero en las versiones actuales este sistema de archivos ficticio nos brinda mucha información La misma, se especifica en la siguiente tabla:
Nombre del Archivo | Descripcion |
proc/X | Directorio con la información del proceso X (X es el PID del proceso) |
/proc/cpuinfo | Información sobre la CPU (tipo, marca, modelo, prestaciones, etc) |
/proc/devices | Lista de dispositivos configurados en el kernel. |
/proc/dma | Canales de DMA utilizados en ese momento |
/proc/filesystems | Sistemas de archivos configurados en el kernel. |
/proc/interrupts | Muestra cuales interrupciones están en uso y cuantas de ellas se han procesado |
/proc/ioports | Muestra cuales puertos están en uso y cuantos de ellos se han procesado |
/proc/kcore | Imagen de la memoria física del sistema. |
/proc/kmsg | Mensajes generados por el kernel que luego son enviados a syslog |
/proc/ksyms | Tabla de símbolos del kernel. |
/proc/loadavg | Carga del sistema |
/proc/meminfo | Información sobre la utilización de memoria. |
/proc/modules | Módulos cargados por el kernel. |
/proc/net | Información sobre los protocolos de red |
/proc/stat | Estadisticas varias sobre el sistema |
/proc/uptime | Informascion del tiempo desde cuando el sistema está funcionando |
/proc/version | Version del Kernel |
Se debe tener en cuenta que algunos de estos archivos son de texto puro, los cuales pueden leerse de manera convencional, y otros son necesarios comandos para poder interpretarlos, por ejemplo sar.
La herramienta sar realiza todo un proceso en particular para poder extraer información de estos archivos ficticios la cual luego se transformará en informes de pruebas de rendimiento. El verdadero core y hacedor de todas las tareas de recolección de datos de esta herramienta es el sadc. El sadc (System Activity Data Collector o Recolector de Datos de Actividad del Sistema) es un archivo binario que realmente se encarga de extraer información del directorio /proc para que luego sea leída y formateada a un formato de texto mediante sar. Este archivo puede ser ejecutado al instante (Modo Real) mediante la misma llamada a sar o bien, mediante la previa configuración de una tabla cron, que se encarga de juntar información en un momento determinado (previamente configurado) y leerla en otro momento (Modo Estático) también utilizando sar. En definitiva, el recolector de datos es sadc y el “formateador” de los mismos es sar.
Los informes de rendimiento del sistema pueden evaluar multitudes de cosas a la vez, como puede ser el rendimiento del CPU, de la memoria, de la actividad de I/O, etc.
Se recomienda releer el apartado “Instalación y Archivos de Configuración” a modo de fusionar los conceptos explicados con anterioridad y poder llegar a comprender de una manera más amplia el funcionamiento de esta herramienta. Aunque no es necesario saber al pie de la letra su funcionamiento, nunca está de más para así poder comprender de manera completa el proceso con el cual se obtiene información de nuestro sistema.
De la Teoría a la Practica
Ahora que ya sabemos como funciona sar, empezaremos a utilizar esta herramienta en la práctica para realizar sencillas pruebas de rendimiento sobre nuestro sistema. En primer lugar, tendremos que tener instalada esta herramienta. Si todavía no la tienes instalada, dirígete a la sección anterior “Instalación y Archivos de Configuración”.
Empezaremos haciendo uso del modo real. En primer lugar, nos dirigimos hacia nuestra terminal de GNU/Linux. Una vez allí, tipeamos sar y luego apretamos la tecla ENTER.
Existen 15 tipos de reportes que son los más utilizados para realizar pruebas. Los mismos se listan en la Tabla 2. Como podemos deducir ahora, ejecutar el comando sar “a secas” es lo mismo que ejecutar sar -u.
Volviendo a la salida del comando sar, la misma muestra información relacionada con el sistema en forma de columnas. En este caso, las columnas más importantes son idle y wait (en versiones viejas, waitio).
El valor especificado en idle indica el porcentaje de desocupación que tiene la CPU en ese instante. Si este valor tiende, o es igual a cero, significa que la CPU está muy sobrecargada. Por el contrario, si este valor tiende a valores altos, quiere decir que la CPU no está realizando una labor que requiere de mucho procesamiento, lo cual no la mantiene ocupada.
Si por ejemplo el valor de idle=10 y el número de procesos es elevado, debería pensarse en optimizar la CPU, ya que podría ser el cuello de botella del sistema.
Por otro lado, el valor que se muestra en la columna de wait (o waitio) indica el porcentaje de espera por el sistema de entrada y salida en ese instante. Al contrario de lo que sucede con idle, si este valor es grande, significa que los discos están sobrecargados. Un porcentaje rondando el 70% es señal de una sobrecarga considerable del sistema de I/O.
Ahora veremos cómo realizar pruebas de rendimiento durante un lapso de tiempo específico. La herramienta sar nos permite tomar muestras de datos estadísticos de uso del sistema cada un intervalo de tiempo determinado. Por ejemplo, podemos indicarle que nos muestre las estadísticas de rendimiento del sistema 5 veces, cada 10 segundos, mediante la siguiente sintaxis.
Sar [tiempo] [repeticiones]
Estos parámetros indican lo siguiente:
tiempo: indica cada cuanto tiempo hay que controlar el sistema entre informe e informe. Se especifica en segundos.
repeticiones: indica cuantas veces hay que repetir el proceso de monitorización del sistema e informar sobre el mismo.
Por ejemplo, si tecleamos sar 5 10 en nuestra consola obtendremos un informe cada cinco segundos sucesivamente diez veces. Obviamente, el informe final se podrá considerar terminado cuando trascurran todas las repeticiones, es decir, en cincuenta segundos.
Podemos observar las ligeras variaciones que se dieron en el sistema, más específicamente en la columna del valor idle. Estas variaciones son prácticamente despreciables por su poca diferencia entre valor y valor, por lo cual no nos desemboca en la sospecha de un posible problema.
Para verificar a ciencia cierta el verdadero uso de todo lo explicado anteriormente, provocaremos intencionalmente stress al sistema. Mediante un simple programa realizado en Lenguaje C haremos que la CPU se mantenga ocupada por un instante de tiempo considerable, provocando una sobrecarga de la misma. En el mismo instante que ejecutamos nuestro programa, realizaremos una prueba de rendimiento con sar para analizar los valores que nos arroja. Al programa lo llamaremos stress.c y su lógica es muy sencilla. Simplemente crea un archivo y va guardando en él los caracteres generados mediante una expresión matemática. Asimismo, para poder guardar cada carácter, tendrá que pasar por dos bucles for anidados, lo cual le provocará un grado importante de ocupación y stress al sistema.
gcc stress-c -o stress
Una vez generado el archivo binario, abrimos dos instancias de consola. En la primera ponemos en ejecución a sar tomando 20 pre-informes de rendimiento de sistema cada 5 segundos, así: sar 5 20. Dejamos pasar 10 o 12 segundos y luego en la segunda consola ejecutamos el programa stress mediante el comando ./stress.
Analicemos un poco este informe de rendimiento. Observemos detenidamente los valores de idle y wait. En un principio, al haber invocado primero a sar, dejar pasar unos 10 o 12 segundos y luego invocar al programa stress, los valores de idle y wait indican que hay poco uso de CPU y el sistema de entrada y salida está ocioso. Analizando unas líneas más abajo, más específicamente la línea tres del informe, podemos notar un cambio significativo en el valor arrojado por idle. De estar un 95% desocupado pasa a estar el 54% desocupado. Pasando cinco segundo más, en la línea cuatro, podemos contemplar cómo la CPU se encuentra totalmente sobrecargada, debido a nuestro programa generador de stress, ya que el valor arrojado aquí es del 0%, indicando una sobrecarga abrupta en el sistema. También podemos notar como el valor de wait sube a la par que baja el valor de idle. Esto se debe a que el sistema está procesando (idle) los bucles for de nuestro generador de stress y al mismo tiempo, está escribiendo los valores en un archivo, obviamente utilizando el sistema de entrada/salida (wait). Por último, debido a que en este caso el proceso stress finalizó antes que termine el informe de rendimiento brindado por sar, podemos apreciar cómo los valores idle y wait se van “recuperando” de la sobrecarga del sistema progresivamente.
Puede tener un informe más detallado acerca del Sistema de Entrada/Salida ejecutando el comando sar -d. Básicamente, los campos retornados en este informe son muy intuitivos. Igualmente, si necesita ayuda, consulte la pagina del manual: man sar.
Por otra parte, también podemos combinar múltiples reportes. Por ejemplo, si queremos evaluar el uso de la CPU y la memoria, podemos ejecutar el comando sar -ur. O bien, si desea un informe completo de todo el sistema, use la opción -A de sar.
Este es el uso genérico de esta herramienta. Los distintos informes varían en la información que brindan cada uno, pero la esencia de uso y aplicación en la práctica es absolutamente la misma. Por cuestiones obvias, se hace imposible abordar en detalle todos los informes y variantes que emplea sar. Es por ello que se anima al lector a seguir investigando sobre esta herramienta de suma utilidad.
Configurando el Modo Estático
Como se explicó con anterioridad, el Modo Estático brindado por sar permite que se conforme información acerca del rendimiento del sistema utilizando un archivo basado en cron (/etc/cron.d/sysstat). Para hacer uso de esta función, hace falta habilitarla.
Para empezar a hacerlo, nos dirigimos al directorio /etc/default/ y abrimos con nuestro editor de texto favorito el archivo sysstat. Una vez allí, modificamos la variable ENABLED con el valor “true”. Con esto, estaremos habilitando el Modo Estático Es decir, el script /usr/lib/sysstat/sa1 se ejecutará cada 10 minutos, ya que es su valor por defecto, y recogerá datos de los últimos 7 días, escribiendo un archivo con dichos datos en/var/log/sysstat/saXX.
El número de días a retener se configura en el otro script, el /usr/lib/sysstat/sa2, que hace dos tareas. Por un lado escribe un resumen diario de los parámetros de rendimiento en ficheros de texto plano con nombre sarXX y, por el otro, elimina los ficheros saXX y sarXX de antigüedad anterior a la establecida, algo que se configura en la variable HISTORY del mismo fichero. Nótese la mínima diferencia entre los nombres de los archivos generados por sa1 y sa2.
Por último, nos sería de utilidad saber cómo leer estos archivos generados por los scripts. Como sabemos, el encargado de traducir esta información es sar. Supongamos que nos dirigimos al directorio /var/log/sysstat/ y nos encontramos con el archivo sa28, es decir, un archivo que se ha creado el día 28 del mes en curso. Si queremos leer la información contenida en él, simplemente ejecutamos sar pasándole como parámetro el archivo de información a leer, mediante la opción -f.
En resumen, podríamos leer el archivo empleando el comando sar -f /var/log/sysstat/sa28.
Revisando Informes de manera Visual
Existe una herramienta completamente ajena al paquete sysstat llamada isag (Interactive System Activity Grapher). El mismo es un programa visual que nos permitirá crear gráficas de los datos que tenemos en el sistema, a partir de los informes arrojados por sar. Lo instalamos, lo ejecutamos, elegimos uno de los ficheros de rendimiento y podemos analizar los datos de forma extraordinariamente visual. La Figura 6 muestra un gráfico de isag sobre el uso de la CPU.
Optimizando el Sistema
Luego de realizar y analizar las pruebas de rendimiento correspondientes, llega el momento de llevar a cabo la optimización del sistema. Ésta depende del resultado del análisis en cada sistema, lo cual es algo muy particular. Para poder optimizar un sistema correctamente, se tiene que tener en cuenta como factor principal la saturación de los recursos que posee.
A continuación se deja un listado de algunas de las posibles optimizaciones que le podemos realizar al sistema según los datos obtenidos:
Mucha utilización de CPU: este parámetro básicamente nos lo da el tiempo idle con valores bajos. Con comandos como ps o top podemos verificar cuales son los procesos que se encargan de “devorar” la CPU y tomar decisiones como: posponer su ejecución, pararlos de forma temporal, cambiar la prioridad (comando renice), cambiar de CPU o agregar otra.
Problemas de Memoria Principal: las soluciones básicas para la memoria principal son más que obvias: o se incrementa la capacidad o se reducen las necesidades. Por el coste actual de las memorias, es más adecuado incrementar su tamaño, siempre que esto sea posible, antes que emplear muchas horas para ordenar o reducir requisitos de los procesos en ejecución Reducir los requisitos puede hacerse reduciendo las tablas del kernel, quitando módulos, limitando el número máximo de usuarios, reduciendo buffers, etc. Todo lo cual degradará el sistema (ver Cuadro “El Efecto Burbuja”) y las prestaciones serán peores y en algunas casos, nos estamos arriesgando a que el sistema quede totalmente inoperativo.
Como otro factor, se debe procurar que la memoria principal tenga la suficiente capacidad como para acoger un porcentaje elevado de procesos en ejecución. Si esto no es posible, el sistema operativo podrá paginar e ir al swap, degradando notablemente la ejecución de ese proceso.
Otro aspecto válido es reducir la cantidad de memoria que utilizan los usuarios eliminando procesos redundantes y cambiando la carga de trabajo. Para poder lograrlo, se deberán monitorizar los procesos que están durmiendo (zombies) y eliminarlos, como también aquellos que no progresan en su Entrada/Salida.
También, puede llegarse a un mejor rendimiento modificando el valor de tiempo máximo (quantum) que el scheduler del sistema operativo dedica a cada proceso. Éste es un valor fijo dentro del código del sistema operativo, y es por ello, que es fácil modificarlo, con los riesgos que esto trae aparejado. Para hacerlo, tendremos que remitimos al kernel-source-2.x.x/kernel/sched.c. Para usuarios no tan avanzados (o arriesgados) se recomienda el comando renice.
Problemas relacionados al Disco: después de la memoria, un tiempo de respuesta bajo puede ser debido al sistema de discos. En primer lugar, debe verificarse que se disponga de tiempo de CPU (idle > 20%) y que el número de Entrada/Salida sea elevado. Existen muchos factores para optimizar éstos, los cuales se hacen mención a continuación
En sistemas con un solo disco, generalmente se realiza desde el punto de vista del espacio, cuatro particiones de la siguiente manera: /, swap, /usr y /home. Esto genera pésimas respuesta de Entrada/Salida porque si, por ejemplo, un usuario compila un programa desde su directorio home y el compilador se encuentra en /usr/bin, la cabeza del disco se moverá por toda su longitud. En estos casos, es mejor unir las particiones /urs y /home en una sola más grande, aunque puede llevar aparejado inconvenientes en cuanto al mantenimiento.
Por otro lado, en sistemas multidisco, es buena práctica planificar dónde se encontrarán los archivos más utilizados para equilibrar el trafico hacia ellos y que puedan utilizar todas las capacidades de la Entrada/Salida con cache y concurrente.
También, hay que tener en cuenta que se obtienen mejores prestaciones sobre dos discos pequeños, que uno grande del tamaño de los dos anteriores.
Borrar o comprimir archivos que no se usan muy a menudo puede desembocar en un aumento notable de la capacidad del disco.
Como último consejo, se cae de maduro que el cambio de disco por uno de mayor velocidad (RPM) siempre tendrá un impacto positivo en un sistema limitado por la Entrada/Salida.
Elección de los programas adecuados: esto es fácil y directo. Usar las versiones más eficientes para cada tipo de programa: por ejemplo, por razones obvias, vi es más eficiente que emacs. También, egrep es mas rápido que grep.
Lo mismo ocurre con los gestores de ventana, muchos de los cuales son muy bonitos y agradables, pero no se justifica su consumo excesivo de recursos de sistema. Por ejemplo, GNOME es mucho mas eficiente que KDE, pero no tanto como XFCE. En cuanto a los procesadores de texto, AbiWord consume muchos menos recursos que el legendario OpenOffice.org Write. Lo mismo sucede con los navegadores, sobretodo si tienen la JVM activada.
Estas sencillas observaciones pueden hacer que el sistema mejore notablemente a costo cero.
Conclusión
Como pudimos comprobar en este artículo, tener un sistema realmente optimizado no es tarea fácil Se requieren de muchos conocimientos técnicos y de mucha compresión sobre lo que realmente le está sucediendo al sistema. Solamente, la etapa de identificación del problema es complicada según sea la complejidad del mismo. Luego, recién allí teniendo identificado el problema, podremos dar un diagnóstico y una posible solución para que las cosas mejoren.
No solamente se necesita de sar para poder realizar las revisiones de un problema. También es necesario usar en conjunto herramientas como pueden ser top, ps, vmstat, iostat, free, du, dd, etc.
El valor en tiempo de la muestra de realización de pruebas de rendimiento también toma una fuerte influencia sobre el informe final, el cual debe ser un tiempo considerable, y en lo posible, realizarlo repetidas veces distintos días a diferentes horarios, con el fin de obtener un informe más neutral sobre los instantes donde el sistema posee problemas de rendimiento (si no lo es a toda hora).
En fin, se anima al lector a seguir investigando sobre esta materia, la cual, sin duda es de mucho interés para cualquier informático.