Manuel:Cache Varnish

This page is a translated version of the page Manual:Varnish caching and the translation is 100% complete.

Varnish est un serveur proxy inverse, efficace et léger[1] qui réduit le temps nécessaire pour distribuer les pages demandées fréquemment.

Varnish est un accélérateur HTTP qui stocke les copies des pages distribuées par le serveur web. La prochaine fois que la même page sera demandée, Varnish va distribuer la copie au lieu de la redemander au serveur Apache. Cette méthode de cache supprime le besoin pour MediaWiki de regénérer la même page à chaque fois, ce qui améliore les performances de manière fulgurente.[2]

Varnish a l'avantage d'être conçu spécialement pour une utilisation comme accélérateur HTTP (proxy inverse). Il socke la plupart de ses données de cache en mémoire, ce qui crée moins de fichiers disque et réduit les accès au système de fichiers par rapport au paquet Squid qui est plus important et multi-fonction. Tout comme Squid, il distribue les pages souvent demandées, aux utilisateurs anonymes (par IP) à partir d'un cache au lieu de les demander au serveur web originel. Ceci réduit à la fois l'utilisation de la CPU et l'accès à la base de données par le serveur MediaWiki de base.

Grâce à cette performance de gain, MediaWiki a été conçu pour s'intégrer avec un cache web et il notifie Squid ou Varnish quand une page doit être purgée du cache afin d'être regénérée.

Du point de vue MediaWiki, une installation de Varnish correctement configurée est interchangeable avec son équivalent Squid.

Architecture

Un exemple de configuration Varnish + Apache + MediaWiki sur un même serveur est donné ci-dessous. Une stratégie de cache un peu plus complexe peut utiliser plusieurs serveurs web derrière les mêmes caches Varnish (tous pouvant être considérés ensemble comme un seul hôte) ou utiliser des serveurs indépendants pour délivrer du countenu wiki ou des images.

Monde extérieur

Serveur

Accélérateur Varnish
w.x.y.z:80

Serveur web Apache
127.0.0.1:80

Vu de l'extérieur, Varnish se comporte comme un serveur web. En réalité il passe les requêtes au serveur web Apache, mais uniquement lorsque c'est nécessaire. Apache s'exécutant sur le même serveur n'écoute que les requêtes du localhost (127.0.0.1) tandis que Varnish n'écoute que les requêtes arrivant sur l'adresse IP externe du serveur. Les deux services peuvent se partager le port 80 sans entrer en conflit pour autant que chacun d'eux est lié à une adresse IP différente.

Configurer Varnish

La configuration suivante fonctionne pour Varnish version 4 et les suivantes.

vcl 4.0;
# set default backend if no server cluster specified
backend default {
    .host = "127.0.0.1";
    .port = "8080";
    # .port = "80" led to issues with competing for the port with apache.
}

# access control list for "purge": open to only localhost and other local nodes
acl purge {
    "127.0.0.1";
}

# vcl_recv is called whenever a request is received 
sub vcl_recv {
        # Serve objects up to 2 minutes past their expiry if the backend
        # is slow to respond.
        # set req.grace = 120s;

        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;

        set req.backend_hint= default;
 
        # This uses the ACL action called "purge". Basically if a request to
        # PURGE the cache comes from anywhere other than localhost, ignore it.
        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
                return (synth(405, "Not allowed."));
            } else {
                return (purge);
            }
        }
        
        # Pass requests from logged-in users directly.
        # Only detect cookies with "session" and "Token" in file name, otherwise nothing get cached.
        if (req.http.Authorization || req.http.Cookie ~ "([sS]ession|Token)=") {
            return (pass);
        } /* Not cacheable by default */
 
        # normalize Accept-Encoding to reduce vary
        if (req.http.Accept-Encoding) {
          if (req.http.User-Agent ~ "MSIE 6") {
            unset req.http.Accept-Encoding;
          } elsif (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
          } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
          } else {
            unset req.http.Accept-Encoding;
          }
        }
 
        return (hash);
}

sub vcl_pipe {
        # Note that only the first request to the backend will have
        # X-Forwarded-For set.  If you use X-Forwarded-For and want to
        # have it set for all requests, make sure to have:
        # set req.http.connection = "close";
 
        # This is otherwise not necessary if you do not do any request rewriting.
 
        set req.http.connection = "close";
}

# Called if the cache has a copy of the page.
sub vcl_hit {
        if (!obj.ttl > 0s) {
            return (pass);
        }
}

# Called after a document has been successfully retrieved from the backend.
sub vcl_backend_response {
        # Don't cache 50x responses
        if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
            set beresp.uncacheable = true;
            return (deliver);
        }   
 
        if (!beresp.ttl > 0s) {
          set beresp.uncacheable = true;
          return (deliver);
        }
 
        if (beresp.http.Set-Cookie) {
          set beresp.uncacheable = true;
          return (deliver);
        }
 
        if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
          set beresp.uncacheable = true;
          return (deliver);
        }

        return (deliver);
}

Configurer MediaWiki

Comme Varnish fait ses requêtes à partir de localhost, Apache recevra directement 127.0.0.1 pour l'adresse IP du distant. Néanmoins, comme Varnish redirige les requêtes vers Apache, il est configuré pour ajouter l'entête X-Forwarded-For de sorte à ce que l'adresse du distant extérieur soit préservée. MediaWiki doit être configuré pour utiliser l'entête X-Forwarded-For afin d'afficher correctement les adresses des utilisateurs dans special:recentchanges.

