¿Estrategias para borrar la memoria caché para sitios grandes?

30

Uno de mis sitios de Drupal 7 tiene miles de campos, un montón de tipos de contenido, más de 25 vistas y cientos (que pronto serán miles) de tipos de perfil. Debido a esto, estoy usando un parche central que almacena mejor en caché la información del campo de entidad (http://drupal.org/node/1040790), y la versión -dev de Vistas que almacena mejor en caché las vistas por pantalla (en lugar de tener una ENORME vistas de la fila de caché con todos los datos de vistas en ella).

Esto ha ayudado a que la mayoría de las páginas del sitio se carguen con 20-30 MB de RAM utilizada, en lugar de 160 MB + (en lugar de extraer filas de tabla cache_ * para campos y vistas que eran 10 MB +, los parches ayudan a mantener los datos cache_ * mucho más eficientes).

Sin embargo, esto presenta un problema, ya que las reconstrucciones de caché tardan mucho tiempo . Por lo general, más de un minuto o dos. Y durante este tiempo, Drupal simplemente no cargará ninguna página (dado que las cachés de las que intenta leer aún no están compiladas, otras solicitudes tienen que esperar).

Durante los ciclos de poco tráfico, esto no es un gran problema; aproximadamente cien usuarios simplemente tendrán que esperar un minuto antes de que se cargue la página. Pero durante los ciclos de alto tráfico, el servidor Apache comienza a volverse loco, con más de 40 cargas de CPU, y la memoria se llena rápidamente porque todos los subprocesos de trabajo se sientan a esperar y maximizan su memoria, lo que provoca el intercambio. Es una especie de espiral de muerte. Un reinicio de httpd aclarará las cosas, pero toma de 5 a 10 minutos para que las cosas vuelvan a la normalidad.

Mi objetivo es hacerlo de modo que el borrado de caché no ponga de rodillas al sitio. Por un lado, si utilizo las funciones de limpieza de caché individuales de admin_menu (como "CSS y JS", luego "Menú", luego "Registro de temas", etc.), las cosas van sin problemas hasta que presiono la opción "Página y más". Es entonces cuando se restablece el caché de las vistas (una operación muy intensiva de CPU y base de datos con la cantidad de vistas que deben almacenarse en caché), y cuando se restablece el caché de información de campo (que también es intenso en la CPU y la base de datos en este sitio).

Entonces ... mis preguntas / ideas:

  • Utilizando drush y / u otras secuencias de comandos de shell, ¿es posible para mí borrar cachés de una manera más inteligente que "destruir todos los cachés a la vez y esperar una reconstrucción limpia"?
  • ¿Puedo bloquear las solicitudes http mientras se está borrando la caché para que apache no se obstruya con un montón de solicitudes de sellado de caché?
  • Si puedo borrar cachés fuera de Drupal / solicitud httpd normal, presumiblemente podría establecer un límite de memoria PHP más alto para la operación de borrado de caché, y retroceder mi límite de memoria universal (ahora configurado en 256 MB, en caso de que cualquier hilo httpd individual necesite borrar cachés ...)

Básicamente: ¿Hay alguna forma inteligente y elegante de borrar todos los cachés con Drupal además de simplemente hacer clic en el botón en la interfaz de usuario o usar drush cc all?

[ Editar para aclarar : el principal problema que tengo son las reconstrucciones de caché , que (a) toman un tiempo y (b) bloquean todas las demás solicitudes hasta que se completen las reconstrucciones. Me gustaría encontrar una manera de hacerlo para que las reconstrucciones no sean tan mortales en tiempos de mucho tráfico.]

geerlingguy
fuente
2
Interesante pregunta. Si deshabilita el almacenamiento en caché, ¿es adecuado el rendimiento de su sitio? IOW, ¿ha optimizado Apache / PHP / MySQL para que se ejecute tan bien como puede sin el almacenamiento en caché habilitado? Obviamente, no he visto su sistema, pero configurar apc.stat = 0 y asegurarme de tener suficiente memoria para APC ayudará a reducir el uso del disco. El uso de mysqltuner.pl también le dará una indicación de si MySQL es el cuello de botella. Luego puede activar el almacenamiento en caché y ajustar (aumentará el uso de DB, por lo que es posible que deba ajustar los parámetros de MySQL).
mpdonadio
Utilizo Redis (similar a memcache) para mantener las tablas de caché de vistas en la memoria. Eso mejoró los tiempos de carga drásticamente. Espero tener la función "vistas de caché por pantalla" en una versión estable, eso tiene mucho sentido.
Uwe
@MPD: deshabilitar el almacenamiento en caché mataría rápidamente todo el sitio; típicamente 100-500 usuarios autenticados, y algunas secciones del sitio son bastante pesadas. El mayor problema para mí no son las lecturas de caché (he experimentado con Memcached, Redis y el caché de usuario de APC para eso), sino con la reconstrucción de caché, que es muy intensa en la CPU.
geerlingguy
Idealmente, desea utilizar datos de caché antiguos mientras se reconstruye el nuevo caché. ¿Es esto correcto?
mikeytown2
@ mikeytown2 - correcto, ese sería el ideal.
geerlingguy

Respuestas:

9

¿Hay alguna forma inteligente y elegante de borrar todos los cachés con Drupal además de simplemente hacer clic en el botón en la interfaz de usuario o usar drush cc all?

El módulo de acciones de caché hace eso. Depende de la regla. Por ejemplo, puede configurar una regla para borrar una vista específica cuando se ha agregado o actualizado un nodo de tipo "x". Consulta los documentos para obtener más detalles.

También eche un vistazo al módulo elegante de caché : aún no lo he probado pero parece interesante.

uwe
fuente
Ya estoy usando drush cc [type]para borrar caché específico (similar a las acciones de caché), pero estoy más interesado en encontrar formas de borrar el caché con más gracia y asegurarme de que otros hilos httpd no estén matando al servidor Apache.
geerlingguy
1
parece que drush cc borrará todas las cachés de vistas. Con las acciones de caché, puede borrar una vista o pantalla específica. Probablemente haya un error en la versión de desarrollo de vistas, de lo contrario no tomaría un minuto o dos reconstruir los cachés. ¿Tiene el mismo problema al usar las vistas 7.x-3.5? También echa un vistazo a drupal.org/project/cache_graceful - no han probado aún, pero parece interesante
Uwe
El desarrollador de vistas divide las pantallas de vista en sus propias filas de caché, para ayudar con el rendimiento de lectura de caché. Esto significa que las vistas pasan probablemente 5 veces más tiempo construyendo el caché (¡pero eso ayuda a reducir el uso de memoria al leer mucho los cachés!)
geerlingguy
¿Podría agregar la información sobre Cache Graceful en su respuesta original? Lo aceptaré, ya que ese módulo en particular ayuda un poco (pero no soluciona el problema por completo para mí). Creo que tendré que reorganizar un poco el sitio para usar menos campos y tipos de entidad para solucionar realmente mi problema.
geerlingguy
Okay. Me interesaría conocer su experiencia con cache_graceful. ¿Qué parte no solucionó?
uwe
2

El principal problema es que está utilizando MySQL para almacenar datos de caché; para sitios de alta carga, esta es una solución muy ineficaz.

Aconsejo usar Memcache en su lugar. Esto aumentará dramáticamente el rendimiento del sistema de caché y le dará 2 grandes beneficios:

  1. Memcache es mucho más rápido para las operaciones de lectura y escritura que MySQL: todas las operaciones de caché (y la reconstrucción de caché completa) funcionarán más rápido.
  2. Debido a que los datos de la caché ya no se almacenan en la base de datos, la eliminación de la caché no bloqueará ninguna otra consulta MySQL.

Aquí hay un ejemplo de configuración de Memcache para Drupal 7.

Eugene Fidelin
fuente
He usado Memcached y APC de varias maneras, y aunque ayudan mucho con las lecturas de caché, el principal problema que tengo es la reconstrucción real; la base de datos no está haciendo casi nada mientras el servidor web está estampando el caché durante el proceso de reconstrucción (muy lento / largo).
geerlingguy
APC y Memcached hacen cosas diferentes. Creo que la configuración correcta de Memcached te ayudará. Por cierto, si su sitio es visitado principalmente por usuarios anónimos, puede usar Varnish. En este caso, Varnish utilizará su propio sistema de caché y Apache no se ejecutará para solicitudes anónimas.
Eugene Fidelin
El sitio tiene casi un 100% de tráfico autenticado, de lo contrario, consideraría usar Varnish. Podría ver el módulo Cache Graceful en este punto.
geerlingguy
0

Utilizando drush y / u otras secuencias de comandos de shell, ¿es posible para mí borrar cachés de una manera más inteligente que "destruir todos los cachés a la vez y esperar una reconstrucción limpia"?

Si no desea destruir todos los cachés, use: drush cc type_of_cachepara borrar uno específico o defina el suyo.

Alternativamente, borre todas las tablas tipo caché manualmente, p. Ej.

echo "SHOW TABLES LIKE 'cache%'" | $(drush sql-connect) | tail -n +2 | xargs -L1 -I% echo "DELETE FROM %;" | $(drush sql-connect) -v 

Si está utilizando memcached (sintaxis Bash), intente:

pgrep memcached && echo flush_all > /dev/tcp/127.0.0.1/11211

¿Puedo bloquear las solicitudes http mientras se está borrando la caché para que apache no se obstruya con un montón de solicitudes de sellado de caché?

Habilite el modo de mantenimiento ( drush -y vset maintenance_mode 1) para evitar que las personas accedan al sitio. O configure el front-end para redirigir a otro lugar (por ejemplo, en Varnish, redirigir en Apache o cambiar .htaccess).

Si puedo borrar cachés fuera de Drupal / solicitud httpd normal, presumiblemente podría establecer un PHP más alto memory_limitpara la operación de borrado de caché, y retroceder mi universal memory_limit(ahora configurado en 256 MB, en caso de que cualquier hilo httpd individual necesite borrar cachés ... .).

El borrado de la memoria caché no requiere más memoria, pero la reconstrucción de la memoria caché después del borrado tomará más. Siempre puede calentar los cachés ejecutando cron o abriendo cualquier página, p. Ej.

time php -n -d memory_limit=-1 time $(which drush) cc registry
PHP_OPTIONS='-d memory_limit="2G"' drush cron
php -d memory_limit=1G ./scripts/drupal.sh http://localhost/

Especifique -nignorar el php.iniprocesamiento, que además puede acelerar el proceso de limpieza de caché.

kenorb
fuente
-1

Potencialmente hay un costo monetario involucrado, pero podría usar una configuración de servidor de almacenamiento en caché como Varnish. Lo bueno es que Varnish servirá su sitio mientras su caché se está limpiando en el servidor de producción, sin que el usuario sea más sabio.

La desventaja: dependiendo de cuántos segundos / minutos de tiempo de inactividad del servidor de producción frente a su configuración de tiempo de espera de VCL, Varnish puede actualizarse durante ese tiempo y verá una pantalla de error Varnish 503.

Pero este enfoque junto con Redis o Memcache puede ayudar.

mulderjoe
fuente
Esta pregunta se refiere solo a los cachés internos de Drupal; la reconstrucción de los cachés de Drupal tomó una eternidad, y capas adicionales de almacenamiento en caché fuera / frente a Drupal no harían mucho para ayudar a la reconstrucción de datos de caché real (además de descargar algo de tráfico que el servidor web de otro modo necesitaría mantener durante un tiempo mientras los cachés son reconstruidos)
geerlingguy
En ese caso, encontré que Zend OpCache funcionaba bien. :-)
mulderjoe