Optimice apache / php / mysql ejecutándose en VPS para cargas pesadas

17

Pregunta sobre la optimización de un servidor apache / mysql en un VPS con 512 m de RAM. Bajo carga normal, todo funciona rápido, sin retraso de conexión. Sin embargo, cuando recibimos nuestros días de tráfico intenso (más de 50k visitas), el sitio se arrastra y tarda más de 30 segundos en recuperar el contenido de Apache.

El sitio se ejecuta en Expression Engine (CMS) (en PHP) y he seguido su guía de optimización de carga pesada. Busqué en Google y seguí bastantes por ahí para apache con un poco de suerte, llevándolo a donde está ahora, pero necesito obtener tiempos de respuesta constantes.

Supongo que esto es diferente de la pregunta 'optimizar para poca memoria' aquí, ya que tengo suficiente RAM (para lo que estoy tratando de hacer), solo necesito hacer que el servidor no se ahogue bajo una carga pesada.

¿Alguna recomendación?

Loros
fuente
1
Solo un seguimiento: se cambió a Lighttpd y la diferencia ya es sorprendente, manejando la carga mucho mejor. Estoy seguro de que habrá más optimizaciones, pero eso ayudó mucho. Y, estaba usando eaccelerator, que había elegido sobre APC, ya que me lo pidieron.
Loros

Respuestas:

18

Para PHP hay 2 cosas importantes que aumentarán la capacidad:

  1. Caché PHP avanzado (APC) como se mencionó. Esto es lo que usamos en Yahoo !. Hay otros proyectos similares, pero este es el bebé de Rasmus.
  2. FastCGI en lugar de mod_php. Existe un debate sobre este tema, ya que mod_php suele ser el más rápido. Sin embargo, supongo que tiene un único servidor Apache que ofrece contenido dinámico de PHP y activos estáticos (JS, CSS, flash, imágenes, PDF, etc.). Las solicitudes de esos activos estáticos no necesitan consumir tanta memoria, pero debido a que PHP es un módulo, está en cada hilo de Apache.

Para Apache:

  1. Usar trabajador MPM
  2. Habilitar KeepAlive

También puede ir tan lejos como para considerar cambiar de Apache a Lighttpd o Nginx . Amo a Apache. Utilizo el tonto de muchas de sus funciones avanzadas. Acepto sus gastos generales porque necesito lo que ofrece. Para la pila LAMP común, es más de lo necesario y un desperdicio de recursos.

Para MySQL:

  1. Sus esfuerzos de optimización rendirán 10 veces cuando se dedique a analizar y corregir consultas, en lugar de modificar sus valores my.cnf. No estoy diciendo que no sea importante corregir el almacenamiento en caché, las conexiones, etc., pero para la mayoría de las personas es solo el 9% del problema.
  2. Durante su control de calidad, active el registro de consultas generales en su puesta en escena / dev mysqld para capturar todas las consultas enviadas. (¡NO haga eso en su servidor mysql de producción!)
  3. Use EXPLAIN para analizar las consultas. Especialmente si está utilizando un marco con un ORM (abstrae la base de datos y le impide escribir su propio SQL), necesitará limpiar uniones extrañas, SELECCIONAR sin cláusula WHERE, ORDER BY que inducen 'usar filesort' y consultas que no usan índices.
  4. Si está utilizando MySQL 5.1, aproveche el generador de perfiles de consulta .

Otras herramientas que vale la pena considerar son mk-visual-explicar

He citado 10 grandes referencias. Estas cosas deberían hacerte tararear. Por favor, háganos saber cómo resulta.

Bruno Bronosky
fuente
6

Mueva sus archivos de sesión PHP a tmpfs , use APC (u otro) y elimine todos los módulos PHP que no necesite. Elimine todos los módulos de Apache que no necesite / use.

