Optimizar Apache para uso con WordPress
Saludos,
Tengo un sitio WordPress con más de 150k visitas/día.
Está ejecutándose en un Intel Core i5 CPU 760 @ 2.80GHz, con CentOS y 4 GB de RAM.
El problema es que WordPress consume demasiada RAM y después de un tiempo el servidor se sobrecarga y la RAM se agota. He probado muchos ajustes en Apache pero nada parece funcionar. Después de reiniciar Apache, el sitio funciona sin problemas pero después de una o dos horas se sobrecarga nuevamente.
¿Alguien tiene algún consejo que pueda ayudarme?
Por cierto, estoy usando WP-Super Cache.
ACTUALIZACIÓN: Información adicional
Aquí está mi lista de plugins:
- Akismet
- Contact Form 7
- Domain Mirror
- Faster Image Insert
- IntenseDebate
- Role Manager
- SexyBookmarks
- Smart Youtube
- Star Rating for Reviews
- Thumbnail For Excerpts
- WP-Polls
- WP-SWFObject
- WP Super Cache
En cuanto a los ajustes, he probado algunos consejos de aquí
Mis configuraciones son:
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 200
MaxRequestsPerChild 1000
</IfModule>
<IfModule worker.c>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 1000
</IfModule>
Timeout 120
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
También aquí está mi my.cnf
[mysqld]
set-variable=local-infile=0
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Por defecto se usa el formato de contraseña antiguo para compatibilidad con clientes mysql 3.x
# (aquellos que usan el paquete de compatibilidad mysqlclient10).
old_passwords=1
# Se recomienda deshabilitar los enlaces simbólicos para prevenir varios riesgos de seguridad;
# para hacerlo, descomenta esta línea:
# symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
ACTUALIZACIÓN
Aquí está mi uso actual de memoria
ps -ylC httpd --sort:rss
S UID PID PPID C PRI NI RSS SZ WCHAN TTY TIME CMD
S 504 8446 8444 0 78 0 7884 59507 554050 ? 00:00:00 httpd
S 504 29164 8444 0 78 0 13380 87043 - ? 00:00:00 httpd
[... código abreviado para brevedad ...]
S 504 22354 8444 0 75 0 62124 93962 - ? 00:00:00 httpd
¿Esto cambia lo que me recomendarían?

Souljacker,
Primero revisaría tus plugins. Star Ratings for Reviews no se ha actualizado en más de 3 años y parece que es muy pesado para la base de datos. Vi algunas consultas SQL directas con INNER JOINS que parecen problemáticas.
En el lado del servidor deberías implementar caché de objetos. APC es el estándar de facto y te dará los mejores resultados.
Una vez que instales APC, cambia a W3 Total Cache o Mark Jaquith's APC Object Cache Backend para aprovecharlo al máximo.
La configuración de tu httpd.conf parece correcta. Por lo que veo en tu my.cnf, no estás aprovechando el caché de consultas de MySQL, el caché de hilos ni controlando los tamaños de los buffers.
Puedes usar un script de ajuste para ayudarte con la configuración de my.cnf. Me gusta usar mysqltuner y tuning primer también es muy bueno.
Mysqltuner mostrará sugerencias y te dará algunas pautas sobre qué ajustar según el uso de tu base de datos.
En mi servidor con 12GB de RAM, la configuración luce así. (¡Solo es un ejemplo, no uses estos valores!)
key_buffer = 512M
max_allowed_packet = 32M
thread_stack = 1M
thread_cache_size = 128M
myisam-recover = BACKUP
max_connections = 60
table_cache = 5000
table_definition_cache = 1024
thread_concurrency = 16
# * Configuración del caché de consultas
query_cache_type = 1
query_cache_limit = 4M
query_cache_size = 48M
max_heap_table_size = 512M
tmp_table_size = 512M
join_buffer_size = 3M
sort_buffer_size = 8M
read_buffer_size = 8M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 16M
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 1
Como otros han mencionado, usar Nginx reducirá drásticamente la carga en tu servidor si estás dispuesto a configurarlo. Escribí un tutorial sobre cómo instalar y configurar Apache con Nginx como proxy inverso.
Espero que esto ayude.

wp-supercaché ahora también admite el uso de APC como caché de objetos; sin embargo, tanto para w3 total cache como para wp-supercache, he observado un comportamiento extraño con el almacenamiento en caché de objetos, especialmente en el contexto de usuarios registrados. No estoy seguro de si se trata de algo específico de mi sitio, pero ¡estén atentos y realicen pruebas exhaustivas!

Además, aunque mysqltuner (y también instalar mtop) es útil, descubrí que el mayor aumento de rendimiento ocurrió al activar el registro de consultas lentas y luego usar EXPLAIN para entender por qué ciertas consultas eran lentas.

