Apache: Alta carga de CPU

Llevo desde el fin de semana con la mosca detrás de la oreja. Uno de los servidores que administro ha visto incrementada de forma inexperada su carga media de CPU sin motivo aparente. Donde el load average normal de 1 minuto variaba entre 0.40 y 0.80 de repente suponía cargas tan elevadas como 60 o 100 unidades.

En esos momentos puntuales que llegaban a dejar la máquina zombie el proceso que abarcaba un consumo de entre el 60% y el 90% de CPU era apache2. Intrigante que ni error.log ni slow-queries.log de MySQL (lo que normalmente suele ser cuello de botella) dieran ninguna pista.[@MORE@]

Analytics tampoco decía nada de un aumento considerable de visitas -más bien al contrario- y el resto de herramientas de monitorización parecían cómplices del problema (¡tener tools para ésto!).

En un alarde de desesperación y viendo más o menos por dónde podían venir los tiros -a través del método de prueba y error- localicé el VirtualHost que estaba dando problemas, un código no auditado y afamado por su ausente optimización. Vamos que ya tenía precedentes, aunque ninguno de esta índole.

Después de desactivar distintas partes del dominio en más pruebas esperando focalizar el error en algún script concreto, la conclusión es que tenía que ser algo que se incluía en todos los archivos, algo común a toda la web. Así que miramos los includes comunes (si, PHP) y llegamos a la conclusión de que era problema de sesiones, sin exculpar al programador.

Una de las primeras acciones de todos los scripts es definir el tiempo de sesión a 3 días, definir el directorio donde se guardarán los archivos de sesión y arrancar la sesión. Probablemente el programador no esperaba tener 60k visitas y más de 200k páginas vistas en los 3 días que dura cada sesión, pero está claro que para apache2 suponía un problema el acceso de lectura/escritura a un mismo directorio con más de 90k archivos.

La solución inicial -a falta de más tiempo para cambiar el sistema de sesiones a memcache, Redis o cualquier otra solución basada en RAM- era sencilla, reducir el tiempo de sesión, vaciar el directorio donde se guardan las sesiones, comprobar de nuevo el load average durante un intervalo representativo y una tarea programada que monitorice el contenido de ese directorio. Después de todo la carga se ha vuelto a estabilizar entre 0.30 y 0.40.

No sé si estoy para moralejas porque la solución es temporal, pero como lo prometido es deuda me gustaría terminar esta anotación advirtiendo a todo el mundo sobre la fiabilidad del código no auditado, el uso moderado de las sesiones y las endorfinas que libera uno cuando consigue resolver algo "así".

sysadmin

About the author

Óscar
has doubledaddy super powers, father of Hugo and Nico, husband of Marta, *nix user, Djangonaut and open source passionate.
  • La verdad es que guardar las sesiones en disco no es problema si no metes cosas grandes en la sesión. Poner memcached para eso es trivial (no hay que tocar el código), te quitas el problema de I/O, y a no ser que las sesiones sean enormes, tampoco hablamos de un consumo de memoria muy alto (ej. 4KB por sesión, a 90K sesiones, tenemos ~351MB en memoria; que es razonable comparado con el coste de cambiar el código).
  • En primera instancia lo que se me pasó por la cabeza fue memcached y después degeneró a Redis o algo NoSQL pero ya te digo que el tiempo es limitado e igual la mejor de las soluciones sea la que propones.
  • Enhorabuena. No es fácil llegar a este tipo de error...Dios nos libre cuando tengamos que buscar en el código.
  • Tenias permiso del programador para modificar su código o violaste sus derechos de autor
  • @xaco Gracias... esperemos que eso nunca pase y si pasa que sea con menor carga de trabajo encima. @xeo Obviamente tenía todo el permiso del mundo, aunque no le veo relación con lo que se describe.
  • Si no tienes interés en tener persistencia en las sesiones (si no paras memcached, no problem), no uses Redis (IMHO).
  • En principio y para este proyecto concreto la persistencia no es requisito indispensable, así que -por lo que dices- blanco y en botella ;).
blog comments powered by Disqus