1. Optimiser la gestion du cache d'un site web
fortement identifié et dynamique
Jean SEMERE
2. Présentation du projet
Mettre en relation des
prêteurs et des micro-
entrepreneurs
Drupal : catalogue de
projets, stockage des
infos perso, gestion du
”panier”, ...
Flexcube : gestion des
comptes prêteurs, des
prêts, et des
remboursements
Drupal ↔ Flexcube :
webservices SOAP
4. Politique de cache
Cache de page : 90%
du trafic en mode
connecté
Cache de blocs :
soulage la DB mais
granularité pas toujours
suffisante
5. Politique de cache
Cache de page : 90%
du trafic en mode
connecté
Cache de blocs :
soulage la DB mais
granularité pas toujours
suffisante
cache_get /
cache_set /
cache_clear_all :
politique de cache
custom pour compléter
le dispositif
6. Cache de pages via Varnish
Varnish : reverse proxy HTTP
Apache : ~50 req/s | Varnish : ~ 3000 req/s
req
req
hit
Apache Varnish resp
miss
Drupal hit
resp Apache
(bootstrap partiel)
miss
Drupal
Drupal (bootstrap full)
(bootstrap full)
resp
resp
7. Pressflow
Drupal 6 : un cookie pour chaque visiteur
(même anonyme) => pas de cache de page
Varnish possible
Pressflow 6 : collection de patches pour D6
Objectif : performance et scalabilité
Entre autres :
Compatibilité Varnish
Support complet de la réplication SQL
Optimisation des requêtes pour MySQL
8. Cache de blocs via Varnish ?
Bloc panier/ par session Bloc statut / par rôle
/ TTL court / TTL infini
Bloc menu / par rôle / TTL quasi infini
Bloc filtres Bloc statistiques
/ global / global
/ TTL infini / TTL long
Bloc projets
/ global
/ TTL court Varnish
10. Caching D6 des blocs
theme_blocks($region)
block_list($region)
Bloc 1 Bloc 2
NO_CACHE PER_ROLE
HTML Bloc 1 Bloc 2
généré Cache ID
HTML Bloc 2
cache_get
lu depuis le cache
HTML Bloc 2
cache_set
généré
11. Caching ESI des blocs
theme_blocks($region)
block_list($region)
Bloc 1 Bloc 2
NO_CACHE PER_ROLE
HTML Bloc 1 Bloc 2
généré Cache ID
<esi:include
src=”/esi-block/cid” />
12. Caching ESI des blocs
theme_blocks($region) /esi-block/cid
hit
HTML Bloc 2
Varnish lu depuis Varnish
block_list($region)
miss
Décodage
du cache ID
Bloc 1 Bloc 2
NO_CACHE PER_ROLE
Restauration partielle
HTML Bloc 1 Bloc 2 du contexte
généré Cache ID
HTML Bloc 2 Assemblage
<esi:include
généré ESI
src=”/esi-block/cid” />
Mise en cache
de l'ESI
13. Caching ESI des blocs
/esi-block/cid
Varnish hit
HTML Bloc 2
Varnish
1 ESI <=> 1 URL lu depuis Varnish
Contexte encapsulé miss
dans l'URL Décodage
du cache ID
Drupal
Cache clé / valeur Restauration partielle
du contexte
Contexte encapsulé
dans la clé de cache HTML Bloc 2 Assemblage
généré ESI
=> Utilisation de la clé
de cache Drupal dans Mise en cache
l'URL de l'ESI de l'ESI
14. Caching ESI des blocs
/esi-block/cid
Infos de session => hit
passage du cookie Varnish HTML Bloc 2
lu depuis Varnish
Paramètres miss
encapsulés dans la Décodage
du cache ID
clé de cache
Gestion des Restauration partielle
du contexte
globales ?
$_GET['q'], etc. HTML Bloc 2 Assemblage
généré ESI
Mise en cache
de l'ESI
15. ESI vs cache Drupal
ESI : cache HTML
Cache Drupal : cache HTML, data, etc
Caches complémentaires, pas concurrents
cache_get / cache_set : pas d'équivalent ESI
En ESI : lookup Varnish / flush Varnish
Mécanisme de lookup builtin dans Varnish
Flush des ESI
Requête HTTP de type PURGE vers Varnish
Surcharge de cache_clear_all pour flusher les ESI
Clés de cache
16. Cache ESI custom
Pas d'équivalent ESI à
cache_get / cache_set
Possibilité de cacher
en ESI n'importe quel
portion de HTML, à
partir du moment où on
générer le HTML offline
dans un contexte
restreint
Exemple : Cache ESI
des displays de nodes
17. Cache ESI custom
Créer une clé de cache pour le HTML à cacher
node:nid:(callback):locale:theme:contexte
Ecrire une fonction qui génère le tag
<esi:include> avec la bonne clé de cache
function esi_inline_node($nid, $callback, $cache, $ttl)
Ecrire la fonction de génération offline du HTML
function esi_render_node()
Ecrire une (ou plusieurs) fonctions de callback
de theming
Flush : cache_clear_all('node:nid', 'cache_inline', TRUE)
18. Impact sur les performances
Tests de charge en cours
Gains observés en phase de dev (en cas de hit
de cache) :
~ 50% de gain en cache de pages vs memcache
~ 30% de gain en cache de blocs vs memcache
~ 50% de gain (dans notre cas) sur le cache
custom vs memcache
Impact sur la scalabilité
Impact en cas de cache miss => importance du
choix de politique de cache