Carnet Wiki

Version 4 — Mars 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 chaine 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 on obtient des 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.
Mais leur amélioration ne doit pas mener à une usine à gaz.

Stratégies possibles

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 les temps d’invalidation sélective par 10 (en moyenne).

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

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.

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. On pourrait définir un plugin standardisé auxquelles devront se conformer les squelettes souhaitant bénéficier de 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 particulier