Para crear un tmpfs (un directorio en RAM!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs

En / etc / fstab, agregue la línea a continuación para crearla al reiniciar.

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0

¡En /etc/apache2/php.ini, ajuste para almacenar sus sesiones en RAM (tmpfs)!

session.save_handler = files
session.save_path = "/tmpfs"

Nota: ¡Con sus archivos PHP Y archivos de sesión en RAM apenas toca el disco!

Use expires_module en apache para que los navegadores almacenen en caché la mayoría de las cosas.

ExpiresActive On
ExpiresDefault "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/ico "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType text/css "Access plus 90 days"
ExpiresByType text/html "Access plus 90 days"
ExpiresByType application/x-shockwave-flash "Access plus 90 days"
ExpiresByType application/x-javascript "Access plus 90 days"

¡No use archivos .htaccess ! En cambio, codifíquelos en el archivo de configuración de vhost. Eliminará / reducirá drásticamente las comprobaciones de disco por todas las solicitudes http ... realmente suma.

Options FollowSymLinks 
AllowOverride None

Ejemplo de .htaccess utilizado en su archivo vhost.conf ...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>
Anulado
fuente
5

Se me ocurren un par de cosas.

Opcode cache siempre es una buena idea. Prefiero http://eaccelerator.net/ sobre APC. Si no ha estado desarrollando APC en el camino, tratar de agregarlo casi siempre es doloroso. Eaccelerator, aunque no es tan elegante, parece funcionar.

Un proxy inverso también es una buena idea, pero debe observar el uso de RAM. Encuentro Apache 2.2 con mpm-worker para tomar una buena cantidad de RAM por sí mismo. En su caso, recomendaría algo más ligero como Nginx y ejecutar Apache con PHP como FASTCGI o simplemente dejarlo según el proceso. La idea de usar Varnish, Squid, Nginx, etc. es que sirvan contenido estático, se ocupen de las conexiones de los usuarios y solo pasen solicitudes de PHP a Apache, que usted trata como un servidor de aplicaciones.

Si está ejecutando una versión bastante reciente de Mysql 5.1, como al menos 5.1.24, ahora tiene acceso a registros lentos de menos de un segundo. Comenzaría long_query_time en 1 o 2 y luego lo reduciría a 0.5 a medida que maneje los realmente largos. También hay mucha información de ajuste general en la red para Mysql, pero no tienes la RAM para hacer mucho. ¿Has aumentado alguna de las configuraciones por defecto? La mayoría de los archivos my.cnf predeterminados están configurados para usar aproximadamente 64 MB de RAM. Al menos, subiría el key_buffer de 16MB a 64MB.

Además, ¿estás usando las tablas Myisam o Innodb? Si mantiene la sesión en la base de datos, querrá cambiar la tabla de sesión a Innodb (o convertirla en cookie) en lugar de dejarla en una tabla Mysiam que bloquee el nivel de la tabla en lugar del bloqueo de nivel de fila. Básicamente, cualquier tabla que tenga más del 20% de escritura al 80% de lectura es un candidato para pasar a Innodb. Recuerde que necesitará equilibrar la cantidad de RAM entre las tablas Myisam y las tablas Innodb porque las memorias intermedias para cada una se configuran por separado.

Y, por último, otros 512 MB de RAM recorrerían un largo camino en su configuración o incluso otros VPS de 512 MB para ejecutar Mysql si eso es más barato o aproximadamente el mismo precio. De hecho, me inclinaría hacia una segunda instancia porque eso duplicará el disco IO disponible. Uno de los problemas con los servidores VPS es que su IO no está protegida de otras personas en el mismo servidor físico.

Hmmm, mi publicación está muy dispersa, pero te da muchos lugares para buscar. Buena suerte.

kashani
fuente
2
  • Use un caché de código de operación para php como apc.
  • Use un acelerador http como calamar o barniz.
bruja
fuente
1

En una situación de poca memoria (512 Mb es bajo, para un servidor de alto tráfico) vale la pena considerar su elección de servidor web y motor de base de datos.

Lighttp es más claro de fábrica que Apache, por lo general, se puede hacer después de muchos ajustes, e incluso hay opciones más ligeras que eso. Por supuesto, esto no es posible si hay características de Apache de las que depende que no son compatibles con otros servidores.

sqlite es mucho más estricto que mySQL, y también más rápido en muchas condiciones. Comprueba si el motor que estás utilizando es compatible con esto y si lo intenta.

La otra opción, la opción fácil, es obtener más RAM en la VM si puede permitírselo.

David Spillett
fuente
1

Más allá de las excelentes sugerencias aquí, debe tenerse en cuenta que todos los VPS no se crean de la misma manera. En mi experiencia, PHP resultó ser un CPU pesado.

Un Benchmark de Wordpress AB (ab -n 500 -c 25 http://dominio.com/index.php ) de nginx / apc / phpfpm / mysql (local) en EC2 resultó en ~ 2 solicitudes / segundo en su nivel de entrada "2GB Servidor de unidad de cómputo RAM / 1 ".

El mismo Benchmark ejecutado contra la misma pila exacta (implementada por script en un sistema operativo idéntico) en un servidor de Rackspace Cloudserver de 512 MB devuelve ~ 80 req / segundo. Entonces 4x menos ram, 40x rendimiento en este experimento rudimentario.

Al ver la parte superior durante el AB, verá que EC2 simplemente no podía manejar la simultaneidad e inmediatamente alcanzaría el 100% de carga de la CPU y se bloquearía. Viendo la parte superior en el servidor de 512 MB (CPU de cuatro núcleos virtualizada) durante el mismo punto de referencia, los núcleos alcanzarían ~ 60% de carga y manejarían sin problemas el punto de referencia.

Los VPS son extremadamente fáciles de activar y desactivar sin compromiso, ¡no hace daño poner a prueba la infraestructura de su VM / VPS!

EDITAR 1: Además, la instancia pequeña "High CPU" de EC2 solo pudo producir ~ 10 / req segundo, con la CPU siendo el cuello de botella. Mi conclusión fue que sacrificas el rendimiento por la estabilidad / robustez con EC2 y, por supuesto, hay muchos casos de uso que requieren un entorno de este tipo.

iainlbc
fuente
Además, considere nginx (v.1 lanzado hoy). wordpress.com cambió su configuración de velocidad reducida con nginx, por lo que es claramente un servidor web capaz.
iainlbc
Nginx es realmente impresionante. Solo desearía que pudiera leer las reglas mod_rewrite de los archivos .htaccess.
Martijn Heemels