Stratégies d'effacement de la mémoire cache pour les grands sites?

30

Un de mes sites Drupal 7 a des milliers de champs, un tas de types de contenu, plus de 25 vues et des centaines (bientôt des milliers) de types de profils. Pour cette raison, j'utilise un correctif principal qui met mieux en cache les informations de champ d'entité (http://drupal.org/node/1040790), et la version -dev de Views qui met mieux en cache les vues par affichage (au lieu d'en avoir un ÉNORME vues ligne de cache avec toutes les données de vues en elle).

Cela a aidé la plupart des pages du site à se charger avec 20 à 30 Mo de RAM utilisés, plutôt que 160 Mo + (au lieu de tirer vers le haut les lignes de la table cache_ * pour les champs et les vues de 10 Mo +, les correctifs aident à garder les données cache_ * beaucoup plus efficaces).

Cela pose cependant un problème dans la mesure où les reconstructions de cache prennent beaucoup de temps . Habituellement, plus d'une minute ou deux. Et pendant ce temps, Drupal ne chargera simplement aucune page (puisque les caches à partir desquels il essaie de lire ne sont pas encore construits, d'autres requêtes doivent attendre).

Pendant les cycles à faible trafic, ce n'est pas un gros problème; une centaine d'utilisateurs devront simplement attendre une minute avant le chargement de la page. Mais pendant les cycles à fort trafic, le serveur Apache commence à devenir fou, avec plus de 40 charges de processeur, et la mémoire se remplit rapidement car tous les threads de travail attendent et maximisent leur mémoire, provoquant un échange. C'est une sorte de spirale de mort. Un redémarrage de httpd éclaircira les choses, mais il faut 5 à 10 minutes pour que les choses reviennent à la normale.

Mon objectif est de faire en sorte que les vides de cache ne mettent pas le site à genoux. D'une part, si j'utilise les fonctions individuelles de suppression du cache d'admin_menu (comme "CSS et JS", puis "Menu", puis "Registre de thème", etc.), les choses se passent bien jusqu'à ce que je clique sur l'option "Page et autre". C'est à ce moment que le cache des vues est réinitialisé (une opération très intensive en CPU et en base de données avec le nombre de vues qui doivent être mises en cache), et lorsque le cache d'informations sur le terrain est réinitialisé (qui est également intense en CPU et en base de données sur ce site).

