OpenZFS est bien plus qu’un simple système de fichiers : c’est une pile de stockage complète qui intègre nativement des mécanismes de cache multiniveaux. Pour les environnements aux besoins variés — serveurs de fichiers, bases de données, machines virtuelles — comprendre et configurer correctement le L2ARC (Level 2 Adaptive Replacement Cache) et le SLOG (Separate Log device) peut faire la différence entre un stockage qui subit les accès et un stockage qui les absorbe.
Cet article s’adresse aux administrateurs qui ont déjà un pool ZFS en production et qui souhaitent aller au-delà de la configuration par défaut. On y couvre l’architecture de cache ZFS, les critères de décision pour ajouter un L2ARC ou un SLOG, les commandes de configuration sur Debian et Ubuntu, les paramètres de tuning du module, et la supervision des métriques pour valider l’efficacité des ajustements.
Les manipulations ont été validées avec OpenZFS 2.2.x sur Debian 12 et Ubuntu 22.04/24.04. Pour une introduction à ZFS, consultez d’abord ZFS sur Linux — Installation et gestion avancée.
Architecture de cache ZFS : ARC, L2ARC et ZIL/SLOG
L’ARC : le cache primaire en RAM
L’ARC (Adaptive Replacement Cache) est le cache principal de ZFS, résidant entièrement en RAM. Contrairement à un LRU classique, l’ARC maintient quatre listes internes qui distinguent les données fréquemment accédées des données récemment accédées, le rendant résistant aux effets de balayage (cache scan). Par défaut, ZFS peut utiliser jusqu’à 50 % de la RAM avec une croissance et réduction dynamiques selon la pression mémoire du système.
Règle fondamentale : chaque gigaoctet de RAM supplémentaire apporte plus de bénéfice qu’un gigaoctet de SSD en L2ARC. Maximiser la RAM reste toujours la première étape avant d’ajouter des disques de cache.
Le L2ARC : extension du cache sur SSD/NVMe
Le L2ARC est un cache en lecture situé sur un ou plusieurs disques rapides (SSD ou NVMe). Lorsqu’une entrée est sur le point d’être évincée de l’ARC, ZFS peut l’écrire dans le L2ARC. Les lectures ultérieures de cette donnée sont servies depuis le SSD plutôt que depuis les disques rotatifs du pool.
Point critique : le L2ARC ne stocke que des données en lecture. Les écritures passent toujours par les disques principaux du pool (ou le SLOG). De plus, chaque bloc en L2ARC nécessite un pointeur en RAM d’environ 80 octets — sur un serveur contraint en mémoire, un L2ARC surdimensionné peut paradoxalement réduire l’efficacité globale de l’ARC en consommant l’espace mémoire disponible pour les pointeurs.
Le ZIL et le SLOG : accélérer les écritures synchrones
Le ZIL (ZFS Intent Log) est le journal d’intention de ZFS. Lorsqu’une application effectue une écriture synchrone (fsync, O_SYNC, NFS en mode sync), ZFS doit confirmer l’écriture sur disque avant de répondre à l’application. Par défaut, le ZIL est intégré au pool principal, ce qui signifie que chaque écriture synchrone attend les disques du pool.
Le SLOG (Separate Log device) déplace ce journal sur un dispositif dédié à très faible latence. L’écriture synchrone est confirmée dès l’écriture sur le SLOG — le flush vers le pool principal se fait en arrière-plan. La latence perçue par l’application chute sans compromettre la durabilité des données.
Important : le SLOG agit sur la latence des écritures synchrones, pas sur le débit global. Si votre workload n’utilise pas
fsyncouO_SYNC(écritures asynchrones pures), un SLOG n’apportera aucun bénéfice mesurable.
Quand ajouter un L2ARC ou un SLOG ?
Le L2ARC est pertinent si
- Le dataset actif est nettement plus grand que la RAM disponible et les lectures sont répétées sur des données « tièdes » (ni très fréquentes, ni très rares)
- Le workload est majoritairement en lecture aléatoire : images de VM fréquemment accédées, fichiers de travail d’un serveur de fichiers
- Le hit ratio ARC mesuré via
arcstatest bas malgré une RAM raisonnable (< 80 %) - Vous disposez d’un NVMe ou SSD performant non utilisé
- La règle générale : L2ARC = 1× à 4× la RAM ; ne pas dépasser 10× sans justification mesurée
Le L2ARC est inutile (voire contre-productif) si
- Le dataset actif tient entièrement en RAM (hit ratio ARC > 95 %)
- Le workload est en lecture séquentielle pure : streaming, backup, exports
- Le serveur dispose de peu de RAM (moins de 32 Go) — le overhead mémoire des pointeurs L2ARC l’emporte sur le bénéfice
Le SLOG est pertinent si
- Le pool est sur des disques rotatifs et reçoit des écritures synchrones en volume
- Des applications utilisent fsync intensif : PostgreSQL, MySQL/InnoDB, NFS avec option
sync, iSCSI - La latence d’écriture est le goulot d’étranglement identifié (mesuré, pas supposé)
Installer et vérifier OpenZFS sur Debian/Ubuntu
# Debian 12
apt install linux-headers-$(uname -r) zfsutils-linux zfs-dkms
# Ubuntu 22.04 / 24.04 (paquet natif dans main)
apt install zfsutils-linux
# Vérifier la version installée
zpool version
# Résultat attendu : zpool: 2.2.x-x ou supérieur
# Lister les pools existants
zpool list
Ajouter un L2ARC à un pool existant
Identifier les disques disponibles
# Lister les disques avec leur type (ROTA=0 = SSD/NVMe)
lsblk -d -o NAME,SIZE,ROTA,TYPE,MODEL
# Obtenir les identifiants stables recommandés pour la production
ls -l /dev/disk/by-id/ | grep -E "nvme|ssd"
Ajouter le cache au pool
# Ajouter un NVMe comme L2ARC au pool "datapool"
# Toujours utiliser /dev/disk/by-id/ plutôt que /dev/sdX ou /dev/nvmeXnY
zpool add datapool cache /dev/disk/by-id/nvme-Samsung_SSD_980_PRO_1TB_XXXX
# Vérifier la configuration du pool — une section "cache" doit apparaître
zpool status datapool
# Afficher la taille du L2ARC dans le pool
zpool list -v datapool
Retirer un L2ARC
# Le retrait est propre : les données du cache sont perdues,
# mais le pool reste intact et fonctionnel
zpool remove datapool /dev/disk/by-id/nvme-Samsung_SSD_980_PRO_1TB_XXXX
Ajouter un SLOG (dispositif ZIL séparé)
Règle absolue : miroir obligatoire
Un SLOG non mirroré en production est une bombe à retardement. En cas de perte du SLOG pendant une fenêtre de commit (entre l’acquittement à l’application et le flush vers le pool), les écritures synchrones en transit sont perdues. Toujours mirorer le SLOG avec deux devices distincts.
# Ajouter deux NVMe en miroir comme SLOG au pool "datapool"
zpool add datapool log mirror
/dev/disk/by-id/nvme-device-A
/dev/disk/by-id/nvme-device-B
# Vérifier — la section "logs" doit afficher le miroir
zpool status datapool
Partitionner un seul NVMe pour SLOG + L2ARC
Le SLOG ne nécessite que quelques secondes d’écritures synchrones en tampon (les commits ZFS ont lieu toutes les 5 secondes par défaut). 4 à 16 Go suffisent dans la quasi-totalité des cas. Il est courant de partitionner un NVMe et d’affecter une petite partition au SLOG, le reste au L2ARC :
# Installer l'outil de partitionnement GPT
apt install gdisk
# Partitionner : 16 Go pour le SLOG, le reste pour le L2ARC
sgdisk -n 1:0:+16G -t 1:8300 -c 1:"ZFS-SLOG"
-n 2:0:0 -t 2:8300 -c 2:"ZFS-L2ARC"
/dev/nvme1n1
# Vérifier les partitions créées
lsblk /dev/nvme1n1
# Ajouter les deux rôles au pool
zpool add datapool log /dev/nvme1n1p1
zpool add datapool cache /dev/nvme1n1p2
# Confirmer la configuration finale
zpool status -v datapool
Tuning des paramètres du module OpenZFS
Les paramètres du module zfs sont exposés dans /sys/module/zfs/parameters/. Les modifications à chaud sont immédiates mais non persistées au redémarrage. Pour les persister, on utilise /etc/modprobe.d/zfs.conf.
Paramètres L2ARC clés
# Lire la valeur courante d'un paramètre
cat /sys/module/zfs/parameters/l2arc_write_max
# Limiter le débit d'écriture vers le L2ARC (en bytes/s)
# 100 Mo/s = 104857600 — protège l'endurance du SSD
echo 104857600 > /sys/module/zfs/parameters/l2arc_write_max
# Boost d'écriture au démarrage (remplissage initial accéléré)
echo 209715200 > /sys/module/zfs/parameters/l2arc_write_boost
# Empêcher les prefetch de polluer le L2ARC (recommandé)
echo 1 > /sys/module/zfs/parameters/l2arc_noprefetch
# Activer la reconstruction du L2ARC au redémarrage (OpenZFS 2.0+)
echo 1 > /sys/module/zfs/parameters/l2arc_rebuild_enabled
Persister les paramètres
cat > /etc/modprobe.d/zfs.conf << 'EOF'
# L2ARC : débit d'écriture limité pour préserver l'endurance du SSD
options zfs l2arc_write_max=104857600
options zfs l2arc_write_boost=209715200
options zfs l2arc_noprefetch=1
options zfs l2arc_rebuild_enabled=1
EOF
# Mettre à jour initramfs pour prendre en compte la config au boot
update-initramfs -u
Limiter l’ARC pour les serveurs de base de données
# Sur un serveur PostgreSQL/MySQL avec son propre buffer pool,
# limiter l'ARC à 16 Go pour laisser de la mémoire à l'application
# 16 Go = 17179869184 bytes
echo 17179869184 > /sys/module/zfs/parameters/zfs_arc_max
# Persistance
echo "options zfs zfs_arc_max=17179869184" >> /etc/modprobe.d/zfs.conf
update-initramfs -u
# Vérifier la taille ARC courante (en Go)
awk '/^size/ {printf "ARC size: %.2f GBn", $3/1024/1024/1024}'
/proc/spl/kstat/zfs/arcstats
Superviser les performances du cache
arcstat : métriques ARC et L2ARC en temps réel
# arcstat est fourni avec zfsutils-linux sur Debian/Ubuntu
# Afficher les métriques toutes les secondes
arcstat 1
# Colonnes essentielles à surveiller :
# read = lectures totales (ARC + L2ARC + pool)
# hits = hits ARC (lecture servie depuis la RAM)
# miss = miss ARC (donnée absente de la RAM)
# l2hits = hits L2ARC (servi depuis le SSD de cache)
# l2miss = miss L2ARC (lecture depuis le pool principal)
# arcsz = taille ARC courante
# l2sz = taille L2ARC courante
Calculer le hit ratio manuellement
# Snapshot des compteurs ARC
grep -E "^hits |^misses |^l2_hits|^l2_misses" /proc/spl/kstat/zfs/arcstats
# Calcul du hit ratio ARC
awk '
/^hits / { hits=$3 }
/^misses / { misses=$3 }
END { printf "ARC hit ratio: %.1f%%n", hits*100/(hits+misses) }
' /proc/spl/kstat/zfs/arcstats
# Calcul du hit ratio L2ARC
awk '
/^l2_hits / { hits=$3 }
/^l2_misses/ { misses=$3 }
END {
if (hits+misses > 0)
printf "L2ARC hit ratio: %.1f%%n", hits*100/(hits+misses)
else
print "L2ARC: pas encore de données"
}
' /proc/spl/kstat/zfs/arcstats
zpool iostat : I/O par composant du pool
# Afficher les I/O par vdev (disques, cache, log) toutes les 2 secondes
zpool iostat -v datapool 2
# Afficher les latences moyennes par vdev (OpenZFS 2.1+)
zpool iostat -l datapool 2
# Latences attendues indicatives :
# SLOG (NVMe entreprise) : < 100 µs en écriture
# L2ARC (NVMe consommateur) : 100-500 µs en lecture
# HDD 7200 rpm : 5-15 ms
Bonnes pratiques et anti-patterns
Ce qu’il faut faire
- Mesurer avant d’optimiser : surveiller
arcstatetzpool iostatpendant 24 à 48h en charge réelle avant tout ajustement - Miroir systématique du SLOG : un SLOG non mirroir en production est inacceptable
- Utiliser les IDs stables (
/dev/disk/by-id/) pour référencer les devices, jamais/dev/sdXqui peut changer au reboot - Activer
l2arc_rebuild_enabled(OpenZFS 2.0+) pour que le cache survive aux redémarrages planifiés - Aligner le recordsize sur le type d’application : 16K pour MySQL InnoDB, 32K pour PostgreSQL, 1M pour les fichiers séquentiels
Anti-patterns à éviter
- Ajouter un L2ARC sur un serveur avec peu de RAM (moins de 32 Go) : le overhead des pointeurs mémoire peut dégrader l’ARC existant
- Utiliser un SSD grand public sans capacitors pour le SLOG : en cas de coupure électrique, les données dans le cache volatile du SSD sont perdues avec le SLOG
- Dimensionner un SLOG à plusieurs centaines de Go : le ZIL n’en a jamais besoin, c’est du gaspillage d’espace rapide
- Modifier les tunables sans mesure baseline : impossible de valider l’impact sans point de référence
- Mettre le pool et le SLOG/L2ARC sur le même disque physique : aucun gain, et dégradation des performances I/O du pool
À lire également
- ZFS sur Linux : snapshots, clones et RAID-Z en pratique — Maîtriser les fonctionnalités fondamentales de ZFS avant de passer au tuning avancé du cache.
- ZFS sur Linux — Installation et gestion avancée — Installation pas à pas et gestion quotidienne d’un pool ZFS sur Debian et Ubuntu.
- DRBD : réplication de blocs entre deux serveurs en temps réel — Pour compléter un pool ZFS avec une couche de réplication synchrone entre deux nœuds.
- Tuning kernel Linux — paramètres sysctl essentiels pour la production — Les paramètres kernel qui complètent le tuning ZFS pour maximiser les performances I/O en production.