Deuxième article de notre série des­ti­née à vous pré­sen­ter les nou­veau­tés de notre reverse-proxy HTTP. Après le pare-feu appli­ca­tif, nous vous pré­sen­tons le cache HTTP fron­tal que nous avons inté­gré à notre infra­struc­ture.

punch it star trek GIF @Giphy

Un cache HTTP, qu’est-ce que c’est ?

Un graphique vaut mieux qu’un long discours

Nous avons tes­té les per­for­mances de notre cache fraî­che­ment inté­gré à notre proxy sur notre blog, ser­vi par une appli­ca­tion WordPress. Le résul­tat obte­nu nous laisse à pen­ser que cette fonc­tion­na­li­té va vous plaire.

Le nombre de requêtes ser­vies par seconde aug­mente consi­dé­ra­ble­ment lorsqu’on active notre cache, pas­sant de 15 req/s à 2604 req/s, soit 173 fois plus de requêtes ser­vies sur une même durée. Le temps mis pour obte­nir la réponse à une requête baisse d’autant, pas­sant de 63.65ms à 0.38ms en moyenne. Intéressant, et très simple à acti­ver !

Nous avons réa­li­sé ce bench­mark avec ApacheBench en fai­sant des requêtes vers la page d’accueil de ce blog. Nous avons exé­cu­té chaque tir1) quatre fois pour chaque confi­gu­ra­tion, avec et sans cache, avant de faire la moyenne des résul­tats obte­nus. Ce blog est héber­gé sur un ser­veur dédié, les dif­fé­rences de per­for­mances mesu­rées sur un ser­veur mutua­li­sé seront du même ordre. Vous pou­vez d’ailleurs faire vos propres tests en vous connec­tant en SSH à votre ser­veur, et en exé­cu­tant la com­mande ab avec les mêmes options sur une page de votre site.

Fonctionnement d’un cache

Le cache désigne un sys­tème de sto­ckage tem­po­raire de don­nées dans le but d’en accé­lé­rer le trai­te­ment ulté­rieur. Un cache HTTP s’occupe de sto­cker tem­po­rai­re­ment des docu­ments web comme les pages HTML, les docu­ments CSS, les images, etc. Ce méca­nisme est prin­ci­pa­le­ment uti­li­sé pour dimi­nuer la latence induite par le ser­veur lorsqu’il doit ser­vir une page et/ou réduire sa charge de tra­vail.

Lorsqu’un client demande une page à un ser­veur web, ce der­nier va géné­rer une page et l’envoyer sur le réseau. Le cache inter­cepte la réponse à ce moment, et la stocke dans sa mémoire locale avant de la ser­vir au client.

Schéma de mise en cache d'une resource web
Mis en cache d’une res­source lors de sa requête (icônes : The Noun Project)

Lorsqu’une requête pour la même page est émise par un client, elle sera direc­te­ment ser­vie par le cache qui détient désor­mais une copie de la res­source deman­dée. Le ser­veur web ne sera plus inter­ro­gé.

Schéma d'une resource web servie par un cache
Restitution d’une res­source pré­cé­dem­ment mise en cache (icônes : The Noun Project)

Utiliser le cache chez alwaysdata

Vous pou­vez acti­ver le cache fron­tal pour chaque site indi­vi­duel­le­ment en vous ren­dant sim­ple­ment dans Sites → Modification → Cache, puis en cochant la case Activer le cache.

Capture d'écran de l'interface d'administration pourla configuration du cache HTTP par site

Il vous fau­dra régler le TTL pour les pages issues de ce site. Le TTL défi­nit la durée pen­dant laquelle le cache peut ser­vir une page. Sa valeur doit être sélec­tion­née avec soin. S’il est bon de choi­sir un TTL éle­vé pour un site dont le conte­nu n’est pas sou­vent mis à jour ; il sera en revanche judi­cieux d’abaisser cette valeur dans le cas d’un site dont le conte­nu change très régu­liè­re­ment, comme un site de news. Dans ce der­nier cas, si le TTL reste éle­vé, le visi­teur peut se retrou­ver avec une ver­sion péri­mée de la page deman­dée.

Prenons l’exemple de ce blog. Nous sou­hai­tons nous assu­rer qu’un visi­teur se retrouve avec une ver­sion rela­ti­ve­ment fraîche de la page d’accueil. Lorsque nous ajou­tons un article, la page d’accueil cachée aupa­ra­vant sera péri­mée. Nous allons donc pré­fé­rer une valeur de TTL com­prise entre 5 et 10 secondes afin de béné­fi­cier des hausses de per­for­mances sans ris­quer de ser­vir la page cachée pen­dant une durée trop longue.

Cette fonc­tion­na­li­té est consi­dé­rée comme en bêta test et sus­cep­tible d’évoluer encore.

Cette fonc­tion­na­li­té est dépen­dante de la capa­ci­té de votre appli­ca­tion à auto­ri­ser les pages géné­rées à être cachées. Si cette der­nière ne l’autorise pas expli­ci­te­ment, il y a un risque que notre proxy ne puisse pas cacher les res­sources qui sont ser­vies par elle.

L’implémentation

Nous avons choi­si d’écrire en Python2) un module inté­grant les spé­ci­fi­ca­tions du stan­dard expo­sées dans la RFC 7234. Le sto­ckage des res­sources cachées, quant à lui, est confié à un ser­veur Redis local per­met­tant l’optimisation de la mémoire uti­li­sée avec très peu d’efforts.

En plus des spé­ci­fi­ca­tions liées à la RFC, nous avons implé­men­té le verbe HTTP PURGE. Cette méthode offre la pos­si­bi­li­té de sup­pri­mer une entrée dans le cache par le client juste en l’appelant sur son URL. Ceci peut être utile lorsque vous cher­chez à for­cer le rafraî­chis­se­ment d’une page mise en cache.


Après la per­for­mance, la jour­na­li­sa­tion ! Dans le pro­chain et der­nier billet de cette série, nous vous pré­sen­te­rons notre sys­tème de per­son­na­li­sa­tion des lignes de logs géné­rées par vos ser­veurs web. Vous allez désor­mais pou­voir les for­ma­ter selon vos besoins.

Notes   [ + ]

1. ab -c 10 -t 60 http://blog.alwaysdata.com/
2. parce qu’on aime bien Python chez always­da­ta