¿Por qué Apache se vuelve loco y acaba con MySQL?

¿Por qué Apache se vuelve loco y acaba con MySQL?

Apache se salió de control en los últimos días e hizo que MySQL fallara dos veces. Todo comenzó cuando migré un sitio web de WordPress que también contiene un foro phpBB.

No tengo mucha experiencia en administración de servidores, por lo que me ha resultado muy difícil identificar la causa del problema. Cuando noté que MySQL no funcionaba, ejecuté TOP y vi que la carga de mi sistema aumentaba a 98.00. El servidor ejecuta 10 V-HOSTS, todos los cuales reciben una buena cantidad de tráfico, por lo que obviamente vi muchos procesos de Apache-2 ejecutándose.

La alta carga del servidor continuó durante 10 minutos y luego volvió a su estado normal. No vi un aumento en el tráfico de la red en este momento.

Desafortunadamente, el registro de errores de MySQL se deshabilitó (ahora se volvió a habilitar), por lo que no hay pistas al respecto. Pero estoy bastante seguro de que se debe a que Apache estaba consumiendo todos los recursos, por lo que se eliminó el ID del proceso MySQL.

Mis preguntas son:

La próxima vez que esto ocurra, ¿cómo puedo identificar qué está causando el pico de carga del sistema? ¿Podría ser un script php que se volvió loco? ¿Podría ser un ataque DDOS?

¿Existe alguna forma de reiniciar MySQL automáticamente cuando falla?

Ya lo tengo instalado htop. ¿Podría ser esto más útil que top?

Aquí las estadísticas de mi servidor:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 

Respuesta1

Es posible que MySQL aún no registre nada, porque lo que probablemente sucede es que el sistema lo está eliminando sin ceremonias debido a la presión de la memoria del sistema por parte de los hijos de Apache. Debería haber un rastro de esto en /var/log/syslog.

MySQL debería intentar reiniciarse en caso de fallo o terminación forzada, pero a menos que haya suficiente memoria disponible, no puede hacerlo... y mysqld_safe no ve este segundo fallo como un "fallo" sino más bien como una "negativa a empezar", para que no siga intentándolo. Los administradores a menudo malinterpretan el intento fallido de reinicio como el "bloqueo", ya que la naturaleza del error original está oculta detrás de un mensaje que fácilmente se pasa por alto en el registro de errores de MySQL:

mysqld_safe Number of processes running now: 0

VerPost mortem del accidente de InnoDBpor una circunstancia que sospecho es similar a la tuya.

La respuesta aparentemente simple al "por qué" es que entre Apache y MySQL, la carga que tiene y sus configuraciones actuales, no tiene suficiente memoria en la máquina, y hay un punto de inflexión relacionado con la carga de tráfico que saca a relucir esta condición. .

Apache atiende cada solicitud simultánea del navegador desde un proceso hijo, por lo que a medida que aumenta el número de conexiones simultáneas, aumentará el número de hijos. Primero deberá limitar este valor en la configuración de Apache para poder comprender qué está causando realmente el aumento de conexiones simultáneas... ¿es simplemente un aumento de tráfico intenso pero legítimo? ¿Algún tipo de denegación de servicio? ¿Consultas de base de datos que retrasan las solicitudes porque duran demasiado? ¿Algo que necesita optimización?

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

Limitar los procesos concurrentes de Apache debería ayudar a prevenir esto, pero para ser claros, es ingenuo pensar que esta es la solución completa, así que no quiero dar a entender eso. Una vez que los procesos se limitan a un nivel razonable o al menos más seguro, se puede proceder a identificar lo que realmente está sucediendo. (Existen otros controles de restricción en Apache, pero esa no es mi área de especialización).

La "mejor práctica" es, por supuesto, ejecutar su base de datos en un hardware diferente para que la aplicación no pueda eliminarla. Si bien parece más eficiente, en la superficie, "maximizar la utilización" de una máquina compartiéndola, esto es una falsa economía. La mayor parte de la memoria utilizada por MySQL, en una carga de trabajo típica, se asigna en el momento del inicio y se mantiene mientras MySQL Server esté en ejecución. Es probable que las demandas de CPU compartan los tiempos pico para MySQL y Apache, ya que, en última instancia, atienden la misma carga. De hecho, podría estar mejor con dos máquinas m1.large en lugar de una sola m1.xlarge, y el costo sería el mismo ya que la más pequeña cuesta exactamente la mitad del precio de la más grande... incluso si ya pagó por adelantado. por el descuento adicional,este cambio se puede lograr.

Respuesta2

Tienes algunos puntos que comprobar:

-Verifique /var/log/messages: oomkiller puede finalizar el proceso mysql si no hay más memoria para usar. Comprueba la ram con -lm gratis (sin caché)

-Si usas Apache con prefork mpm: verifica el número de procesos. Si Apache acumula una cantidad importante de procesos (durante una carga de trabajo pesada) con un enlace a MySQL, la latencia y la memoria utilizada pueden crecer rápidamente.

-Verificar el número de hilos lanzados por mysql con unmostrar estado global: Es importante comprobar threads_cached, threads_created y threads_running (threads_created debe estar cerca de 0).

-Comprueba la ram utilizada por Mysql.

Respuesta3

También podría considerar implementarconjuntos de CPUy reservar recursos para mysql. Esto es lo más parecido a ejecutar estos servicios en hardware diferente y, al mismo tiempo, brindarle los beneficios de mantener un único servidor.

información relacionada