SocialGouv / code-du-travail-numerique

Code du Travail Numérique
https://code.travail.gouv.fr
Apache License 2.0
107 stars 22 forks source link

Partage du cache entre les instances + revalidation des pages statiques suite à une MAJ de la prod #5556

Open maxgfr opened 9 months ago

maxgfr commented 9 months ago

Actuellement, il faut attendre 30 minutes pour que les pages en ISR se reload

Il faudrait syncrhoniser la fin de la prod avec ce processus : https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration#using-on-demand-revalidation

m-maillot commented 9 months ago

Etant donné que l'on a X replicas. Comment s'assurer que le cache a été invalidé par l'ensemble des replicas ?

maxgfr commented 9 months ago

Très bonne question ! De ce que j'ai compris, il faudrait configurer le cache de tel sorte qu'il soit partagé avec tous les pods. Il y a un lien sur la documentation pour faire cela : https://nextjs.org/docs/app/building-your-application/deploying#configuring-caching

maxgfr commented 9 months ago

Dans cette discussion : https://github.com/vercel/next.js/discussions/23017, un mec a configuré ça sur kube de la sorte : https://github.com/vercel/next.js/discussions/38858#discussioncomment-6552331

maxgfr commented 9 months ago

Sur cette documentation : https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration#self-hosting-isr, j'ai trouvé ceci :

By default, generated assets will be stored in-memory on each pod. This means that each pod will have its own copy of the static files. Stale data may be shown until that specific pod is hit by a request. To ensure consistency across all pods, you can disable in-memory caching. This will inform the Next.js server to only leverage assets generated by ISR in the file system.

maxgfr commented 9 months ago

L'autre solution évoqué par les SREs, serait d'utiliser redis comme source de caching partagé entre tous les pods.

Il y a un example ici : https://github.com/vercel/next.js/tree/canary/examples/cache-handler-redis

romain-b13 commented 9 months ago
maxgfr commented 9 months ago

Actuellement, il y a deux limites :

1) La première concerne le fait qu'on a pas de Réplicas sur l'actuel chart qu'on utilise pour redis. Ce qui est un SPOF. La suggestion que je propose serait mettre sur kontinuous cette version du chart de redis proposé par Bitnami

2) La deuxième est l'invalidation des pages statiques. En effet, actuellement lors d'une MAJ des données de la preprod / prod, on ne sait pas quelle page sera à jour. La documentation de next en 14.1 propose cette approche où via l'API on peut mettre à jour manuellement page par page. C'est top lorsqu'on sait exactement quelles sont les pages à mettre à jour. Actuellement, nous ne savons pas le faire. Ainsi, il faut invalider l'ensemble du cache. Lors de mes tests, si on passe par ce endpoint avec p-map, cela fait planter le site car ça demande beaucoup de travail. Le code a été enlevé ici

maxgfr commented 9 months ago

La possibilité pour régler le pattern d'invalidation global des pages serait de rebuilder l'ensemble du site, mais bon c'est pas du tout top. On va pas relancer un build complet du site à chaque MAJ de la preprod ou prod.

Donc, l'option de faire du SSR pour éviter de se casser la tête avec un revalidate (ici, qui a un role de ttl) sur chacune des pages semble être une option envisageable.

Ainsi, on gérererait le cache via un nginx ou autre, où on aurait un endpoint pour invalider l'ensemble du cache.

1) Si on est en SSR, on aurait pas la problématique de page statique non à jour 2) Si on a du cache, il aura juste besoin d'être invalider globalement à chaque MAJ de la prod

Il faudrait voir si on utilise un cache deux paramètres :

A voir 👀

maxgfr commented 9 months ago
  • [x] vérifier que l'admin peut appeler l'api d'invalidation du front pour les pages statiques et le cache

Oui, l'API de revalidation fonctionne bien, mais elle est optimisée pour regénerer page par page. Donc si on revalide tout, ça risque de lagguer

maxgfr commented 9 months ago

@achauve a proposé une solution qui va cacher les routes d'API et le site d'egapro ici : https://github.com/SocialGouv/egapro/pull/2053

La solution semble parfaite pour l'approche SSR + cache

achauve commented 9 months ago

Par contre il faudrait adapter l'approche egapro à cdtn. Pour ça il faudrait avoir la liste des url paths qu'il ne faut pas cacher, s'il y en a. Ensuite pour tous les autres on ignore les headers nextjs et on force le cache nginx sur N minutes.