web-dev-qa-db-fra.com

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

Un de mes Drupal 7 sites 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, je suis en utilisant 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'avoir une rangée de cache de vues ÉNORMES 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ée, plutôt que 160 Mo + (au lieu de tirer vers le haut les lignes de la table cache_ * pour les champs et les vues qui étaient 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, les 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 d'effacement 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 de vider 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 demandes http pendant que l'effacement du cache se produit pour qu'Apache ne soit pas obstrué par un tas de demandes de tampon-tampon?
  • Si je peux effacer les caches en dehors de la demande httpd Drupal/normal, je pourrais probablement définir une valeur supérieure PHP memory_limit pour l'opération d'effacement du cache, et reculer mon universal memory_limit (actuellement défini sur 256 Mo, dans cas, chaque thread httpd individuel doit vider 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 ) bloquer toutes les autres demandes 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.]

29
geerlingguy

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 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 le docs pour plus de détails.

Jetez également un œil au module cache graceful - ne l'avez pas encore essayé mais semble intéressant.

9
uwe

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.

2
Eugene Fidelin

À l'aide de drush et/ou d'un autre script Shell, est-il possible pour moi de vider 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 voulez pas faire exploser tous les caches, utilisez: drush cc type_of_cache pour en effacer un spécifique, ou définir 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 demandes http pendant que l'effacement du cache se produit pour qu'Apache ne soit pas obstrué par un tas de demandes de tampon-tampon?

Activer le mode de maintenance (drush -y vset maintenance_mode 1) pour empêcher les gens 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 requête Drupal/normal httpd, je pourrais probablement définir un niveau supérieur PHP memory_limit pour l'opération d'effacement du cache, et reculez 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 ex.

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 -n ignorer php.ini traitement qui peut en outre accélérer le processus de suppression du cache.

0
kenorb