Echa un vistazo aquí: Consejos de rendimiento para una gran base de usuarios - es un conjunto útil de aspectos a considerar que van más allá de solo Apache.
Cuando buscas optimizar el rendimiento, es bastante importante examinar toda la infraestructura para identificar posibles problemas - por ejemplo, en uno de mis sitios eventualmente rastreé un problema que inicialmente parecía ser de Apache (Apache se quedaba sin memoria bajo carga media) hasta una consulta SQL lenta que se solucionó agregando un índice adicional a la tabla de comentarios.
Además, instala APC u otro caché de código de operación PHP.
[Actualización]
Es bastante probable que tu configuración de MaxClients sea demasiado alta - si los 200 procesos están activos y si en promedio consumen alrededor de 20MB por proceso, eso agota tus 4GB, sin contar MySQL y todos los demás procesos. Reduce la configuración de MaxClients y continúa investigando dónde está tu problema real.
Puedes verificar cuánta memoria está usando cada proceso de Apache con esto:
ps -ylC httpd --sort:rss
(reemplaza httpd por apache2 si estás en Ubuntu)

vota por xcache en lugar de APC, pero estrictamente la versión 1.3.x+

APC es el camino a seguir. Supera a xcache en todas mis pruebas y eventualmente estará incluido con PHP.

sí, según los benchmarks que he visto, la diferencia entre APC y otros aceleradores de op-code es bastante mínima, por lo que la facilidad de instalación y el hecho de que APC está a punto de convertirse en parte de la distribución de PHP (con PHP6) cuentan más para mí, pero lo importante es instalar uno de ellos!

Al revisar Plesk veo SOLO Apache usando excesivamente la memoria. Todo el resto del sistema está utilizando bastante poca memoria.

@souljacker nadie está sugiriendo que MySQL en sí esté utilizando demasiada memoria (es bastante probable que de hecho necesites aumentar la memoria disponible para él). Pero, si lees lo que escribí, las consultas SQL lentas pueden ser una causa de problemas OOM en Apache, ya que los procesos de Apache hacen cola esperando que MySQL responda, por lo que se generan más procesos. Eso no significa que sea tu problema - necesitarás investigar un poco para determinar dónde está el problema.

He instalado APC. ¿Es eso todo? ¿Simplemente instalo o tengo que configurar algo? Parece que nada ha cambiado

Compara Nginx y Apache y toma una decisión:
- http://www.webandblog.com/reviews/apache-vs-nginx-testing-performance-under-heavy-load/
- http://www.joeandmotorboat.com/2008/02/28/apache-vs-nginx-web-server-performance-deathmatch/
- http://blog.webfaction.com/a-little-holiday-present
- y millones de publicaciones más en blogs
Acabo de cambiar de Apache a Nginx y es un trabajo de unos 10 minutos:
- descarga/instala Nginx (wget / yum install / apt-get / ...)
- cambia el archivo de configuración de nginx para que apunte a tu directorio web (ver ejemplos http://kbeezie.com/view/nginx-configuration-examples/ )
- inicia nginx
listo.
También pasé a php-fpm en el mismo proceso, otro trabajo de unos 20 minutos:
- descarga php
- configura con las librerías necesarias (ej. suhosin) (o cambia el código c con tus propios mensajes de broma) (recuerda eliminar las extensiones específicas de apache y recuerda incluir zlib para instalar/descomprimir plugins de wp desde wp)
- configura/compila php
- cambia el archivo de configuración de nginx para incluir llamadas a php-fpm
- inicia php-fpm y reinicia nginx
listo
(agregando archivos /etc/init.d de inicio donde sea necesario)
No he ejecutado pruebas de rendimiento yo mismo, simplemente sigo ciegamente al "resto de ellos"
Fuera del alcance de esta respuesta: También planeo abandonar MySQL y usar MariaDB (GPL) en su lugar.

También podrías obtener un Apache ligero simplemente con una configuración adecuada. No me malinterpretes, Nginx o cualquier otro servidor web ligero como lighthttpd son geniales. Mi consejo es usar Apache para contenido dinámico y un Nginx/lighthttpd para contenido estático.

lo mejor sería si WordPress fuera reescrito en servlets C *guiño* Para dinámico/estático: estoy deslumbrado por los 1000 posts de blog al día sobre diferencias y solo quiero mantener 1 servidor web, más fácil.

Estoy de acuerdo contigo aquí. Mantener un servidor web sigue siendo más fácil que dos. Pero en lugar de desechar Apache e instalar un nuevo servidor web solo porque es "más rápido" en la configuración predeterminada, no es la respuesta.

@Roman Wünsche tal vez podrías compartir algunos consejos sobre cómo obtener una configuración ligera de apache que supere a nginx?

Trabajar con configuraciones prefork y Worker es algo complicado, alterar algunos valores definitivamente ayuda a aumentar el rendimiento y reducir el uso de RAM, también recuerda que Apache reserva algo de RAM, eso no significa que te estés quedando sin RAM. Consulta este artículo para obtener los mejores consejos de optimización.
