Carnet Wiki

Version 6 — March 2018 JLuc

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).

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

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 de la liste. L’invalidation sélective pourrait alors directement spécifier les caches de quelle liste doivent être invalidés.
-  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, puisqu’il n’y aurait aucun rejet (divisés par un facteur 100 ou 1000 ?).

Ces possibilités peuvent se combiner.

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 On pourrait définir un plugin standardisé auxquelles devront se conformer les squelettes souhaitant bénéficier de règles l’invalidation sélective du cache :
-  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