Carnet Wiki

Version 10 — March 2018 — 78.242.xx.xx

Laboratoire du cache

Cachelab permet d’expérimenter et tester diverses stratégies de cache lorsqu’on emploie mémoization et un cache en mémoire : APC, memcache, redis aussi peut être

L’expérimentation porte surtout le ciblage de l’invalidation du cache

cachelab.php est un fichier du plugin xray qui commence à implémenter les fonctions utiles. Il est valable, pour l’instant, uniquement pour APC cache mais vise à passer par l’API de memoization et donc être disponible pour toutes les mémoizations en mémoire.

Les fonctions cachelab_filtre et cachelab_applique permettent d’invalider sélectivement une liste de caches selon plusieurs critères :
-  présence d’une ou plusieurs chaines dans le chemin du squelette.
-  présence d’une variable avec une certaine valeur dans l’environnement du cache.

Ces 2 fonctions sont utilisables dans un code php pour faire une invalidation sélective des caches.

cachelab.php les utilise pour permettre l’étude de ces filtrage et invalidations sélectives :
-  commande par les paramètres passés dans l’url
-  mesure des microtimes

Lors des tests les temps de filtrage sont de l’ordre de .1 à .5 secondes lorsqu’il y a 10000 à 20000 caches en mémoire. C’est supportable lorsque le filtrage et l’invalidation n’ont lieu qu’à la demande lorsqu’on crée ou modifie un contenu, mais il serait intéressant tout de même de limiter cet impact.

Limites de l’expérimentation

Si en moyenne 98% des squelettes sont en cache, alors il est peu utile de cibler précisément quels caches doivent être invalidés (cf explications de cerdic , et dans la discussion sur la zone).

Mais en pratique, xray montre des taux de rendement du cache bien moindres (rapport : nombre d’accés en cache / nombre d’accés total). À part pour les fichiers js compressés et css, le taux n’atteint jamais 98%.

Mais en pratique, xray montre des taux de rendement du cache bien moindres (rapport : nombre d’accés en cache / nombre d’accés total). Le rendement du cache est d’autant plus faible que les internautes créent souvent des articles, ou déposent un commentaire... ou même ajoutent ou retirent un favori avec le plugin favoris, car tous les caches sont invalidés à chacune de ces opérations !

Cerdic attire l’attention sur le coût de l’invalidation sélective. Il pointe aussi le plugin refresher comme exemple de complexité dissuasive.

Les premières lignes jetées pour cachelab sont pourtant simples et procurent déjà de bons résultats en situation d’étude. Il faudra veiller à ce que leur amélioration ne mène pas à une usine à gaz.

Stratégies possibles

Toutes les stratégies évoquées ci après peuvent se combiner.

garbage collector

En l’état actuel, 90% des caches sont périmés en général. Il serait intéressant de les effacer et de ne retenir que les caches valides. On diviserait par 10 (en moyenne) les temps de recherche pour invalidation sélective.

Ce garbage collector peut se faire soit au fur et à mesure qu’on découvre des caches invalides, soit globalement en cron.

cachecool

On pourrait au contraire souhaiter garder les caches invalides et les utiliser à la demande, comme fait cachecool. Cela n’atténue pas la charge sur le serveur, mais ça donne l’impression d’un service plus rapide.

On peut combiner les 2 approches :
-  les caches périmés sont supprimé par cron toutes les X secondes ou minutes
-  dans l’intervalle, les caches périmés sont quand même servis. L’utilisateur doit être averti qu’il doit parfois attendre un peu pour que les affichages soient mis à jour.

listes ciblées

Une autre possibilité serait de constituer des listes ciblées : sous-ensembles pré-filtrés de caches. Une telle liste de caches serait alimentée au moment de la création d’un cache, lorsque ce dernier satisfait les critères définissant la liste. L’invalidation sélective pourrait alors directement spécifier les caches de quelle liste doivent être invalidés, en paramètre de suivre_invalideur.
-  Il y aurait un surcoût lors de la création d’un cache, pour préfiltrer le cache. Mais ce surcoût semble très réduit.
-  Les temps d’invalidation seraient alors énormément réduits (divisés par un facteur 100 ou 1000 ?), puisqu’il n’y aurait aucun filtrage requis. Tout le parcours serait utile.

Cette possibilité semble intéressante même pour filecache, lorsque le cache ne se fait pas en mémoire mais sur le disque.

pipeline suivre_invalideur

Un pipeline suivre_invalideur permettrait d’obtenir un changement de fonctionnement restreint, sans surcharger tout le fichier.

Selon les sites et les objets

Les stratégies d’implémentation dépendent des sites et des objets utilisés.

Il semble possible de déployer une stratégie optimisée dans le code php qui implémente un objet lorsque ce code est conçu “sur mesure” pour un site donné.

Ça semble plus difficile pour des objets génériques qui ne préjugent rien du contexte d’utilisation. La stratégie par défaut de SPIP à l’heure actuelle reste peut être bien la meilleure dans ces cas là.

Un entre-deux semble possible toutefois pour les squelettes généralistes de SPIP : dist, spipr, escale, SC, sarka...

Enfin, on peut imaginer définir un ensemble de convention de nommage des dossiers et fichiers permettant d’implémenter des régles standard de filtrage et invalidation ciblée du cache. Sur la base de ces conventions, on pourrait définir un plugin standardisé auquel auraient recours les squelettes se conformant aux conventions et souhaitant bénéficier de l’invalidation sélective du cache.
Exemple de règles :
-  nom de dossiers contenant ’liste_monobjet’ pour contenir les listes de monobjet devant être invalidées lorsqu’on crée, supprime ou modifie un monobjet
-  noms de squelettes contenant ’monobjet’ lorsqu’il faut filtrer pour les invalider sélectivement lorsqu’on crée, supprime ou modifie un monobjet avec un id_monobjet particulier