Como se indicó en la introducción, una vez que se ha aplicado las normas de "higiene" en el sistema, tenemos dos posibilidades para mejorar aún más su performance: la configuración de la memoria y la repartición CPU-I/O. Aunque ambos análisis se pueden hacer en paralelo, es muy conveniente hacerlos secuencialmente a fin de cuantificar separadamente el impacto y simplificar las observaciones. Asimismo, es bastante recomendable empezar con la configuración de la memoria, dado que las soluciones por este concepto son más sencillas y menos costosas que en lo concerniente a la repartición CPU-I/O.
Algunos sistemas nunca tienen absolutamente ninguna carencia de memoria. Una forma sencilla de determinar esta situación es observando si han hecho uso del swap. Como se aprecia en el ejemplo, el swap (en este caso de aproximadamente 1200 megabytes) no tiene uso HASTA ESTE MOMENTO, lo que significa que el sistema todavía no ha tenido que recurrir al él por falta de memoria:
sys1$ /sbin/swapon -s Filename Type Size Used Priority /dev/hda7 partition 1228932 0 -1Si esta situación se mantiene a lo largo de muchos días, es indicativo de que dicho sistema probablemente tiene exceso de memoria, o cuando menos, exceso de swap. En estos sistemas, dificilmente podríamos mejorar la performance en lo referente al consumo de memoria.
Normalmente los sistemas experimientan carencias de memoria durante ciertos lapsos en los que se ejecutan determinados procesos pesados. Si estos "períodos de carencia" son breves, entonces no hay mucho que mejorar en cuanto a la falta de memoria. Por el contrario, si los períodos de carencia son prolongados, la performance se puede multiplicar asombrosamente.
En conclusión, el primer paso consiste en determinar si nuestro sistema tiene largos períodos de carencia de memoria (por lo menos de algunos minutos) o si éstos son breves y poco numerosos (de pocos segundos de duración.) Para el primer caso se aconseja una reconfiguración, mientras que para el segundo una reconfiguración mejoraría muy poco la performance del conjunto y probablemente no valdría el esfuerzo.
A continuación se muestra parte de la salida de vmstat para un sistema que inicialmente no tiene carencias de memoria, pero luego de unos segundos sí que las tiene:
$ vmstat 2 ---------memory- ---swap-- -----io---- --system-- ----cpu---- swpd free si so bi bo in cs us sy id wa 67288 478472 188 262 282 279 1037 239 8 1 81 10 67288 478472 0 0 0 0 1002 59 2 0 99 0 67288 478472 0 0 0 0 1001 54 2 0 99 0 67288 478472 0 0 0 24 1010 103 1 0 99 0 67288 478456 0 0 0 0 1017 467 8 1 91 0 67236 102320 34 0 46 16 1023 297 11 54 35 2 72148 3336 1276 4202 2446 4204 1424 459 15 23 0 61 111640 2960 1674 20072 4210 20086 1263 273 1 6 0 93 129996 3208 1960 9180 3622 9180 1190 327 1 4 0 96 129996 3568 3200 0 3862 0 1245 480 1 2 0 97 129996 3176 2454 0 2984 6 1225 414 4 2 0 95 129988 3496 3672 0 4076 68 1328 567 2 2 0 96 129988 2892 3268 0 4396 2 1325 531 0 2 0 97 175224 2768 2864 22664 3186 22710 1309 455 1 7 0 92 175224 3016 2460 0 3030 0 1254 675 5 3 0 92 76508 474376 438 0 478 0 1060 189 2 10 70 20 76508 474388 6 0 6 2 1012 436 8 1 91 1 76508 474404 0 0 0 0 1001 54 2 0 99 0 76508 474408 0 0 0 0 1001 57 1 0 99 0 76508 474408 0 0 0 0 1001 51 2 0 99 0Obviando la primera línea (que son valores acumulados), apreciamos que bajo las columnas 'si' y 'so' (swap in/swap out) los valores permanecen inicialmente en cero, y luego 'so' se dispara; luego de unos instantes 'si' también adquiere valores significativos. Finalmente tras unos 20 segundos, ambas columnas retornan a cero.
Este es un ejemplo típico de un sistema que durante unos segundos experimienta carencia de memoria. Los usuarios de este sistema probablemente experimentarán lentitud en la respuesta durante estos momentos.
¿Qué debemos hacer al respecto? si durante todo el día éste es el único momento de carencia de memoria, entonces cualquier reconfiguración de memoria sólo nos permitiría ganar hasta 20 segundos en todo el mismo día, lo cual es evidentemente despreciable. Si por el contrario, este comportamiento hubiera durado algunas horas, o si ocurriera en muchas ocasiones (que acumulando su duración podría totalizar horas) entonces la reconfiguración sí es aplicable.
Si hemos decidido reconfigurar la memoria a partir del análisis anterior, entonces tenemos esencialmente tres opciones:
Modificar el orden de ejecución de los procesos
Modificar los programas
Ampliar la memoria
Describiremos cada caso por separado.
Este es el primer nivel de solución al problema de la carencia de memoria; es el más sencillo y el que requiere menos inversión.
A modo de ejemplo, considérese un sistema en el cual dos procesos que se ejecutan separadamente uno detrás del otro tardan (en total) cinco minutos en completarse; pero si se ejecutan simultáneamente tardan una hora o más en terminar. Esto ocurre así debido a que cada proceso por separado no introduce al sistema en el régimen de carencia de memoria o lo hace por muy poco tiempo e intensidad, mientras que la combinación de ambos procesos sí lo hace de lleno y la performance se reduce drásticamente.
Este problema ocurre típicamente en sistemas en los que el número de procesos es muy elevado y por simplicidad para los operadores, se prefiere la ejecución simultánea. Evidentemente, la solución consiste en identificar las "combinaciones" que generan el régimen de carencia de memoria y serializar la ejecución.
Las consideraciones acerca de la optimización que se comentaron en la sección de "higiene" son totalmente aplicables aquí. Lamentablemente muchas instalaciones ejecutan programas de terceros o no cuentan con el personal adecuado para este trabajo, por lo que sólo pueden recurrir a la ampliación de la memoria física (ver más abajo.)
En muchos casos (especialmente programas no documentados) este procedimiento puede resultar costoso (en tiempo de honorarios de programación), poco seguro (pues tal vez el programa ya no se puede optimizar mucho en cuanto a su consumo de memoria), y lento (pues la optimización puede resultar complicada y requiere muchas horas de análisis) por lo que también se recurre a la ampliación de la memoria física.
En este caso sólo hay que determinar cuánta memoria se va a agregar. En la mayoría de casos la gente opta por agregar "bancos" de memoria que suelen duplicar la memoria existente, y volver a efectuar el análisis de la performance para cerciorarse de que ya no hay carencia de aquella.
Esta aproximación iterativa es válida, pero en algunos casos es aconsejable tener una idea más exacta (por ejemplo, si el dinero escasea, o si no hay disponibilidad de "bancos" de memoria en el mercado, o si nuestro hardware está casi al límite de su capacidad de crecimiento en memoria.)
Durante la operación del sistema es frecuente que se observen diversos episodios de carencia de memoria de poca importancia, pero que necesariamente irán utilizando nuestro swap. Si volvemos a la salida de vmstat del ejemplo anterior, apreciaremos que antes de que se inicie el período crítico el consumo de swap era de 67288 bloques (también se pudo obtener con swapon -s.) Este consumo se eleva hasta 175224 bloques para luego disminuir gradualmente. Esto quiere decir que el proceso pesado excedió en 175224-67288=107936 bloques la capacidad de nuestra memoria empleando el swap. Por tanto, si agregamos precísamente esta cantidad de memoria física (por ejemplo, un "banco" de 128Mb) el proceso pesado podrá ejecutarse enteramente en RAM[1].
Evidentemente este tipo de análisis requiere bastante paciencia y los resultados pueden ser variables de un día para otro en función de la carga total del sistema.
[1] | De seguro al inicio entraría en el régimen de carencia de memoria dependiendo del consumo que otros procesos hagan de esta, pero tras desplazar a aquellos al swap, el proceso pesado terminaría por completo en la RAM. |