[SPIP Zone] Plugin de cache efficace

Ayant ajouté un log dans suivre_invalideur sur un de mes sites
je constate que l'invalidation du cache est appelée
plusieurs dizaines voir centaine de fois par jours
sur un fonctionnement avec un nombre modéré d'interactions.

Est ce que ça intéresse qqn de vérifier sur son site ?

Si je comprend bien, ça veut dire que les durées de cache indiquées
#CACHE{10000} ne sont pas souvent utilisées quand il y en a besoin
car le cache est invalidé bien avant leur expiration.
C'est bien cela ?

En conséquence je me demande :
qqn aurait-il conçu un plugin qui surcharge l'invalidation des caches SPIP ?

L'ancien système de cache sélectionnait déjà les caches invalidés
en utilisant le paramètre $cond="objet/id_objet" passé à suivre_invalideur
(paramètres qui n'est plus utilisé désormais)
Il n'est plus utilisé car sa gestion était pas efficace :
les caches étaient en BDD et il fallait faire des requêtes.

Pour ma part je me sers maintenant de memoization avec cache APC.
Cela accélère grandement le parcours des caches et leur invalidation
et leur destruction (sélective ou non).

En reproduisant le fonctionnement de l'ancien cache mais avec memoization
et donc en mémoire directement, pas en BDD,
pensez vous que l'ancienne invalidation sélective redevient efficace ?

Je me dis aussi qu'il est possible de cibler plus précisément encore
les caches invalidés.
Quand on crée un nouvel article (ou objet) on peut vouloir invalider
les caches de
- touts les caches consacrées à cet article spécifiquement (id_article dans le contexte)
- tous les caches des squelettes dont le chemin contient la chaine 'liste'
- éventuellement tous les caches dont le chemin contient un certain mot ('admin' pour un backend maison par exemple)

Le cas échéant, si jamais le format standard de l'argument $cond="id='objet/id_objet'"
était insuffisant pour paramétrer assez finement suivre_invalideur,
ou pourrait aussi l'enrichir avec un format genre
"id='objet/id_objet/regexp_nomducache'" ou "id='objet/id_objet' chemin='regexp_nomducache'"
Par exemple "id='article/1234/(liste|admin|selection)'"
ou "id='article/1234' chemin='(liste/|admin|selection/)'"

JLuc

"There are only two hard things in Computer Science: cache invalidation and naming things."
— Phil Karlton

l’invalidation est appelée quand le contenu éditorial est modifié, donc si tu modifie le contenu éditorial plusieurs dizaines de fois voire centaines de fois par jour oui, ça invalide autant que ça.
Peut-être il y a un abus de ce côté là dans ton cas, à regarder.

Pour ce qui est de l’invalidation selective, c’est une usine à gaz qui n’a pour intérêt que de compliquer énormément toutes les choses.
Il faut se demande à quoi sert le cache et ce qu’on en attends : en l’occurence de la robustesse vis à vis des pics de charge et de l’indisponibilité éventuelle temporaire de la base de donnée.

De ce point de vue être capable de ressortir du cache du contenu vieux de plusieurs heures n’a pas énormément d’intérêt.
Ce qui nous intéresse c’est d’être capable de réduire statistiquement le nombre de hit hors cache vs en cache.

Si tu as 1 hit par seconde et que tu invalides toutes les 10 minutes tu auras donc statistiquement 1 hit hors cache pour 600 hits dans le cache (je fais l’approximationd des concurrences), soit 99,8% de tes hits dans le cache.
Si tu invalide toutes les heures tu passes à 99,97%. Et si tu invalides toutes les 6 heures tu passes à 99,995%.

La question est de savoir combien de charge serveur tu vas économiser en passant de 99,8% à 99,995% de hits dans le cache ?
Et donc du coup combien de charge et d’énergie tu peux allouer à la gestion de l’invalidation d’un cache pour ne pas être perdant ?

En pratique dès qu’on commence à dépenser de l’énergie à calculer quoi invalider on est perdant par rapport à l’espérance de gain…

--

Cédric

On 7 févr. 2018 à 09:22 +0100, JLuc <jluc@no-log.org>, wrote:

Ayant ajouté un log dans suivre_invalideur sur un de mes sites
je constate que l'invalidation du cache est appelée
plusieurs dizaines voir centaine de fois par jours
sur un fonctionnement avec un nombre modéré d'interactions.

Est ce que ça intéresse qqn de vérifier sur son site ?

Si je comprend bien, ça veut dire que les durées de cache indiquées
#CACHE{10000} ne sont pas souvent utilisées quand il y en a besoin
car le cache est invalidé bien avant leur expiration.
C'est bien cela ?

En conséquence je me demande :
qqn aurait-il conçu un plugin qui surcharge l'invalidation des caches SPIP ?

L'ancien système de cache sélectionnait déjà les caches invalidés
en utilisant le paramètre $cond="objet/id_objet" passé à suivre_invalideur
(paramètres qui n'est plus utilisé désormais)
Il n'est plus utilisé car sa gestion était pas efficace :
les caches étaient en BDD et il fallait faire des requêtes.

Pour ma part je me sers maintenant de memoization avec cache APC.
Cela accélère grandement le parcours des caches et leur invalidation
et leur destruction (sélective ou non).

En reproduisant le fonctionnement de l'ancien cache mais avec memoization
et donc en mémoire directement, pas en BDD,
pensez vous que l'ancienne invalidation sélective redevient efficace ?

Je me dis aussi qu'il est possible de cibler plus précisément encore
les caches invalidés.
Quand on crée un nouvel article (ou objet) on peut vouloir invalider
les caches de
- touts les caches consacrées à cet article spécifiquement (id_article dans le contexte)
- tous les caches des squelettes dont le chemin contient la chaine 'liste'
- éventuellement tous les caches dont le chemin contient un certain mot ('admin' pour un backend maison par exemple)

Le cas échéant, si jamais le format standard de l'argument $cond="id='objet/id_objet'"
était insuffisant pour paramétrer assez finement suivre_invalideur,
ou pourrait aussi l'enrichir avec un format genre
"id='objet/id_objet/regexp_nomducache'" ou "id='objet/id_objet' chemin='regexp_nomducache'"
Par exemple "id='article/1234/(liste|admin|selection)'"
ou "id='article/1234' chemin='(liste/|admin|selection/)'"

JLuc

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

Le 07/02/2018 à 09:21, JLuc a écrit :

Je pense aussi qu’on perd plus d’énergie à calculer quels fichiers/caches doivent être invalidés lors de telle ou telle modification, que la stratégie actuelle de dire : une modification = tout le cache à revalider.

Si je comprend bien, ça veut dire que les durées de cache indiquées
#CACHE{10000} ne sont pas souvent utilisées quand il y en a besoin
car le cache est invalidé bien avant leur expiration.
C'est bien cela ?

Sur ce point précis, je pense que la balise #CACHE ne sert pas à grand chose, sauf dans 2 situations :
- tu ne veux aucun cache (0) pour des raisons obscures, mais ça peut arriver,
- tu as du contenu dans le squelette qui dépend de données externes à ton site qui s’actualisent plus fréquemment que celles de ton site (une boucle DATA sur un RSS d’un autre site par exemple) et dans ce cas tu préfères mettre un cache plus court que celui par défaut.

MM.

Le 07/02/2018 à 10:20, cedric@yterium.com a écrit :

"There are only two hard things in Computer Science: cache invalidation and naming things."
— Phil KarltonOuf, on est pas seuls dans l'univers.

Pour ce qui est de l’invalidation selective, c’est une usine à gaz qui n’a pour intérêt que de compliquer énormément toutes les choses.
Il faut se demande à quoi sert le cache et ce qu’on en attends : en l’occurence de la robustesse vis à vis des pics de charge et de l’indisponibilité éventuelle temporaire de la base de donnée.

Ce sont des circonstances critiques mais relativement exceptionnelles
pour lequel le fonctionnement actuel est ok... pour autant que le pic ne dure pas.

Ce qui m'intéresse actuellement, c'est de diminuer la charge serveur au quotidien,
simplement pour bénéficier au mieux des ressources limitées dont on dispose
en s'en servant pour des tâches utiles, comme de "calculer du nouveau"
plutôt que de "calculer des trucs déjà connus dans le passé".

Et donc du coup combien de charge et d’énergie tu peux allouer à la gestion de l’invalidation d’un cache pour ne pas être perdant ?

Ok ce qu'il faut optimiser.

En pratique dès qu’on commence à dépenser de l’énergie à calculer quoi invalider on est perdant par rapport à l’espérance de gain…

Je n'ai pas encore cette pratique mais la décision SPIPienne de tout invalider à chaque changement
a été prise à une époque où la gestion du cache passait par la BDD
et où les caches étaient stockés dans des fichiers,
et c'était donc très coûteux.
Je ne me trompe pas sur le contexte dans lequel s'inscrivait de cette décision ?

Mais dans un autre contexte, avec un cache géré par mémoization par exemple,
les rapports sont très différents, car le coût d'interrogation du cache est bien moindre,
de même que le coût de son filtrage ou nettoyage ciblé.
As tu la pratique avec un cache géré par mémoization ?

JLuc

On 7 févr. 2018 à 09:22 +0100, JLuc <jluc@no-log.org>, wrote:

Ayant ajouté un log dans suivre_invalideur sur un de mes sites
je constate que l'invalidation du cache est appelée
plusieurs dizaines voir centaine de fois par jours
sur un fonctionnement avec un nombre modéré d'interactions.

Est ce que ça intéresse qqn de vérifier sur son site ?

Si je comprend bien, ça veut dire que les durées de cache indiquées
#CACHE{10000} ne sont pas souvent utilisées quand il y en a besoin
car le cache est invalidé bien avant leur expiration.
C'est bien cela ?

En conséquence je me demande :
qqn aurait-il conçu un plugin qui surcharge l'invalidation des caches SPIP ?

L'ancien système de cache sélectionnait déjà les caches invalidés
en utilisant le paramètre $cond="objet/id_objet" passé à suivre_invalideur
(paramètres qui n'est plus utilisé désormais)
Il n'est plus utilisé car sa gestion était pas efficace :
les caches étaient en BDD et il fallait faire des requêtes.

Pour ma part je me sers maintenant de memoization avec cache APC.
Cela accélère grandement le parcours des caches et leur invalidation
et leur destruction (sélective ou non).

En reproduisant le fonctionnement de l'ancien cache mais avec memoization
et donc en mémoire directement, pas en BDD,
pensez vous que l'ancienne invalidation sélective redevient efficace ?

Je me dis aussi qu'il est possible de cibler plus précisément encore
les caches invalidés.
Quand on crée un nouvel article (ou objet) on peut vouloir invalider
les caches de
- touts les caches consacrées à cet article spécifiquement (id_article dans le contexte)
- tous les caches des squelettes dont le chemin contient la chaine 'liste'
- éventuellement tous les caches dont le chemin contient un certain mot ('admin' pour un backend maison par exemple)

Le cas échéant, si jamais le format standard de l'argument $cond="id='objet/id_objet'"
était insuffisant pour paramétrer assez finement suivre_invalideur,
ou pourrait aussi l'enrichir avec un format genre
"id='objet/id_objet/regexp_nomducache'" ou "id='objet/id_objet' chemin='regexp_nomducache'"
Par exemple "id='article/1234/(liste|admin|selection)'"
ou "id='article/1234' chemin='(liste/|admin|selection/)'"

JLuc

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

On 7 févr. 2018 à 15:18 +0100, JLuc <jluc@no-log.org>, wrote:

Le 07/02/2018 à 10:20, cedric@yterium.com a écrit :
> "There are only two hard things in Computer Science: cache invalidation and naming things."
> — Phil KarltonOuf, on est pas seuls dans l'univers.

> Pour ce qui est de l’invalidation selective, c’est une usine à gaz qui n’a pour intérêt que de compliquer énormément toutes les choses.
> Il faut se demande à quoi sert le cache et ce qu’on en attends : en l’occurence de la robustesse vis à vis des pics de charge et de l’indisponibilité éventuelle temporaire de la base de donnée.

Ce sont des circonstances critiques mais relativement exceptionnelles
pour lequel le fonctionnement actuel est ok... pour autant que le pic ne dure pas.

Ce qui m'intéresse actuellement, c'est de diminuer la charge serveur au quotidien,
simplement pour bénéficier au mieux des ressources limitées dont on dispose
en s'en servant pour des tâches utiles, comme de "calculer du nouveau"
plutôt que de "calculer des trucs déjà connus dans le passé".
> Et donc du coup combien de charge et d’énergie tu peux allouer à la gestion de l’invalidation d’un cache pour ne pas être perdant ?

Ok ce qu'il faut optimiser.

Tu fais allègrement l’impasse sur mon calcul d’ordre de grandeur qui te montre justement qu’entre invalider un cache toutes les 10min et invalider un cache toutes les 6 heures tu optimise tout au plus 0.2% de tes hits.
Même en supposant qu’un hit calcul est 10 fois plus couteux qu’un hit en cache, ça te fait un gain potentiel sur tes ressources serveurs de l’ordre de 2%, cela en supposant que ton énergie dépensée à gérer ton invalidation est nulle.

> En pratique dès qu’on commence à dépenser de l’énergie à calculer quoi invalider on est perdant par rapport à
> l’espérance de gain…

Je n'ai pas encore cette pratique mais la décision SPIPienne de tout invalider à chaque changement
a été prise à une époque où la gestion du cache passait par la BDD
et où les caches étaient stockés dans des fichiers,
et c'était donc très coûteux.
Je ne me trompe pas sur le contexte dans lequel s'inscrivait de cette décision ?

Mais dans un autre contexte, avec un cache géré par mémoization par exemple,
les rapports sont très différents, car le coût d'interrogation du cache est bien moindre,
de même que le coût de son filtrage ou nettoyage ciblé.
As tu la pratique avec un cache géré par mémoization ?

Moi je sais pas trop comment avec memoization tu fais pour dire « hé invalide moi tous les caches qui correspondent à l’article 18 » vu que justement c’est un système de stockage clé-valeur, donc tu n’as pas de relationnel ni de structure de requêtes pour ressortir un lot de cache etc.

Enfin moi je dis ça je dis rien…

Maintenant si il s’agit de gérer le passage de certains pics de charge uniquement, tu peux avoir une stratégie relativement triviale et peu couteuse qui consiste à dire
« si mon serveur est plus chargé que tel seuil et que j’ai un cache disponible qui date de moins de 24h je le considère valide même si mon flag derniere_modif me dit que normalement je devrais le mettre à jour »

Avec ça ton site fais le gros dos quand tu as un pic de charge et fonctionne nominalement le reste du temps.
Mais si ton serveur est constamment trop chargé tu perd l’invalidation du cache liés aux modifications éditoriales (et c’est là qu’il est important d’avoir quand même un délai maxi sur le cache, pour assurer que ton site se mettra quand même un peu à jour)

--
Cédric

Merci cerdic et marcimat pour vos réponses qui me permettent de voir les limites du truc
et comment préciser aussi.

Je répond ci après et commence à tester.

Le 07/02/2018 à 17:17, cedric@yterium.com a écrit :

Tu fais allègrement l’impasse sur mon calcul d’ordre de grandeur qui te montre justement qu’entre invalider un cache toutes les 10min et invalider un cache toutes les 6 heures tu optimise tout au plus 0.2% de tes hits.
Même en supposant qu’un hit calcul est 10 fois plus couteux qu’un hit en cache, ça te fait un gain potentiel sur tes ressources serveurs de l’ordre de 2%, cela en supposant que ton énergie dépensée à gérer ton invalidation est nulle.

Effectivement je n'ai pas encore bien intégré ces ratios.

En pratique tout de même, l'efficacité n'atteint pas souvent de 98,5%.
Notamment pendant un usage intensif de l'admin-privé-backend,
les invalidations sont très fréquentes (une par minute par exemple).
Typiquement dans ce cas il serait utile de n'invalider que les squelettes de l'admin
- on peut affiner et préciser quelle partie de l'admin doit être invalidée -.

Moi je sais pas trop comment avec memoization tu fais pour dire « hé invalide moi tous les caches qui correspondent à l’article 18 » vu que justement c’est un système de stockage clé-valeur, donc tu n’as pas de relationnel ni de structure de requêtes pour ressortir un lot de cache etc.

Avec memoization on a un accés rapide au contexte (et à toutes les métadata) associées à un cache.
Il suffit de les passer tous en revue et voir s'il y a id_article=18 dans le contexte.
ça aurait été hyper lent avec filecache mais ça semble raisonnable avec APC Cache
(ou memcache ou reddis probablement).

Dans le cas où on veut invalider les squelettes d'un certain sous-dossier,
il n'y a pas besoin d'accéder au contexte, il suffit de tester le nom du cache,
qui intègre le chemin du cache.
D'où la proposition : que suivre_invalideur reçoive un argument
du format "id='objet/id_objet' chemin='regexp_nomducache'"

Dans mon cas pour le backend il faut tester s'il ya la chaine 'admin' dans le chemin.
Dans le cas du privé de spip, j'ai l'impression que la chaine 'prive' ne suffit pas
(la chaine 'prive' ne se retrouve dans le nom du cache que si c'est une noisette perso pour le privé)
Mais s'il y a à disposition un mécanisme d'invalidation ciblée comme ça,
on peut aussi, ensuite, construire les squelettes en conséquence.
Par exemple, dans mon cas, les squelettes de listes d'objets sont dans un dossier 'liste' :
ça tombe bien car c'est facile à cibler pour invalider chaque fois qu'on crée ou modifie un objet.

Pour les caches qui sont repérés,
on pourrait probablement les invalider spécifiquement en ajoutant un champ 'valide' dans les metadata
(à tester dans la fonction qui vérifie la validité d'un cache)
mais en tout cas il est facile de les vider simplement (mais au détriment de cachecool)
et c'est ce que j'envisageais jusqu'à maintenant.

Par exemple si on veut que tous les squelettes de listes d'objets se mettent à jour dans le public
ainsi que les squelettes avec id_article=18 dans le contexte
ainsi que tout l'admin et le prive
on pourrait demander suivre_invalideur("id='article/18' chemin='liste|admin|prive'")

Maintenant si il s’agit de gérer le passage de certains pics de charge uniquement, tu peux avoir une stratégie relativement triviale et peu couteuse qui consiste à dire « si mon serveur est plus chargé que tel seuil et que j’ai un cache disponible qui date de moins de 24h je le considère valide même si mon flag derniere_modif me dit que normalement je devrais le mettre à jour »

En effet, ça semble assez simple à mettre en place.

Avec ça ton site fais le gros dos quand tu as un pic de charge et fonctionne nominalement le reste du temps.
Mais si ton serveur est constamment trop chargé tu perd l’invalidation du cache liés aux modifications éditoriales (et c’est là qu’il est important d’avoir quand même un délai maxi sur le cache, pour assurer que ton site se mettra quand même un peu à jour)

Pour apprécier "l'énergie" mise pour un filtrage je vais tester le coût d'un filtrage de cache
selon les critères "id_objet dans le contexte" et "chemin dans le nom"
(pour invalidation ciblée ou vidage ciblé)

JL

Le 08/02/2018 à 12:14, JLuc a écrit :

Merci cerdic et marcimat pour vos réponses qui me permettent de voir les limites du truc
et comment préciser aussi.

Je répond ci après et commence à tester.

Voici un échantillon de résultats de mes premiers tests :
- filtrage lors du parcours :
  chemin preg_match (admin|prive|liste) OU contexte contient id_monobjet=18
- à un moment où le rendement du cache est de 87%
- 18000 caches APC parcourus et testés
- 225 chemins trouvés et 185 id_objet trouvés
- non distinction entre cache invalidés ou non (pour le test seulement)
- action entreprise sur les caches résultats : $d['lab_invalide']=true;

-> temps requis, tel qu'indiqué par microtime : 0.5 secondes
    (assez stable pour cette quantité de caches)

Cela infléchit il votre appréciation sur le rendement d'un tel effort,
dans la mesure où ça ne doit se faire qu'à chaque invalidation ?

Et le coût n'est plus que de 0.2 secondes si on ne teste pas id_monobjet=18
(car dans ce cas il n'y a pas besoin d'examiner les metadatas du contenu du cache).

Pour utiliser un tel mécanisme, il y a plein de paramètres ajustables :
- que faire des caches périmés : les vider ou les garder comme maintenant ?
Si on les vide, le parcours pour invalidation devient plus rapide (moins de 0.1 seconde)
car il y a bien moins de cache à parcourir
mais si on les garde on peut les utiliser en cas de pic (effet cachecool temporaire).
- enrichir le format de recherche de l'objet pour l'invalidation (accepter une suite d'objets)
- au contraire, simplifier le format de recherche du chemin pour éviter une regexp

JLuc

Le 07/02/2018 à 17:17, cedric@yterium.com a écrit :

Tu fais allègrement l’impasse sur mon calcul d’ordre de grandeur qui te montre justement qu’entre invalider un cache toutes les 10min et invalider un cache toutes les 6 heures tu optimise tout au plus 0.2% de tes hits.
Même en supposant qu’un hit calcul est 10 fois plus couteux qu’un hit en cache, ça te fait un gain potentiel sur tes ressources serveurs de l’ordre de 2%, cela en supposant que ton énergie dépensée à gérer ton invalidation est nulle.

Effectivement je n'ai pas encore bien intégré ces ratios.

En pratique tout de même, l'efficacité n'atteint pas souvent de 98,5%.
Notamment pendant un usage intensif de l'admin-privé-backend,
les invalidations sont très fréquentes (une par minute par exemple).
Typiquement dans ce cas il serait utile de n'invalider que les squelettes de l'admin
- on peut affiner et préciser quelle partie de l'admin doit être invalidée -.

Moi je sais pas trop comment avec memoization tu fais pour dire « hé invalide moi tous les caches qui correspondent à l’article 18 » vu que justement c’est un système de stockage clé-valeur, donc tu n’as pas de relationnel ni de structure de requêtes pour ressortir un lot de cache etc.

Avec memoization on a un accés rapide au contexte (et à toutes les métadata) associées à un cache.
Il suffit de les passer tous en revue et voir s'il y a id_article=18 dans le contexte.
ça aurait été hyper lent avec filecache mais ça semble raisonnable avec APC Cache
(ou memcache ou reddis probablement).

Dans le cas où on veut invalider les squelettes d'un certain sous-dossier,
il n'y a pas besoin d'accéder au contexte, il suffit de tester le nom du cache,
qui intègre le chemin du cache.
D'où la proposition : que suivre_invalideur reçoive un argument
du format "id='objet/id_objet' chemin='regexp_nomducache'"

Dans mon cas pour le backend il faut tester s'il ya la chaine 'admin' dans le chemin.
Dans le cas du privé de spip, j'ai l'impression que la chaine 'prive' ne suffit pas
(la chaine 'prive' ne se retrouve dans le nom du cache que si c'est une noisette perso pour le privé)
Mais s'il y a à disposition un mécanisme d'invalidation ciblée comme ça,
on peut aussi, ensuite, construire les squelettes en conséquence.
Par exemple, dans mon cas, les squelettes de listes d'objets sont dans un dossier 'liste' :
ça tombe bien car c'est facile à cibler pour invalider chaque fois qu'on crée ou modifie un objet.

Pour les caches qui sont repérés,
on pourrait probablement les invalider spécifiquement en ajoutant un champ 'valide' dans les metadata
(à tester dans la fonction qui vérifie la validité d'un cache)
mais en tout cas il est facile de les vider simplement (mais au détriment de cachecool)
et c'est ce que j'envisageais jusqu'à maintenant.

Par exemple si on veut que tous les squelettes de listes d'objets se mettent à jour dans le public
ainsi que les squelettes avec id_article=18 dans le contexte
ainsi que tout l'admin et le prive
on pourrait demander suivre_invalideur("id='article/18' chemin='liste|admin|prive'")

Maintenant si il s’agit de gérer le passage de certains pics de charge uniquement, tu peux avoir une stratégie relativement triviale et peu couteuse qui consiste à dire « si mon serveur est plus chargé que tel seuil et que j’ai un cache disponible qui date de moins de 24h je le considère valide même si mon flag derniere_modif me dit que normalement je devrais le mettre à jour »

En effet, ça semble assez simple à mettre en place.

Avec ça ton site fais le gros dos quand tu as un pic de charge et fonctionne nominalement le reste du temps.
Mais si ton serveur est constamment trop chargé tu perd l’invalidation du cache liés aux modifications éditoriales (et c’est là qu’il est important d’avoir quand même un délai maxi sur le cache, pour assurer que ton site se mettra quand même un peu à jour)

Pour apprécier "l'énergie" mise pour un filtrage je vais tester le coût d'un filtrage de cache
selon les critères "id_objet dans le contexte" et "chemin dans le nom"
(pour invalidation ciblée ou vidage ciblé)

JL

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

Pour tester j'ai commis un fichier cachelab.

Les 2 fonctions qui parcourent et filtrent le cache selon un pattern paramétrable
(par id_objet dans le contexte ou chaine dans le chemin du cache)
sont visibles là

On peut lister les caches,
leur ajouter un marqueur 'cachelab_mark' (qui pourrait être testé dans une surcharge de cache_valide du core)
ou les vider complètement (les retirer du cache.

microtime mesure les temps et on peut aussi varier la méthode de test du chemin :
avec 3 chemins à tester, strpos est nettement plus rapide que preg_match.

Pour l'instant, c'est pour étude et pas interfacé avec l'invalidation du cache SPIP.

Pour interfacer avec SPIP il faudra surcharger suivre_invalideur.
Il peut y avoir une surcharge standard mais on peut imaginer des surcharges
spécifiques à un site.

Et puis là ça parcourt tous les caches pour trouver ceux qu'il faut invalider
car on n'a à disposition que la liste globale de tous les caches :
c'est pas très efficace puisque la plupart ne sont pas concernés.
On pourrait donc vouloir éviter de tout parcourir pour trouver les caches concernés.
Ça pourrait se faire en gérant des listes de squelettes dont le cache doit être invalidé
dans certaines conditions (par exemple si on ajoute ou modifie un forum / un article
/ un point GIS etc)
À voir comment ces listes seraient alimentées :
- automatiquement, pour les cas simples, lors de la création d'un cache
- en php par des fonctions définissables par le webmestre
- en SPIP par déclaration dans le squelette #INVALIDE_SI{modification, article}
- par un cron qui scannerait la liste et mettrait les listes à jours
...

Pour l'instant c'est dans le plugin xray et pour APC Cache seulement,
mais si ça se continue, car ya plein de trucs à faire plutôt que l'actuel tout ou rien,
ça devrait aller dans un plugin dédié
et être agnostique par rapport à la méthode de cache
(là ya encore quelques références de bas niveau à APC)

JLuc

Le 09/02/2018 à 09:17, JLuc a écrit :

Le 08/02/2018 à 12:14, JLuc a écrit :

Merci cerdic et marcimat pour vos réponses qui me permettent de voir les limites du truc
et comment préciser aussi.

Je répond ci après et commence à tester.

Voici un échantillon de résultats de mes premiers tests :
- filtrage lors du parcours :
chemin preg_match (admin|prive|liste) OU contexte contient id_monobjet=18
- à un moment où le rendement du cache est de 87%
- 18000 caches APC parcourus et testés
- 225 chemins trouvés et 185 id_objet trouvés
- non distinction entre cache invalidés ou non (pour le test seulement)
- action entreprise sur les caches résultats : $d['lab_invalide']=true;

-> temps requis, tel qu'indiqué par microtime : 0.5 secondes
(assez stable pour cette quantité de caches)

Cela infléchit il votre appréciation sur le rendement d'un tel effort,
dans la mesure où ça ne doit se faire qu'à chaque invalidation ?

Et le coût n'est plus que de 0.2 secondes si on ne teste pas id_monobjet=18
(car dans ce cas il n'y a pas besoin d'examiner les metadatas du contenu du cache).

Pour utiliser un tel mécanisme, il y a plein de paramètres ajustables :
- que faire des caches périmés : les vider ou les garder comme maintenant ?
Si on les vide, le parcours pour invalidation devient plus rapide (moins de 0.1 seconde)
car il y a bien moins de cache à parcourir
mais si on les garde on peut les utiliser en cas de pic (effet cachecool temporaire).
- enrichir le format de recherche de l'objet pour l'invalidation (accepter une suite d'objets)
- au contraire, simplifier le format de recherche du chemin pour éviter une regexp

JLuc

Le 07/02/2018 à 17:17, cedric@yterium.com a écrit :

Tu fais allègrement l’impasse sur mon calcul d’ordre de grandeur qui te montre justement qu’entre invalider un cache toutes les 10min et invalider un cache toutes les 6 heures tu optimise tout au plus 0.2% de tes hits.
Même en supposant qu’un hit calcul est 10 fois plus couteux qu’un hit en cache, ça te fait un gain potentiel sur tes ressources serveurs de l’ordre de 2%, cela en supposant que ton énergie dépensée à gérer ton invalidation est nulle.

Effectivement je n'ai pas encore bien intégré ces ratios.

En pratique tout de même, l'efficacité n'atteint pas souvent de 98,5%.
Notamment pendant un usage intensif de l'admin-privé-backend,
les invalidations sont très fréquentes (une par minute par exemple).
Typiquement dans ce cas il serait utile de n'invalider que les squelettes de l'admin
- on peut affiner et préciser quelle partie de l'admin doit être invalidée -.

Moi je sais pas trop comment avec memoization tu fais pour dire « hé invalide moi tous les caches qui correspondent à l’article 18 » vu que justement c’est un système de stockage clé-valeur, donc tu n’as pas de relationnel ni de structure de requêtes pour ressortir un lot de cache etc.

Avec memoization on a un accés rapide au contexte (et à toutes les métadata) associées à un cache.
Il suffit de les passer tous en revue et voir s'il y a id_article=18 dans le contexte.
ça aurait été hyper lent avec filecache mais ça semble raisonnable avec APC Cache
(ou memcache ou reddis probablement).

Dans le cas où on veut invalider les squelettes d'un certain sous-dossier,
il n'y a pas besoin d'accéder au contexte, il suffit de tester le nom du cache,
qui intègre le chemin du cache.
D'où la proposition : que suivre_invalideur reçoive un argument
du format "id='objet/id_objet' chemin='regexp_nomducache'"

Dans mon cas pour le backend il faut tester s'il ya la chaine 'admin' dans le chemin.
Dans le cas du privé de spip, j'ai l'impression que la chaine 'prive' ne suffit pas
(la chaine 'prive' ne se retrouve dans le nom du cache que si c'est une noisette perso pour le privé)
Mais s'il y a à disposition un mécanisme d'invalidation ciblée comme ça,
on peut aussi, ensuite, construire les squelettes en conséquence.
Par exemple, dans mon cas, les squelettes de listes d'objets sont dans un dossier 'liste' :
ça tombe bien car c'est facile à cibler pour invalider chaque fois qu'on crée ou modifie un objet.

Pour les caches qui sont repérés,
on pourrait probablement les invalider spécifiquement en ajoutant un champ 'valide' dans les metadata
(à tester dans la fonction qui vérifie la validité d'un cache)
mais en tout cas il est facile de les vider simplement (mais au détriment de cachecool)
et c'est ce que j'envisageais jusqu'à maintenant.

Par exemple si on veut que tous les squelettes de listes d'objets se mettent à jour dans le public
ainsi que les squelettes avec id_article=18 dans le contexte
ainsi que tout l'admin et le prive
on pourrait demander suivre_invalideur("id='article/18' chemin='liste|admin|prive'")

Maintenant si il s’agit de gérer le passage de certains pics de charge uniquement, tu peux avoir une stratégie relativement triviale et peu couteuse qui consiste à dire « si mon serveur est plus chargé que tel seuil et que j’ai un cache disponible qui date de moins de 24h je le considère valide même si mon flag derniere_modif me dit que normalement je devrais le mettre à jour »

En effet, ça semble assez simple à mettre en place.

Avec ça ton site fais le gros dos quand tu as un pic de charge et fonctionne nominalement le reste du temps.
Mais si ton serveur est constamment trop chargé tu perd l’invalidation du cache liés aux modifications éditoriales (et c’est là qu’il est important d’avoir quand même un délai maxi sur le cache, pour assurer que ton site se mettra quand même un peu à jour)

Pour apprécier "l'énergie" mise pour un filtrage je vais tester le coût d'un filtrage de cache
selon les critères "id_objet dans le contexte" et "chemin dans le nom"
(pour invalidation ciblée ou vidage ciblé)

JL

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

Le 07/02/2018 à 17:17, cedric@yterium.com a écrit :

Moi je sais pas trop comment avec memoization tu fais pour dire « hé invalide moi tous les caches qui correspondent à l’article 18 » vu que justement c’est un système de stockage clé-valeur, donc tu n’as pas de relationnel ni de structure de requêtes pour ressortir un lot de cache etc.

Dans le cache il y a tout le contexte de calcul du cache.

Par exemple (copie du html produit par xray) :

Le cache ...e592219787a85325682e058f4bb5fe2d-breadcrumb/article contient :

[squelette] => html_26ac6d6aa0e77df07a3ca1ca905ee24e
[source] => plugins/prefixeplugin/squelettes/breadcrumb/article.html
[process_ins] => html
[invalideurs] => Array
     (
         [cache] => e592219787a85325682e058f4bb5fe2d-breadcrumb/article
     )

[entetes] => Array
     (
         [X-Spip-Cache] => 86400
     )

[duree] => 0
[texte] => <ol class="breadcrumb"> <li><a href="...">Accueil</a...
[notes] =>
[contexte] => Array
     (
         [page] => article
         [id_article] => 3
         [type-page] => article
         [date] => 2018-02-09 23:45:49
         [date_default] => 1
         [date_redac] => 2018-02-09 23:45:49
         [date_redac_default] => 1
         [id_rubrique] => 47
         [id_secteur] => 45
         [composition] =>
         [lang] => fr
     )

[lastmodified] => 1518216349
[sig] => 1346097260

On peut donc tester le contexte et vériufier si ya id_article=18 dedans.
Par ailleurs le nom du cache 92219787a85325682e058f4bb5fe2d-breadcrumb/article
est fait à partir de son chemin et peut être testé sans même interroger le contenu.

cf lien précédemment indiqué :

JL

Voilà tu commences à rentrer dans le sujet : c’est une voie qui commence par
« oh ce serait pas très compliqué et bien plus efficace »
et très vite on arrive à « ah mais oui mais il y a aussi ces cas là à gérer et… »
et ça finit en usine à gaz.

J’ai pas voulu en rajouter, mais nulle part tu ne traites le problème de « si je modifie l’article 18 ça impact aussi des pages qui n’ont pas id_article=18 dans le contexte, comme par exemple la rubrique parente, la home etc. »

Si tu veux vraiment aller par là tu peux difficilement faire l’impasse sur le plugin Reresher

qui traite du même sujet et qui est un bel exemple de la complexité à laquelle on arrive vite :slight_smile:

--
Cédric

On 10 févr. 2018 à 14:28 +0100, JLuc <jluc@no-log.org>, wrote:

Et puis là ça parcourt tous les caches pour trouver ceux qu'il faut invalider
car on n'a à disposition que la liste globale de tous les caches :
c'est pas très efficace puisque la plupart ne sont pas concernés.
On pourrait donc vouloir éviter de tout parcourir pour trouver les caches concernés.
Ça pourrait se faire en gérant des listes de squelettes dont le cache doit être invalidé
dans certaines conditions (par exemple si on ajoute ou modifie un forum / un article
/ un point GIS etc)

Le 11/02/2018 à 20:47, cedric@yterium.com a écrit :

Voilà tu commences à rentrer dans le sujet : c’est une voie qui commence par
« oh ce serait pas très compliqué et bien plus efficace »
et très vite on arrive à « ah mais oui mais il y a aussi ces cas là à gérer et… »
et ça finit en usine à gaz.

Là où je suis rentré dans du plus compliqué,
c'est en imaginant de gérer des listes spécialisées de caches,
qui seraient automatiquement mises à jours à la création des caches,
et dont les caches seraient automatiquement invalidés après certaines modifications.
Ça suppose que chaque jeu de squelette définisse des règles de sélection
pour constituer les listes, une gestion globale des listes
et une surcharge plus large du noyau spip.

Mais ça, ça vient en plus, en prime, et le reste semble assez simple.
Ça ne semble pas absolument nécessaire
puisque sans ça, on gagne déjà un ou 2 ordres de grandeur en efficacité
en travaillant en mémoire, par rapport à travailler avec des filecaches,
et que ce gain permet de filtrer tous les caches à la recherche de ceux à invalider.

Mais par ailleurs, il me semble que ces listes ont un autre intérêt
(qui m'a décidé à rédiger ce mail) : c'est qu'une telle gestion de listes pourrait *aussi*
servir pour les spip avec filecaches (sans mémoïzation en mémoire vive).
Car sans ces listes de présélections, il est trop coûteux de filtrer tous les filecaches
pour trouver ceux à invalider, mais avec ces listes, ça devient possible même avec filecache
puisqu'il n'y pas de perte pour le filtrage : il faut invalider tous les caches contenus.
Sous réserve de tester, ça élargit beaucoup le champ d'application.

J’ai pas voulu en rajouter, mais nulle part tu ne traites le problème de « si je modifie l’article 18 ça impact aussi des pages qui n’ont pas id_article=18 dans le contexte, comme par exemple la rubrique parente, la home etc. »

Si tout à fait.
Ça me donne l'impression que tu réponds sans vraiment avoir lu.
Ces situations sont traitées par la possibilité d'invalider tous les squelettes
dont le chemin contient une certaine chaîne.

En l'occurence, les 2 exemples que tu évoques contiennent des listes d'articles :
la rubrique parente est une liste d'articles, de même que la home (entre autres choses).
En concevant le squelette, on peut ranger tous ces fichiers squelettes
dans un répertoire dont le nom contient la chaine 'liste',
ou leur donner un nom de fichier contenant la chaine 'liste'.

Ensuite, il suffit de passer 'liste' en argument $chemin de la fonction cachelab_filtre
pour que tous ces caches soient invalidés.
cf Connexion · GitLab

Toutes les listes sont alors invalidées.

C'est plus que nécessaire, mais c'est moins que si on invalide tous les caches,
et la finesse du crible peut se gérer comme on veut,
à la louche, à la petite cuillère ou au plus juste avec un tamis fin,
selon la prise de tête consentie dans l'analyse des besoins des squelettes,
ou selon la puissance du serveur dont on peut librement disposer à perte.

Si tu veux vraiment aller par là tu peux difficilement faire l’impasse sur le plugin Reresher
Refresher - SPIP-Contrib
qui traite du même sujet et qui est un bel exemple de la complexité à laquelle on arrive vite :slight_smile:

En effet, c'est pas simple.

refresher est conçu pour les filecache,
et quand on fonctionne en mémoire, certaines complications sont inutiles
car les parcours de caches sont beaucoup plus rapides.

Je vois que pour le Pull, il faut définir des règles
comme dans le mécanisme plus avancé des listes précalculées.

Je sais pas si je poursuivrai, car on me dit que sur un bon hébergeur
tout ceci n'est pas nécessaire (à confirmer !),
mais j'ai fait un etat des réflexions sur le carnet wiki :

JL

On 10 févr. 2018 à 14:28 +0100, JLuc <jluc@no-log.org>, wrote:

Et puis là ça parcourt tous les caches pour trouver ceux qu'il faut invalider
car on n'a à disposition que la liste globale de tous les caches :
c'est pas très efficace puisque la plupart ne sont pas concernés.
On pourrait donc vouloir éviter de tout parcourir pour trouver les caches concernés.
Ça pourrait se faire en gérant des listes de squelettes dont le cache doit être invalidé
dans certaines conditions (par exemple si on ajoute ou modifie un forum / un article
/ un point GIS etc)

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

Si, si, j’ai bien lu et vu que tu pensais bien invalider les listes/ dans ton lot d’invalidation, mais
* d’une part cela force une convention (qui certes est utilisée dans Z et certains squelettes mais n’a rien d’universel)
* ne couvre pas l’ensemble du problème : tu as plein d'autres cas comme le jumbotron de home ou de rubrique, ou l’article d’accueil de la rubrique qui ne seront pas traités ni vus car la boucle est directement dans le squelette de la rubrique ou de la home, ou la référence à un article similaire sur une page d’un autre article etc…

Le problème principal de la gestion de cache c’est que chaque fois que tu oublies d’invalider quelque chose qui aurait du l’être et que du vieux contenu apparait encore sur le site public cela provoque une insatisfaction et des plaintes d’utilisateurs.

Comprends bien qu’en designant ton système tu es prêt à en comprendre et accepter les limites et les éventuels petits défauts de ce type, les compensant soit par un calcul manuel, soit en laissant vivre et en attendant que cela se mette à jour tout seul.
Mais en livrant un cache de ce type par défaut ce n’est pas du tout le même comportement qu’on récolterait, mais a contrario une insatisfaction exprimée.

L’objectif du cache c’est d’être invisible : il doit améliorer la performance sans impact fonctionnel. Les utilisateurs ne veulent pas un cache il veulent un site qui se met à jour quand ils éditent un article sans être obligé de faire des manipulations supplémentaires.
Partant de là il y a assez peu d’options viables.

Mais une gestion de cache étendue comme tu l’envisages peut être une option proposée aux utilisateurs avancés qui sont conscient des enjeux et gains vs désagréments et pour qui du coup cela ne provoquera pas une insatisfaction.

--
Cédric

On 6 mars 2018 à 05:00 +0100, JLuc <jluc@no-log.org>, wrote:

> J’ai pas voulu en rajouter, mais nulle part tu ne traites le problème de « si je modifie l’article 18 ça impact aussi
> des pages qui n’ont pas id_article=18 dans le contexte, comme par exemple la rubrique parente, la home etc. »

Si tout à fait.
Ça me donne l'impression que tu réponds sans vraiment avoir lu.
Ces situations sont traitées par la possibilité d'invalider tous les squelettes
dont le chemin contient une certaine chaîne.

En l'occurence, les 2 exemples que tu évoques contiennent des listes d'articles :
la rubrique parente est une liste d'articles, de même que la home (entre autres choses).
En concevant le squelette, on peut ranger tous ces fichiers squelettes
dans un répertoire dont le nom contient la chaine 'liste',
ou leur donner un nom de fichier contenant la chaine 'liste'.

Ensuite, il suffit de passer 'liste' en argument $chemin de la fonction cachelab_filtre
pour que tous ces caches soient invalidés.
cf Connexion · GitLab

Toutes les listes sont alors invalidées.

SPIP-Contrib

Bonjour,

Si j'ai bien lu, Refresher - SPIP-Contrib, tout le cache est
invalidé après une activité éditoriale quelconque ?

Cordialement,

Eric

PS : Venant de SPIP 1.8.n, j'avais noté et trouvé cela pratique que le
sommaire se mette à jour par exemple lors de la publication d'un
article. Je ne me doutais que tout était invalidé ?

Le 06/03/2018 à 12:25, eric a écrit :

SPIP-Contrib

Si j'ai bien lu, Refresher - SPIP-Contrib, tout le cache est
invalidé après une activité éditoriale quelconque ?

Ça c'est le fonctionnement normal avec spip, oui.
Et c'est ce qui m'a poussé (et les auteurs de refresher)
à chercher à cibler plus précisément ce qui est invalidé.

JL

Bonsoir,

Chaque fois que je modifie quelque chose, je vérifie si la vitesse du
site varie ou pas.

Je suis avec Gtmetrix, http://www.webpagetest.org/, ... + les outils
habituels de Google.

Avec GtMetrix, webpagetest, pas de soucis, les mesures sont régulières.

Par contre, Analytics me rapporte des mesures avec des écarts
quelquefois important (que je n'arrive pas à reproduire avec les autres
outils). Je vais étudier cela de plus prés. Est ce après invalidation
du cache ?

Je m'informe.

Merci,

Eric

PS :
- en dehors du cache des pages de SPIP, je n'utilise aucun plugin
d'optimisation SPIP.
- j'utilise mod-pagespeed (qui ne cache pas le html, mais seulement les
images ... optimise l'execution des javascripts, les images (webp ...),
et les "tuyaux" pour accélérer le rendu.
- je comptais utiliser Varnish - après avoir rendu le site mobile
Friendly avec Bootstrap 4.

Le mardi 06 mars 2018 à 15:04 +0100, JLuc a écrit :

Le 06/03/2018 à 12:25, eric a écrit :
>
> >
> > SPIP-Contrib
> Si j'ai bien lu, Refresher - SPIP-Contrib, tout le cache
> est
> invalidé après une activité éditoriale quelconque ?
Ça c'est le fonctionnement normal avec spip, oui.
Et c'est ce qui m'a poussé (et les auteurs de refresher)
à chercher à cibler plus précisément ce qui est invalidé.

JL

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zon
e

Hello,

Beaucoup de sujet et de confusion dans la question des performance :
la webperformance (temps d’affichage d’une page) qu’on mesure avec www.webpagetest.org n’a pas grand chose à voir avec le temps de réponse serveur (time to first byte dans webpagetest), avec la charge serveur (consommation moyenne de ressources), avec la gestion des pics de load (tenue à la charge) etc…

Chaque sujet est un vrai sujet, qui nécessite des réponses adaptées en fonction du besoin et de moyens.

Le cache va permettre d’améliorer un peu le TTFB, mais c’est un point qui se discute car on peut argumenter que si on se débarasse de tout le mécanisme de cache le calcul de la page ira plus vite et donc le TTFB sera meilleur (en gros le cache améliore un peu le TTFB quand on sort une page du cache, mais le dégrade quand on doit la calculer).
Mais surtout le cache a pour but d’améliorer la tenue face aux pics de charge car il épargne la connexion SQL et permet de servir plein de hits d’un coup à moindre frais (sans se connecter à SQL).

Pour la webperformance la gestion du cache est absolument anecdotique, c’est la construction des pages qui compte, la minification/concaténation JS et CSS, les medias utilisés etc…

Varnish lui permet d’améliorer la gestion des pics de charge également, en ajoutant un pré-cache statitque devant les appels à apache.
Mais attention : si Varnish est bien capable de servir plein de fois la même page beaucoup plus vite qu’apache (et donc de tenir face à pic de charge), il ralentit le service d’une page à froid (qui n’est pas dans son cache statique ou qui est périmée) puisqu’il ajoute une surcouche.
Il a donc du sens sur un site qui est suceptible de subir un gros trafic inatendu, beaucoup moins sur un site qui a très peu de trafic.

--
Cédric

On 6 mars 2018 à 19:31 +0100, eric <webmaster@opalesurfcasting.net>, wrote:

Bonsoir,

Chaque fois que je modifie quelque chose, je vérifie si la vitesse du
site varie ou pas.

Je suis avec Gtmetrix, http://www.webpagetest.org/, ... + les outils
habituels de Google.

Avec GtMetrix, webpagetest, pas de soucis, les mesures sont régulières.

Par contre, Analytics me rapporte des mesures avec des écarts
quelquefois important (que je n'arrive pas à reproduire avec les autres
outils). Je vais étudier cela de plus prés. Est ce après invalidation
du cache ?

Je m'informe.

Merci,

Eric

PS :
- en dehors du cache des pages de SPIP, je n'utilise aucun plugin
d'optimisation SPIP.
- j'utilise mod-pagespeed (qui ne cache pas le html, mais seulement les
images ... optimise l'execution des javascripts, les images (webp ...),
et les "tuyaux" pour accélérer le rendu.
- je comptais utiliser Varnish - après avoir rendu le site mobile
Friendly avec Bootstrap 4.

Le mardi 06 mars 2018 à 15:04 +0100, JLuc a écrit :
> Le 06/03/2018 à 12:25, eric a écrit :
> >
> > >
> > > SPIP-Contrib
> > Si j'ai bien lu, Refresher - SPIP-Contrib, tout le cache
> > est
> > invalidé après une activité éditoriale quelconque ?
> Ça c'est le fonctionnement normal avec spip, oui.
> Et c'est ce qui m'a poussé (et les auteurs de refresher)
> à chercher à cibler plus précisément ce qui est invalidé.
>
> JL
>
>
> ----
> spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zon
> e
----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zone

Le 06/03/2018 à 09:39, cedric@yterium.com a écrit :

Si, si, j’ai bien lu et vu que tu pensais bien invalider les listes/ dans ton lot d’invalidation,

ok :slight_smile:

mais * d’une part cela force une convention (qui certes est utilisée dans Z et certains squelettes mais n’a rien d’universel)
* ne couvre pas l’ensemble du problème : tu as plein d'autres cas comme le jumbotron de home ou de rubrique, ou l’article d’accueil de la rubrique qui ne seront pas traités ni vus car la boucle est directement dans le squelette de la rubrique ou de la home, ou la référence à un article similaire sur une page d’un autre article etc…

Certes il faut faire du sur mesure.

Par exemple pour être raffraîchi en cas de création d'un nouvel article,
le jumbotron peut être ajouté dans la liste des chemins détectés pour invalidation sélective,
ex : cachelab_filtre ('invalide', 'liste|jumbotron');

Ou bien il peut lui même être rangé dans un dossier dont le nom contient la chaine 'liste'
ce qui serait justifié si c'est un jumbotron tournant.

Par ailleurs le contenu du jumbotron peut inclure une noisette
à laquelle est passée l'id_article retenu,
laquelle sera invalidée à la modification de l'article
avec : cachelab_filtre ('invalide', 'liste|jumbotron', 'article', $id_de_larticle_modifie);

Mais une gestion de cache étendue comme tu l’envisages peut être une option proposée aux utilisateurs avancés qui sont conscient des enjeux et gains vs désagréments et pour qui du coup cela ne provoquera pas une insatisfaction.

ok

Pour des sites qui requièrent déjà le développement d'objets sur mesure,
ou la création de formulaires de saisie ou modification d'objets,
ça ne semble pas un obstacle dans la mesure où est en train de tout concevoir.

Mais ça complique la maintenance plusieurs années ensuite,
car les interventions locales nécessitent une compréhension globale
des relations entre les objets et les différentes parties du site.

JL

Bonjour,

Avant PHP5, j'utilisais Xcache.

Je ne me suis pas encore intéressé à la question avec php7 (Zend
Opcache est configuré et fonctionnel).

Pour Spip memoization, xray, Il faut utiliser APC avec PHP7, et non
Zend OPcache ?

J'ai installé memoization.

J'utilise memcached pour cacher les images, js et tout ce qui peut
l'être (avec mod_pagespeed pour Apache)

J'utilise 2 instances de memcached :

127.0.0.1:11211
127.0.0.1:11212

memoization ne les détecte pas ?

En fait, memoization fait un peu ce que fait PHP avec OPcache / PHP5
avec Xcache ?

J'essaie de comprendre.

Merci,

Eric

Le mercredi 07 février 2018 à 09:21 +0100, JLuc a écrit :

Ayant ajouté un log dans suivre_invalideur sur un de mes sites
je constate que l'invalidation du cache est appelée
plusieurs dizaines voir centaine de fois par jours
sur un fonctionnement avec un nombre modéré d'interactions.

Est ce que ça intéresse qqn de vérifier sur son site ?

Si je comprend bien, ça veut dire que les durées de cache indiquées
#CACHE{10000} ne sont pas souvent utilisées quand il y en a besoin
car le cache est invalidé bien avant leur expiration.
C'est bien cela ?

En conséquence je me demande :
qqn aurait-il conçu un plugin qui surcharge l'invalidation des caches
SPIP ?

L'ancien système de cache sélectionnait déjà les caches invalidés
en utilisant le paramètre $cond="objet/id_objet" passé à
suivre_invalideur
(paramètres qui n'est plus utilisé désormais)
Il n'est plus utilisé car sa gestion était pas efficace :
les caches étaient en BDD et il fallait faire des requêtes.

Pour ma part je me sers maintenant de memoization avec cache APC.
Cela accélère grandement le parcours des caches et leur invalidation
et leur destruction (sélective ou non).

En reproduisant le fonctionnement de l'ancien cache mais avec
memoization
et donc en mémoire directement, pas en BDD,
pensez vous que l'ancienne invalidation sélective redevient efficace
?

Je me dis aussi qu'il est possible de cibler plus précisément encore
les caches invalidés.
Quand on crée un nouvel article (ou objet) on peut vouloir invalider
les caches de
- touts les caches consacrées à cet article spécifiquement
(id_article dans le contexte)
- tous les caches des squelettes dont le chemin contient la chaine
'liste'
- éventuellement tous les caches dont le chemin contient un certain
mot ('admin' pour un backend maison par exemple)

Le cas échéant, si jamais le format standard de l'argument
$cond="id='objet/id_objet'"
était insuffisant pour paramétrer assez finement suivre_invalideur,
ou pourrait aussi l'enrichir avec un format genre
"id='objet/id_objet/regexp_nomducache'" ou "id='objet/id_objet'
chemin='regexp_nomducache'"
Par exemple "id='article/1234/(liste|admin|selection)'"
ou "id='article/1234' chemin='(liste/|admin|selection/)'"

JLuc

----
spip-zone@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-zon
e