La configuration nécessaire est la même pour Squid que pour Varnish. Assurez-vous que le fichier LocalSettings.php contient les lignes suivantes :

$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1', '192.168.0.1' ];
//Use $wgCdnServersNoPurge if you don't want MediaWiki to purge modified pages
//$wgCdnServersNoPurge = [ '192.168.0.2' ];

Assurez-vous de remplacer '192.168.0.1' par l'adresse IP sur laquelle votre cache Varnish est à l'écoute. Ces paramètres servent à deux choses :

  • Si une requête est reçue du serveur cache Varnish, les journaux MediaWiki ont besoin d'afficher l'adresse IP de l'utilisateur et non pas celle de Varnish. Une page Special:recentchanges dans laquelle chaque modification est repportée avec '127.0.0.1' est tout sauf utile; le listing qui s'adresse à un serveur Squid ou Varnish demande donc à MediaWiki d'ignorer l'adresse IP et de lire l'entête 'x-forwarded-for' à la place, pour connaitre l'adresse IP de l'utilisateur.
  • Si une page ou une image est modifiée sur le wiki, MediaWiki envoie une notification à chaque serveur listé dans $wgCdnServers en demandant de supprimer (purger) la page obsolète enregistrée.

Utilisez $wgCdnServersNoPurge pour les adresses qui ne doivent pas figurer parmi les modifications récentes, et qui ne reçoivent pas les messages HTTP PURGE. Par exemple, si Apache et Squid sont respectivement sur 127.0.0.1 et une adresse externe sur la même machine, il n'est pas nécessaire d'envoyer un message purge à Apache à l'attention de Squid. De la même façon, si Squid écoute sur plusieurs adresses, n'envoyez le purge que sur l'une d'entre-elles.

Voir aussi les Paramètres de configuration Squid pour tous les paramètres liés à la mise en cache Squid/Varnish.

Si vous utilisez HTTPS, assurez-vous d'initialiser $wgInternalServer à la même valeur que $wgServer mais avec le protocole http:// , afin d'empêcher que les requêtes de purge ne soient envoyées en HTTPS, depuis que Varnish ne prend plus en compte HTTPS.

If using $wgForceHTTPS , be sure to send request header "X-Forwarded-Proto: https" to suppress the redirect, otherwise disable $wgForceHTTPS to prevent redirect loops.

Quelques notes

Notez que Varnish est une alternative à Squid, et ne remplace pas les autres portions de la stratégie de mise en cache complète de MediaWiki comme :

Code PHP précompilé
Le comportement par défaut de PHP sous Apache est de charger et d'interpréter les scripts web PHP à chaque fois que l'on en a besoin. L'installation d'un cache tel que APC (yum install php-pecl-apc, puis allouez la mémoire en initialisant apc.shm_size=128 ou mieux dans /etc/php.d/apc.ini) peut réduire de beaucoup le temps d'utilisation de la CPU pour que Apache délivre le contenu PHP.
Localisation/Internationalisation
Par défaut, MediaWiki va créer une énorme table de base de données l10n_cache à laquelle il accède constamment - ce qui va vraisemblablement faire plus que doubler la charge du serveur de base de données après une mise à jour avec la dernière version de MediaWiki. Initialisez $wgLocalisationCacheConf afin de forcer l'enregistrement des informations de localisation à l'intérieur du système de fichiers pour remédier à cela.
Variables et données de session
L'enregistrement de données variables telles que la barre latérale MediaWiki, la liste des espaces de noms ou la liste noire anti-abus dans un cache mémoire va accélérer un peu la vitesse d'une installation MediaWiki. Forcer les données de connexion des utilisateurs dans un endroit commun est aussi essentiel à toute installation dans laquelle de multiples serveurs Apache interchangeables sont cachés derrière les mêmes caches Varnish pour fournir les pages des mêmes wikis. Installez le paquet memcached et initialisez les options suivantes dans LocalSettings.php pour forcer à la fois les informations de connexion des utilisateurs et les variables en cache à utiliser memcache :
$wgMainCacheType = CACHE_MEMCACHED;
$wgMemCachedServers = [ '127.0.0.1:11211' ];
Notez que, si vous avez de multiple serveurs, l'adresse 'localhost' doit être remplacée avec celle du ou des serveurs 'memcached' partagés, qui doit être la même pour tous les serveurs web accessibles, de votre site. Cela assure que si un utilisateur se connecte à l'un des serveurs de la grappe, il est connecté au wiki sur tous les serveurs web interchangeables.

Souvent il existe plusieurs moyens alternatifs pour mettre en cache mais ils conduisent au même résulat. Voir Manuel:Cache .


Configuration Apache

Fichier journal

Le journal du serveur web Apache, par défaut, n'affiche que l'adresse du serveur cache Varnish, dans cet exemple 127.0.0.1:80

Apache peut être configuré pour journaliser l'adresse de l'utilisateur originel en capturant l'information x-forwarded-for dans un format personnalisé de fichier journal.[3]

Exemple de fichier httpd.conf de Apache pour configurer les traces de x-forwarded-for :

LogFormat "%{X-Forwarded-for}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" cached

Lien immédiat vers les images

Si un site utilise mod_rewrite de Apache pour bloquer les tentatives des autres sites web aux images immédiates (hotlink), cete configuration devra être supprimée et la configuration équivalente ajoutée dans les fichiers de paramètres de Varnish. Là où un serveur d'images se trouve derrière Varnish, typiquement 90% ou plus des requêtes communes d'images n'arrivent pas jusque Apache et ne seront pas bloquées par un contrôle http_referer dans les configurations Apache.


Voir aussi

Références