1ère étape dans la série des articles sur Varnish : l’installation. Je vais traiter ici de l’installation de Varnish 3 sur une Debian Squeeze 64 bits fraîchement installée. Pourquoi 64 bits ? Parce que Varnish est conçu pour fonctionner sur des architectures 64 bits. Le 32 bits limitera la quantité de mémoire qu’il pourra utiliser, le nombre de threads qu’il pourra ouvrir…

Si vous arrivez directement sur cet article et/ou que vous souhaitez en savoir plus sur Varnish, je vous suggère la lecture de Varnish : aperçu.

Installation

Varnish fournit les paquets pour différentes distributions. Voici les étapes nécessaires à l’installation de Varnish 3 sur une Debian :

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add -
echo "deb http://repo.varnish-cache.org/debian/ squeeze varnish-3.0" >> /etc/apt/sources.list.d/varnish.list
apt-get update
apt-get install varnish

Configuration

La configuration des processus varnishd, varnishlog et varnishncsa se trouve dans /etc/default :

  • varnish pour la configuration du processus varnishd.
  • varnishlog pour la configuration du processus de log varnish.
  • varnishncsa pour la configuration du processus de log varnish au format Apache.

Configuration de varnishd : La configuration par défaut peut être à revoir pour coller au mieux à votre serveur. Je dis peut-être car elle peut vous suffir en fonction de votre besoin (modulo quand même le cache de 256m). Il est important de faire un bench avant et après vos modifications pour vous assurer que vos modifications n’ont pas réduit les performances générales de votre serveur. Un outil pratique pour suivre un peu ce qu’il se passe sur votre serveur pendant un bench : dstat. Ne pas oublier varnishstat qui vous permettra de détecter certains problèmes.

Cache de type file ou malloc ? C’est je pense la première question à vous poser. Varnish sera beaucoup plus performant avec le cache en mémoire. Maintenant, tout est question de la taille de votre cache et de la quantité de RAM dont vous disposez. Si vous décidez d’utiliser le stockage de type malloc, il faudra vous arranger pour que votre cache tienne en RAM sachant que vous pouvez dédier jusqu’à 80% de RAM à votre cache Varnish. Les 20% restant serviront à d’autres caches Varnish et à votre OS. Attention donc à ne pas attribuer 100% de votre RAM au risque de voir, un jour, l’OOM killer faire le ménage ! Si vous devez cacher sur disque, préférez un SSD (test à venir).

Configuration pour un serveur bi-quad core avec 16Go de RAM : En partant sur ce serveur de tests, voilà les valeurs optimisées :

Paramètrevaleur par défautdétail
thread_pool2L’idée est d’avoir un pool par core. Mon serveur en a 8. thread_pool vaut donc 8. Au délà d’un pool par core, les performances seront moins bonnes.
thread_pool_min5C’est le nombre minimum de threads par pool. C’est utile en cas de montée en charge soudaine. La documentation de Varnish donne 200 en exemple de tuning. J’ai testé avec 200 et 100, pas de différence visible. A tester/bencher pour votre besoin.
thread_pool_max500C’est le nombre total de threads que vous pouvez ouvrir. Il faudra adapter le nombre de descripteurs de fichiers disponibles en fonction de cette valeur. La documentation donne 4000 en exemple et 5000 en limite pour ne pas rentrer dans des problèmes de limites système. Augmenter cette valeur trop haut n’augmentera pas vos performances ! Vérifiez avec un bench.
thread_pool_add_delay2ms sur Varnish 3C’est la pose entre chaque création de threads. La réduire permet, surtout au démarrage de Varnish ou en cas de montée en charge soudaine, d’en créer plus rapidement et d’éviter ainsi la mise en attente d’une requête ou son rejet. Sur Varnish 3 on garde la valeur par défaut de 2ms. Sur Varnish 2.1.5, il fallait réduire la valeur par défaut de 20ms à 2ms.
session_linger50msDe 100 à plus selon le besoin et les tests. C’est la durée durant laquelle le thread va attendre pour une nouvelle requête dans la session établie.

Voilà le résultat dans le fichier /etc/default/varnish :

# Configuration file for varnish
# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK
# to be set from this shell script fragment.
# Should we start varnishd at boot? Set to "yes" to enable.
START=yes

# Maximum number of open files (for ulimit -n)
NFILES=131072