Alors ... mes questions / idées:

  • À l'aide de drush et / ou d'un autre script shell, est-il possible pour moi d'effacer les caches d'une manière plus intelligente que de "détruire tous les caches à la fois et d'espérer une reconstruction propre"?
  • Puis-je bloquer les requêtes http pendant que l'effacement du cache se produit pour qu'Apache ne soit pas obstrué par un tas de requêtes de tamponnage?
  • Si je peux effacer les caches en dehors de la demande httpd Drupal / normal, je pourrais probablement définir un PHP memory_limit plus élevé pour l'opération d'effacement du cache, et reculer mon universal memory_limit (actuellement défini sur 256 Mo, au cas où un thread httpd individuel aurait besoin d'effacer les caches ...).

Fondamentalement: existe-t-il un moyen intelligent et gracieux d'effacer tous les caches avec Drupal en plus de simplement cliquer sur le bouton dans l'interface utilisateur ou d'utiliser drush cc all?

[ Modifier pour clarification : Le principal problème que j'ai est la reconstruction du cache , qui (a) prend un certain temps et (b) bloque toutes les autres requêtes jusqu'à ce que les reconstructions soient terminées. Je voudrais trouver un moyen de faire en sorte que les reconstructions ne soient pas aussi mortelles pendant les périodes de fort trafic.]

geerlingguy
la source
2
Question interessante. Si vous désactivez la mise en cache, les performances de votre site sont-elles adéquates? IOW, avez-vous optimisé Apache / PHP / MySQL pour qu'il fonctionne aussi bien qu'il peut sans mise en cache activée? Évidemment, je n'ai pas vu votre système, mais définir apc.stat = 0 et vous assurer que vous avez suffisamment de mémoire pour APC aidera à réduire l'utilisation du disque. L'utilisation de mysqltuner.pl vous donnera également une indication si MySQL est le goulot d'étranglement. Ensuite, vous pouvez activer la mise en cache et modifier (cela augmentera l'utilisation de la base de données, vous devrez donc peut-être ajuster les paramètres MySQL).
mpdonadio
J'utilise Redis (similaire à memcache) pour garder les tables de cache des vues en mémoire. Cela a considérablement amélioré les temps de chargement. Dans l'attente d'avoir la fonctionnalité "vues cache par affichage" dans une version stable, cela a beaucoup de sens.
uwe
@MPD - La désactivation de la mise en cache tuerait rapidement l'ensemble du site; généralement 100 à 500 utilisateurs authentifiés, et certaines sections du site sont assez lourdes. Le plus gros problème pour moi n'est pas les lectures du cache (j'ai expérimenté avec Memcached, Redis et le cache utilisateur APC pour cela), mais avec la reconstruction du cache, qui est très gourmande en CPU.
geerlingguy
Idéalement, vous souhaitez utiliser les anciennes données de cache pendant la reconstruction du nouveau cache. Est-ce correct?
mikeytown2
@ mikeytown2 - correct - ce serait l'idéal.
geerlingguy

Réponses:

9

Existe-t-il un moyen intelligent et gracieux d'effacer tous les caches avec Drupal en plus de simplement cliquer sur le bouton dans l'interface utilisateur ou d'utiliser drush cc all?

Le module des actions de cache fait cela. Cela dépend de la règle. Par exemple, vous pouvez configurer une règle pour effacer une vue spécifique lorsqu'un nœud de type "x" a été ajouté ou mis à jour. Consultez les documents pour plus de détails.

Jetez également un œil au module gracieux du cache - je ne l'ai pas encore essayé mais il semble intéressant.

uwe
la source
J'utilise déjà drush cc [type]pour l'effacement de cache spécifique (similaire aux actions de cache), mais je suis plus intéressé à trouver des moyens d'effacer le cache plus gracieusement et à m'assurer que les autres threads httpd ne tuent pas le serveur Apache.
geerlingguy
1
ressemble à drush cc effacera tous les caches de vues. Avec les actions de cache, vous pouvez simplement effacer une vue ou un affichage spécifique. Il y a probablement un bogue dans la version dev des vues, sinon cela ne prendrait pas une minute ou deux pour reconstruire les caches. Avez-vous le même problème lors de l'utilisation des vues 7.x-3.5? Jetez également un œil à drupal.org/project/cache_graceful - ne l'avez pas encore essayé mais semble intéressant
uwe
Le développeur de vues répartit les affichages de la vue dans leurs propres lignes de cache, pour améliorer les performances de lecture du cache. Cela signifie que les vues passent probablement 5 fois plus de temps à construire le cache (mais cela aide à réduire l'utilisation de la mémoire lors de la lecture des caches!).
geerlingguy
Pourriez-vous ajouter les informations sur Cache Graceful dans votre réponse d'origine? Je l'accepterai, car ce module particulier aide un peu (mais ne résout pas le problème entièrement pour moi). Je pense que je vais devoir refaire un peu le site pour utiliser moins de champs et de types d'entités afin de vraiment résoudre mon problème.
geerlingguy
D'accord. Je serais intéressé de connaître votre expérience avec cache_graceful. Quelle partie n'a-t-elle pas corrigé?
uwe
2

Le principal problème est que vous utilisez MySQL pour stocker des données de cache - pour les sites à forte charge, cette solution est très inefficace.

Je conseille d'utiliser Memcache à la place. Cela augmentera considérablement les performances du système de cache et vous donnera 2 grands avantages:

  1. Memcache est beaucoup plus rapide pour les opérations de lecture et d'écriture que MySQL - toutes les opérations de cache (et la reconstruction complète du cache) fonctionneront plus rapidement.
  2. Parce que les données du cache ne sont plus stockées dans la base de données - l'effacement du cache ne bloquera aucune autre requête MySQL.

Voici un exemple de configuration Memcache pour Drupal 7.

Eugene Fidelin
la source
J'ai utilisé memcached et APC à la fois, de diverses manières, et bien qu'ils aident grandement aux lectures de cache, le principal problème que j'ai est la reconstruction réelle; la base de données ne fait presque rien pendant que le serveur Web tamponne le cache pendant le processus de reconstruction (très lent / long).
geerlingguy
APC et Memcached font des choses différentes. Je pense que la configuration correcte de Memcached vous aidera. BTW, si votre site est principalement visité par des utilisateurs anonymes - vous pouvez utiliser Varnish. Dans ce cas, Varnish utilisera son propre système de cache et Apache ne sera pas exécuté pour les requêtes anonymes.
Eugene Fidelin
Le site a presque 100% de trafic authentifié, sinon j'envisagerais d'utiliser Varnish. Je pourrais examiner le module Cache Graceful à ce stade.
geerlingguy
0

À l'aide de drush et / ou d'un autre script shell, est-il possible pour moi d'effacer les caches d'une manière plus intelligente que de "détruire tous les caches à la fois et d'espérer une reconstruction propre"?

Si vous ne souhaitez pas détruire tous les caches, utilisez: drush cc type_of_cachepour effacer un cache spécifique ou définissez le vôtre.

Vous pouvez également effacer manuellement toutes les tables de type cache, par exemple

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

Si vous utilisez memcached (syntaxe Bash), essayez:

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

Puis-je bloquer les requêtes http pendant que l'effacement du cache se produit pour qu'Apache ne soit pas obstrué par un tas de requêtes de tamponnage?

Activez le mode de maintenance ( drush -y vset maintenance_mode 1) pour empêcher les personnes d'accéder au site. Ou configurez le frontal pour rediriger ailleurs (par exemple dans Varnish, rediriger dans Apache ou changer .htaccess).

Si je peux effacer les caches en dehors de la demande httpd Drupal / normal, je pourrais probablement définir un PHP plus élevé memory_limitpour l'opération d'effacement du cache, et reculer mon universel memory_limit(actuellement défini sur 256 Mo, au cas où un thread httpd individuel aurait besoin d'effacer les caches .. .).

L'effacement du cache ne prend pas plus de mémoire, mais la reconstruction du cache après l'effacement en prendra plus. Vous pouvez toujours réchauffer les caches en exécutant cron ou en ouvrant n'importe quelle page, par exemple

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/

Spécifiez -npour ignorer le php.initraitement qui peut en outre accélérer le processus d'effacement du cache.

kenorb
la source
-1

Il y a potentiellement un coût monétaire, mais vous pouvez utiliser une configuration de serveur de mise en cache comme Varnish. L'avantage est que Varnish servira votre site pendant que votre cache s'efface sur le serveur de production, sans que l'utilisateur soit le plus sage.

L'inconvénient: selon le nombre de secondes / minutes d'indisponibilité du serveur de production par rapport à vos paramètres de délai d'expiration VCL, Varnish peut se mettre à jour pendant ce temps et vous verrez un écran d'erreur Varnish 503.

Mais cette approche avec Redis ou Memcache peut aider.

mulderjoe
la source
Cette question ne concerne que les caches Drupal internes; la reconstruction des caches de Drupal a pris une éternité, et des couches supplémentaires de mise en cache en dehors de / devant Drupal ne feraient pas grand-chose pour aider à la reconstruction des données de cache réelles (en plus de décharger du trafic que le serveur Web aurait autrement besoin de garder pendant un peu pendant la mise en cache sont reconstruits).
geerlingguy
Dans ce cas, j'ai trouvé que Zend OpCache fonctionnait bien. :-)
mulderjoe