# Maximum locked memory size (for ulimit -l)
# Used for locking the shared memory log in memory. If you increase log size,
# you need to increase this number as well
MEMLOCK=82000

# Default varnish instance name is the local nodename. Can be overridden with
# the -n switch, to have more instances on a single server.
INSTANCE=$(uname -n)
VARNISH_VCL_CONF=/etc/varnish/default.vcl

# Default address and port to bind to
# Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=80

# Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=2000

# The minimum number of worker threads to start
VARNISH_MIN_THREADS=100

# The Maximum number of worker threads to start
VARNISH_MAX_THREADS=4000

# The delay between the launching of each thread (in ms)
VARNISH_THREAD_DELAY=2

# Number of thread pools
VARNISH_THREAD_POOLS=8

# To avoid context switching hell when you starve your CPU (and in general),
# letting each thread wait for new requests is essential. (in ms)
VARNISH_SESSION_LINGER=100

# Session workspace : Min : 16k, max 5m (if ESI is in use)
VARNISH_SESSION_WORKSPACE=16384

# Cache file location
#VARNISH_STORAGE_FILE=/var/lib/varnish/$INSTANCE/varnish_storage.bin

# Cache size: in bytes, optionally using k / M / G / T suffix,
# or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=12G

# Backend storage specification
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH\_STORAGE_SIZE}"
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"

# DAEMON_OPTS is used by the init script. If you add or remove options, make
# sure you update this section, too.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
-f ${VARNISH_VCL_CONF} \
-T ${VARNISH_ADMIN_LISTEN\_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
-w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS} \
-s ${VARNISH_STORAGE} \
-p thread_pool_add_delay=${VARNISH_THREAD_DELAY} -p thread_pools=${VARNISH_THREAD_POOLS} \
-p session_linger=${VARNISH_SESSION_LINGER} -p sess_workspace=${VARNISH_SESSION_WORKSPACE}"

Optimisation du système

Les optimisations sont données à titre d’exemple pour un serveur dédié Varnish. Elles seront à adapter en fonction de l’usage de votre cache. Tuning des entrées/sorties :

  • Désactivez l’utilisation de la swap : sysctl -w vm.swappiness = 0
  • Placez le répertoire de travail de Varnish qui héberge le log SHM en tmpfs. Il n’y a aucun risque à perdre ces données en cas de reboot. Par défaut le log SHM est de 80 MB. On va créer un tmpfs de 256MB. Rajoutez cette ligne dans votre /etc/fstab :
bashtmpfs /var/lib/varnish tmpfs defaults,size=256m 0 0

Si vous avez modifié la taille du log (option -l de varnishd), adaptez la taille du tmpfs. A savoir : vous pouvez intervenir à chaud sur la taille de votre tmpfs. Modifiez la taille définie dans le fstab et remontez à chaud via mount -o remount /var/lib/varnish. Vérifiez via un df.

  • Dans le cas ou vous cachez sur disque, il faudra préférer un système de fichier non journalisé pour la partition qui héberge le cache Varnish (utilisez ext2 par exemple). Il sera monté avec les options noatime, nodiratime.
  • Toujours dans l’optique où vous utilisez le disque comme stockage du cache, préférez l’ordonnanceur anticipatory sur un noyau linux inférieur au 2.6.33 (cet ordonnanceur a été retiré) ou cfq, le défaut, sur un noyau plus récent. Si votre disque est un SSD, utilisez le plus simple des ordonnanceurs : noop.

Tuning réseau :

  • Gardez votre varnish et vos backends à l’heure. Utilisez ntp.
  • Optimisez /proc/sys/net en fonction de votre besoin… Sachant que depuis le kernel 2.6.17, tout est en auto tuning jusqu’à 4MB de buffer, dans la majorité des cas, toucher aux différents buffers n’améliorera pas les performances de Varnish.
  • Si votre passerelle fait du NAT, attention si vous réutilisez les sessions en TIME WAIT (tw_reuse=1) et que votre passerelle ne modifie pas tw_timestamp. Les connexions seront bloquées tant que le time wait n’aura pas expiré.
  • Dans le même genre, attention à ne pas activer le suivi de connexion pour serveur Varnish. Vu le nombre de connexions qu’il peut être amené à gérer, cela peut être source à problèmes.

Encore une fois, testez et benchez vos modifications. Vérifiez au niveau de la supervision et des différents compteurs de varnishstat que tout fonctionne correctement et que les performances sont optimales.

A suivre…