À un moment donné, tout administrateur ZFS rencontre le même antagoniste : un working set qui ne rentre pas en RAM. Le symptôme est familier — pics de latence, disques qui s’affolent, utilisateurs affirmant « le stockage est lent » avec la certitude morale de quelqu’un qui n’a jamais regardé iostat.
Utiliser NVMe comme L2ARC semble être la solution évidente : ajouter un périphérique cache rapide et passer à autre chose. Parfois c’est brillant. Parfois c’est une façon coûteuse d’user prématurément votre NVMe pendant que les performances restent obstinément médiocres. Cet article explique dans quel monde vous vous trouvez — avant de l’apprendre en production.
Ce qu’est (et n’est pas) le L2ARC
ZFS dispose d’un cache primaire appelé ARC (Adaptive Replacement Cache). Il vit en RAM et il est extrêmement efficace pour rendre les lectures répétées peu coûteuses. Quand l’ARC est trop petit pour votre working set, ZFS peut étendre le cache sur un périphérique rapide : le L2ARC, « Level 2 ARC ». L2ARC est un cache de lecture. Pas un tampon d’écriture, pas un accélérateur de journalisation, pas une baguette magique.
Ce qui se passe en pratique :
- ARC suit ce qui est chaud. Si ARC ne peut pas tout garder, ZFS peut pousser certaines de ces données vers L2ARC.
- Lors d’un miss dans ARC, ZFS peut regarder dans le L2ARC. Si trouvé, il lit depuis le NVMe plutôt que depuis des disques mécaniques ou des SSD plus lents.
- Le contenu du L2ARC est rempli au fil du temps. Historiquement il n’était pas persistant après reboot ; les implémentations récentes peuvent le persister (plus loin, on en reparle).
Ce que le L2ARC ne fait pas :
- Il n’accélère pas les écritures synchrones (c’est le domaine du SLOG, et même là : seulement pour des charges spécifiques).
- Il ne répare pas un pool lent à cause de fragmentation, d’un mauvais layout de vdev ou d’un goulet CPU.
- Il n’enlève pas la nécessité de dimensionner correctement la RAM. Le L2ARC a toujours besoin de métadonnées en RAM pour être utile.
Vérité opérationnelle : le L2ARC est un outil pour rendre un type précis de latence de lecture moins coûteuse. Si votre problème est « les lectures aléatoires me tuent et les données sont relues », il peut briller. Si votre problème est « tout est aléatoire et jamais relu », il ne servira à rien.
Une citation à mettre sur chaque planning d’astreinte : L’espoir n’est pas une stratégie
— attribuée au général Gordon R. Sullivan. Traitez le L2ARC de la même façon : mesurez, puis décidez.
Faits et historique intéressants (court, utile et légèrement subjectif)
- ARC précède la plupart des habitudes « cloud ». ZFS et ARC proviennent de l’ingénierie de l’ère Solaris où la mémoire était coûteuse et les disques lents, donc la politique de cache était sérieuse.
- Le L2ARC a été conçu pour la mise en cache en lecture, pas pour la durabilité. Les premières implémentations perdaient le cache au reboot ; cela a façonné les attentes opérationnelles pendant des années.
- Le L2ARC nécessite de la RAM pour décrire ce qu’il contient. Chaque bloc mis en cache nécessite des métadonnées dans l’ARC. Un L2ARC gigantesque peut discrètement voler de la RAM dont votre ARC a désespérément besoin.
- Le NVMe a rendu le L2ARC moins embarrassant. Les premiers périphériques L2ARC étaient souvent des SSD SATA ; les améliorations de latence étaient réelles, mais pas toujours spectaculaires. La faible latence du NVMe change les compromis.
- Prélecture et L2ARC ont une relation compliquée. Les lectures séquentielles peuvent inonder les caches avec des données que vous ne toucherez jamais à nouveau. ZFS a ajouté des options (comme
l2arc_noprefetch) parce que les gens n’arrêtaient pas de cacher leurs regrets. - Il y a un « coût de chauffe ». Le L2ARC se remplit progressivement, pas instantanément. Les premières heures (ou jours) peuvent sembler pires que « pas de L2ARC », surtout si vous l’avez mal dimensionné.
- Le débit d’alimentation du cache est volontairement limité. ZFS limite l’agressivité d’écriture vers le L2ARC pour éviter de transformer votre système en usine d’écriture de cache.
- Le L2ARC n’est pas une fonctionnalité sans conséquence. Il consomme CPU, mémoire et écritures vers votre NVMe. Cet usure est réelle ; planifiez-la comme vous planifiez la rétention des logs.
- Le L2ARC persistant existe maintenant dans les implémentations ZFS modernes. Il réduit la douleur de chauffe après un reboot, mais ce n’est pas universel et ce n’est pas gratuit.
Quand le L2ARC NVMe aide vraiment
Le L2ARC sert des charges avec lectures répétées qui échouent dans l’ARC mais pourraient être servies plus rapidement que ce que le pool peut fournir.
Bonnes adéquations
- Hôtes VM avec blocs « chauds » stables parmi de nombreux invités : bibliothèques partagées, fichiers de démarrage, binaires communs, dépôts de patch.
- Bases de données à lecture intensive où le working set est juste un peu trop grand pour la RAM (ou si vous refusez d’acheter plus de RAM pour des raisons budgétaires).
- Caches CI/build où les mêmes toolchains sont réutilisés et votre pool est basé sur des HDD.
- Clusters d’analytics qui scannent de manière répétée les mêmes partitions « récentes », mais pas de façon purement séquentielle.
La condition clé : le L2ARC doit être plus rapide que ce qu’il remplace
Si votre pool est déjà NVMe ou un miroir SSD performant, le L2ARC peut être redondant. Si votre pool est un RAIDZ HDD avec lectures aléatoires, le L2ARC peut sembler miraculeux — à condition que vous relisiez réellement les mêmes blocs.
Blague #1 : Le L2ARC, c’est comme un deuxième frigo — génial si vous conservez des restes, inutile si vous ne mangez que du takeout.
Quand le L2ARC est un piège
La plupart des récits « le L2ARC a déçu » se résument à l’un de ces cas :
1) Votre charge ne relit pas
Ingestion de sauvegardes, scans analytiques froids, copies de fichiers ponctuelles, traitement média séquentiel volumineux — ces charges ont tendance à balayer le cache et disparaître. Le L2ARC devient du trafic d’écriture vers le NVMe avec peu de retour en taux de hits.
2) Votre ARC est affamé, et le L2ARC aggrave la situation
Le L2ARC requiert des métadonnées en RAM. Si votre système est déjà sous pression mémoire, ajouter un grand L2ARC peut réduire la taille effective de l’ARC et augmenter les misses. Félicitations, vous avez mis plus en cache sur NVMe tout en perdant ce qui rend le caching rapide : la RAM.
3) Votre problème n’est pas en lecture
Si la douleur provient d’écritures synchrones, de petites écritures aléatoires ou de contention sur les métadonnées, le L2ARC aura peu d’effet. Souvent le correctif adéquat est un layout différent de vdev, un vdev spécial pour les métadonnées/petits blocs, plus de RAM, ou le réglage de l’application.
4) Vous venez de construire un cache qui thrash
Le thrash signifie que les blocs sont écrits dans le L2ARC puis évincés avant d’être réutilisés. Cela peut arriver parce que le working set est trop grand, que le taux d’alimentation du cache est trop élevé, ou que le motif est une fenêtre roulante plus grande que ARC+L2ARC.
Choisir un NVMe pour L2ARC : latence, endurance et pourquoi « rapide » ne suffit pas
Pour le L2ARC, vous voulez une basse latence sous charge mixte, pas seulement un débit séquentiel héroïque que vous n’atteindrez jamais dans un cache. Les chiffres marketing ne montrent pas la latence en queue lorsque le périphérique est chaud, partiellement plein et effectue du garbage collection en arrière-plan. C’est votre monde réel.
Latence et comportement en file d’attente
Les hits L2ARC sont des lectures aléatoires. Votre NVMe doit gérer des IOPS élevés sans transformer la latence p99 en surprise hebdomadaire. Les modèles ayant des performances cohérentes (souvent des modèles « entreprise ») comptent ici. Les disques grand public peuvent convenir, mais le risque est un comportement plus saccadé lorsque le cache SLC est épuisé ou sous des écritures soutenues liées au remplissage du cache.
L’endurance est une caractéristique, pas une note de bas de page
Le L2ARC est rempli par des écritures. Certaines charges provoquent un churn constant : des blocs sont écrits dans le cache, remplacés, réécrits. Cela peut user les ratings TBW des disques grand public plus vite que prévu par vos achats.
Règle empirique : si vous ne pouvez pas expliquer de manière convaincante votre taux d’écriture de cache, n’achetez pas le NVMe le moins cher. Achetez celui que vous pourrez remplacer sans discussion de carrière.
Protection contre la perte d’alimentation (PLP)
Le L2ARC est un cache ; il n’a pas besoin d’être durable. Mais le comportement en cas de perte d’alimentation compte toujours car un périphérique qui se comporte mal lors de coupures peut bloquer le bus PCIe, boucher les chemins I/O ou provoquer des resets de contrôleur. Le PLP n’est pas obligatoire pour le L2ARC, mais un comportement « entreprise et sérieux » est précieux en production.
Dimensionner le L2ARC : maths simples, contraintes réelles
Les gens dimensionnent le L2ARC comme s’ils dimensionnaient du stockage objet : « plus c’est mieux. » C’est comme ça qu’on se retrouve avec un cache de 4 To devant un système avec 64 Go de RAM et un ARC qui tousse.
La réalité du surcoût en RAM
Le L2ARC a besoin de métadonnées dans l’ARC pour chaque bloc mis en cache. Le surcoût exact varie selon l’implémentation et le recordsize, mais vous devez supposer un coût RAM réel et non négligeable. Si l’ARC est déjà tendu, un grand L2ARC peut nuire. Vous voulez assez de RAM pour garder les métadonnées les plus utiles et les données fréquemment utilisées dans l’ARC, tandis que le L2ARC attrape ce qui déborde.
Commencez petit et prouvez la valeur
Points de départ opérationnellement sensés :
- Choisissez une taille L2ARC qui est au plus quelques multiples de la RAM pour des systèmes typiques, sauf si vous avez mesuré et pouvez justifier davantage.
- Privilégiez un NVMe « à taille adaptée » plutôt que le « plus grand disponible ». Un cache qui ne chauffe jamais est un monument à l’optimisme.
- Mesurez les taux de hit et l’amélioration de latence avant d’augmenter.
Recordsize et compression comptent
ZFS met en cache des blocs. Si vos datasets utilisent un recordsize de 1M pour des écritures séquentielles volumineuses, cela peut changer le comportement de caching comparé à un recordsize de 16K typique de certaines bases de données. La compression affecte aussi combien de données « logiques » tiennent dans le cache et peut améliorer la capacité effective du cache — parfois de façon spectaculaire.
Réglages importants (et ceux qui comptent peu)
La plupart du tuning du L2ARC vise à réduire la mise en cache inutile et à empêcher le remplissage du cache de devenir une charge à part entière.
Privilégier les lectures à la demande plutôt que la prélecture
La prélecture est ZFS qui essaie d’être utile pour l’accès séquentiel. Pour le L2ARC, elle peut être activement contre-productive car elle remplit le cache de données lues une fois, séquentiellement, et jamais relues.
Approche courante : activer le L2ARC mais le configurer pour éviter de mettre en cache la prélecture. Sur Linux/OpenZFS, cela se contrôle souvent via l2arc_noprefetch. Les valeurs par défaut et le comportement varient selon la version ; mesurez sur votre build.
Contrôler le débit d’alimentation
Le L2ARC est alimenté par l’éviction de l’ARC. Il y a des tunables contrôlant combien est écrit par intervalle et la vitesse de montée en charge. Si vous poussez trop fort, vous :
- Augmentez la charge d’écriture sur le NVMe (impact endurance).
- Dépensez du CPU pour la tenue des métadonnées du cache.
- Potentiellement entrez en compétition avec l’I/O réelle du workload.
L2ARC persistant : utile, mais pas à idolâtrer
Le L2ARC persistant réduit la chauffe après reboot en conservant en-têtes et contenu du cache entre redémarrages. C’est un grand avantage pour les systèmes qui rebootent pour mises à jour et ont besoin de performances post-reboot prévisibles. Mais la persistance peut augmenter la complexité et le comportement de scan au démarrage. Traitez-la comme toute autre fonctionnalité : testez, puis déployez.
Tâches pratiques : commandes, sorties et décisions
Voici des tâches réelles que vous pouvez exécuter sur un hôte Linux OpenZFS. Les sorties sont représentatives. Vos chiffres différeront ; vos décisions ne devraient pas être basées sur des impressions.
Task 1: Verify pool health before touching cache
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:43 with 0 errors on Sun Dec 22 03:10:12 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : Vous n’êtes pas déjà en feu. Si vous voyez des erreurs de checksum ou des vdevs dégradés, corrigez cela d’abord.
Décision : N’ajoutez un L2ARC qu’à un pool stable. Un périphérique cache ne sauvera pas un pool malade.
Task 2: Check whether an L2ARC already exists
cr0x@server:~$ sudo zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 65.4T 41.2T 24.2T - - 22% 63% 1.00x ONLINE -
raidz2 65.4T 41.2T 24.2T - - 22% 63%
sda - - - - - - -
sdb - - - - - - -
sdc - - - - - - -
sdd - - - - - - -
sde - - - - - - -
sdf - - - - - - -
Ce que cela signifie : Aucune section cache affichée, donc pas de L2ARC.
Décision : Procédez à la sélection et à l’attachement d’un NVMe, ou arrêtez-vous si vous pouvez résoudre le problème avec de la RAM ou un meilleur layout.
Task 3: Confirm the NVMe device identity and health (before ZFS touches it)
cr0x@server:~$ lsblk -o NAME,MODEL,SIZE,ROTA,TYPE,MOUNTPOINT | grep -E 'nvme|NAME'
NAME MODEL SIZE ROTA TYPE MOUNTPOINT
nvme0n1 Samsung SSD 980 PRO 931.5G 0 disk
Ce que cela signifie : Vous vous apprêtez à utiliser /dev/nvme0n1, 1 To, non rotatif.
Décision : Confirmez que vous ne pointez pas sur votre disque système. Si ce NVMe contient également root, arrêtez. Le partage est possible mais rarement judicieux.
Task 4: Check NVMe SMART and endurance indicators
cr0x@server:~$ sudo smartctl -a /dev/nvme0n1 | sed -n '1,35p'
smartctl 7.4 2023-08-01 r5530 [x86_64-linux-6.8.0] (local build)
=== START OF INFORMATION SECTION ===
Model Number: Samsung SSD 980 PRO 1TB
Serial Number: S5GXNF0R123456A
Firmware Version: 5B2QGXA7
PCI Vendor/Subsystem ID: 0x144d
IEEE OUI Identifier: 0x002538
Total NVM Capacity: 1,000,204,886,016 [1.00 TB]
Unallocated NVM Capacity: 0
Controller ID: 6
Number of Namespaces: 1
Namespace 1 Size/Capacity: 1,000,204,886,016 [1.00 TB]
SMART/Health Information (NVMe Log 0x02)
Critical Warning: 0x00
Temperature: 44 Celsius
Available Spare: 100%
Available Spare Threshold: 10%
Percentage Used: 2%
Data Units Written: 14,512,331
Data Units Read: 22,900,112
Ce que cela signifie : Le disque est sain, usure faible (Percentage Used).
Décision : Si l’usure est déjà élevée, ne pas proposer ce périphérique pour le churn du cache. Si vous devez l’utiliser, limitez le débit d’alimentation et surveillez les écritures.
Task 5: Observe current ARC size and pressure
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsize c
12:10:01 8160 1432 17 902 11 420 5 110 1 46G 58G
12:10:02 7992 1470 18 961 12 401 5 108 1 46G 58G
12:10:03 8421 1522 18 1002 12 413 5 107 1 46G 58G
Ce que cela signifie : L’ARC est ~46G, target/limit ~58G. Taux de miss ~18%. Ça peut être acceptable ou catastrophique selon la latence du pool.
Décision : Si l’ARC est loin de sa cible parce que l’OS la prive de mémoire, corrigez la pression mémoire d’abord. Le L2ARC ne remplace pas la RAM.
Task 6: Measure where your reads are coming from right now
cr0x@server:~$ sudo zpool iostat -v tank 1 3
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 41.2T 24.2T 8900 420 195M 6.8M
raidz2 41.2T 24.2T 8900 420 195M 6.8M
sda - - 1500 70 33.0M 1.2M
sdb - - 1490 72 32.8M 1.1M
sdc - - 1520 71 33.5M 1.1M
sdd - - 1475 68 32.4M 1.1M
sde - - 1460 69 32.1M 1.1M
sdf - - 1455 70 31.9M 1.1M
Ce que cela signifie : Les lectures frappent fortement les vdevs HDD. Si la latence est élevée et que le working set est relu, le L2ARC peut aider.
Décision : Si les disques sont saturés et les lectures aléatoires, un cache est plausible. Si les lectures sont petites et axées sur les métadonnées, envisagez plutôt un vdev spécial.
Task 7: Attach NVMe as L2ARC
cr0x@server:~$ sudo zpool add tank cache /dev/nvme0n1
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
cache
nvme0n1 ONLINE 0 0 0
Ce que cela signifie : Le NVMe est maintenant un périphérique cache (L2ARC).
Décision : Ne déclarez pas la victoire. Maintenant vous surveillez la chauffe, le taux de hit et les écritures NVMe.
Task 8: Verify L2ARC is being used (hit rates and size)
cr0x@server:~$ arcstat 1 5 | sed -n '1,6p'
time read miss miss% ... l2hit l2miss l2miss% l2bytes arcsize c
12:18:01 9010 1210 13 ... 2200 980 31 190G 47G 58G
12:18:02 9155 1198 13 ... 2350 960 29 191G 47G 58G
12:18:03 9033 1160 12 ... 2480 910 27 192G 47G 58G
12:18:04 9199 1205 13 ... 2605 920 26 194G 47G 58G
12:18:05 9122 1188 13 ... 2710 890 25 195G 47G 58G
Ce que cela signifie : Le L2ARC contient ~195G et sert des hits (l2hit). Le pourcentage de L2 miss diminue à mesure qu’il chauffe.
Décision : Si l2bytes reste minuscule pendant des heures sous charge stable, quelque chose cloche : débit d’alimentation, charge ou simplement absence d’éviction de blocs utiles.
Task 9: Watch NVMe I/O to ensure cache fill isn’t clobbering latency
cr0x@server:~$ iostat -x 1 3 | sed -n '1,25p'
Linux 6.8.0 (server) 12/26/2025 _x86_64_ (32 CPU)
Device r/s w/s rMB/s wMB/s await svctm %util
nvme0n1 3200.0 180.0 125.0 40.0 0.7 0.2 68.0
sda 250.0 12.0 4.1 0.3 18.4 2.2 55.0
sdb 240.0 11.0 4.0 0.3 19.1 2.2 54.0
Ce que cela signifie : Le NVMe est occupé, mais la latence (await) est faible. Les HDD montrent un await plus élevé, typique.
Décision : Si le await du NVMe monte à plusieurs millisecondes et concurrence l’I/O applicative, réduisez le débit d’écriture du L2ARC ou reconsidérez la conception. Votre cache ne doit pas devenir votre périphérique le plus chaud.
Task 10: Confirm dataset properties that influence cache behavior
cr0x@server:~$ sudo zfs get -o name,property,value,source recordsize,primarycache,secondarycache,compression tank/vmstore
NAME PROPERTY VALUE SOURCE
tank/vmstore recordsize 128K local
tank/vmstore primarycache all default
tank/vmstore secondarycache all default
tank/vmstore compression lz4 local
Ce que cela signifie : ARC et L2ARC sont autorisés (primarycache=all, secondarycache=all).
Décision : Si un dataset a secondarycache=none, le L2ARC ne le mettra pas en cache. Cela peut être souhaitable pour des sauvegardes en streaming, ou une mauvaise configuration silencieuse.
Task 11: Exclude streaming datasets from L2ARC to prevent pollution
cr0x@server:~$ sudo zfs set secondarycache=none tank/backups
cr0x@server:~$ sudo zfs get -o name,property,value,source secondarycache tank/backups
NAME PROPERTY VALUE SOURCE
tank/backups secondarycache none local
Ce que cela signifie : Le dataset de sauvegarde ne remplira pas le L2ARC.
Décision : Faites cela lorsque vous avez de grands lecteurs/écrivains séquentiels qui évinceraient des blocs utiles mis en cache. Gardez le cache pour les workloads qui le méritent.
Task 12: Inspect L2ARC-related module parameters (Linux OpenZFS)
cr0x@server:~$ sudo sysctl -a 2>/dev/null | grep -E 'l2arc_|zfs\.arc_' | head
zfs.l2arc_noprefetch = 1
zfs.l2arc_write_max = 8388608
zfs.l2arc_write_boost = 33554432
zfs.arc_max = 62277025792
zfs.arc_min = 15569256448
Ce que cela signifie : La prélecture n’est pas mise en cache dans le L2ARC, et des limites d’écriture sont définies (octets par intervalle).
Décision : Si l2arc_noprefetch vaut 0 et que vous avez des workloads séquentiels, envisagez de l’activer. Si le remplissage du cache est trop agressif, ajustez prudemment l2arc_write_max et validez.
Task 13: Change an L2ARC tunable safely (temporary) and validate impact
cr0x@server:~$ sudo sysctl -w zfs.l2arc_write_max=4194304
zfs.l2arc_write_max = 4194304
Ce que cela signifie : Débit maximal d’écriture réduit vers le L2ARC (ici à 4 MiB par intervalle ; l’intervalle dépend de l’implémentation).
Décision : Utilisez cela si les écritures NVMe concurrencent des lectures/écritures sensibles à la latence. Re-vérifiez iostat et la latence p99 des applications après le changement.
Task 14: Confirm that you are not confusing SLOG with L2ARC
cr0x@server:~$ sudo zpool status tank | sed -n '1,35p'
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
cache
nvme0n1 ONLINE 0 0 0
Ce que cela signifie : Seule une vdev cache est présente. L’absence d’une section logs signifie pas de SLOG.
Décision : Si votre douleur vient d’écritures synchrones (NFS avec sync, bases de données avec modèles fsync intensifs), le L2ARC ne résoudra pas ça. Envisagez le SLOG — prudemment — uniquement après mesure.
Task 15: Remove L2ARC (if it’s not helping) without drama
cr0x@server:~$ sudo zpool remove tank nvme0n1
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
Ce que cela signifie : L2ARC détaché. Le pool reste inchangé structurellement (les vdevs cache ne contiennent pas de données uniques).
Décision : Si les performances ne changent pas ou s’améliorent après suppression, votre cache était du bruit ou nuisible. Arrêtez d’essayer de le faire fonctionner et corrigez le vrai goulet.
Task 16: Evaluate memory pressure and reclaim behavior (Linux)
cr0x@server:~$ free -h
total used free shared buff/cache available
Mem: 128Gi 94Gi 4.1Gi 1.2Gi 30Gi 26Gi
Swap: 16Gi 2.3Gi 13Gi
Ce que cela signifie : La RAM est fortement utilisée, available est 26Gi, swap est utilisé.
Décision : L’activité de swap sur une machine de stockage est souvent un signe que l’ARC est étranglé ou que l’hôte est surchargé (VMs, containers). Avant d’ajouter un L2ARC, envisagez d’ajouter de la RAM ou de réduire les charges en colocation. Le surcoût mémoire du L2ARC n’aidera pas un hôte qui swap.
Procédure de diagnostic rapide : trouver le goulot en minutes
Ceci est l’ordre qui fait gagner du temps en production. L’objectif n’est pas « collecter toutes les métriques ». L’objectif est « identifier la ressource limitante et le correctif le plus simple ».
Première étape : déterminer si vous avez un problème de latence de lecture ou autre
- Vérifiez l’I/O du pool et des proxys de latence :
zpool iostat -v 1,iostat -x 1. - Si les disques ne sont pas occupés et que la latence est faible, votre problème peut être CPU, réseau, verrous applicatifs ou comportement d’écriture sync.
Deuxième étape : vérifier l’efficacité de l’ARC et la pression mémoire
- Utilisez
arcstatpour évaluer le taux de misses et la stabilité de la taille ARC. - Utilisez
free -het observez le swap. Si l’hôte swappe, corrigez cela. Le L2ARC n’est pas un remède à la famine mémoire.
Troisième étape : confirmer que la charge a de la localité temporelle
- Recherchez des lectures répétées : comportement de cache de DB, vagues de démarrage de VM, builds CI répétés.
- Si c’est principalement du streaming, le L2ARC sera un générateur d’usure.
Quatrième étape : tester un petit L2ARC et mesurer
- Ajoutez un NVMe L2ARC et surveillez
l2hit,l2misset la latence p95/p99 applicative. - La chauffe importe ; évaluez sur un cycle de workload, pas sur 10 minutes.
Cinquième étape : si c’est lourd en métadonnées, envisagez une autre conception
- L’I/O aléatoire des métadonnées sur des pools HDD répond souvent mieux à un vdev spécial qu’au L2ARC.
- Si la latence des écritures sync est le problème, mesurez et envisagez le SLOG (avec le périphérique adéquat et des attentes réalistes).
Trois micro-récits du milieu professionnel
Micro-récit 1 : l’incident causé par une fausse hypothèse
Ils avaient un cluster de virtualisation chargé sur RAIDZ2 HDD. Les utilisateurs se plaignaient de « lenteurs aléatoires », surtout le lundi matin. L’équipe storage a constaté des IOPS de lecture sur le pool et a décidé de « réparer proprement » avec un gros NVMe L2ARC — plusieurs téraoctets, parce que les achats aiment les chiffres ronds.
Cela s’est bien installé. Les graphes semblaient enthousiasmants : l’utilisation du NVMe a bondi et les IOPS de lecture du pool ont chuté. Tout le monde s’est senti malin pendant environ un jour.
Puis la latence a commencé à grimper. Pas sur le pool HDD — sur l’hôte. La taille de l’ARC a diminué. L’hyperviseur a commencé à swaper sous charge. Les vagues de démarrage de VM se sont aggravées, pas améliorées, et le helpdesk a appris du vocabulaire nouveau.
L’hypothèse erronée était simple : « L2ARC c’est du cache en plus, ça ne peut pas empirer la mémoire. » En réalité, le L2ARC gigantesque a consommé les métadonnées ARC et réduit la cache RAM effective. Le système a échangé des hits RAM rapides contre des hits NVMe plus lents et plus de misses. Ils ont retiré le L2ARC, ajouté de la RAM aux hôtes, et réintroduit un cache plus petit ensuite, ciblé sur des datasets spécifiques. Les performances se sont normalisées et sont restées ennuyeuses.
Micro-récit 2 : l’optimisation qui s’est retournée contre eux
Une équipe de plateforme data exécutait des analytics sur un pool ZFS supporté par des SSD. Ils voulaient accélérer des requêtes de dashboard, et quelqu’un a proposé un L2ARC sur un NVMe grand public de rechange. « C’est juste du cache ; si ça casse, rien ne se casse. » C’était techniquement vrai dans le sens le plus étroit.
Ils ont réglé les paramètres d’écriture du L2ARC de façon agressive pour « le chauffer plus vite ». Il s’est effectivement chauffé plus vite. Il a aussi écrit constamment, parce que la charge scannait de larges fenêtres de données avec peu de réutilisation. Le L2ARC est devenu un tapis roulant d’écriture.
Quelques semaines plus tard, le NVMe a commencé à renvoyer des erreurs média. Pas catastrophique, mais suffisant pour générer des alertes et des micro-saccades I/O. Lors d’un incident, le reset du périphérique a provoqué des blocages temporaires ressemblant à une panne de stockage à l’échelle du cluster. Les gens ont accusé ZFS. ZFS a majoritairement haussé les épaules ; le périphérique faisait une mauvaise journée.
Le postmortem était gênant car l’« optimisation » n’avait pas amélioré le p99 du dashboard de toute façon. Le correctif était plat : retirer le L2ARC, optimiser les requêtes pour réduire le churn, et plus tard ajouter un petit vdev spécial pour métadonnées et petits blocs. Les dashboards se sont améliorés et le NVMe a cessé de mourir pour une fonctionnalité que personne ne savait quantifier.
Micro-récit 3 : la pratique ennuyeuse mais correcte qui a sauvé la mise
Un établissement financier utilisait ZFS pour le stockage VM et services internes. Ils avaient un L2ARC sur NVMe en miroir (oui, en miroir — ils avaient les emplacements et préféraient dormir tranquille). Leur politique de changements était douloureusement stricte : chaque changement storage nécessitait une baseline pré-change, un plan de rollback et un indicateur de succès explicite.
Les patchs trimestriels exigeaient des reboots, et ils avaient déjà observé des baisses de performance post-reboot pendant la chauffe des caches. Ils ont testé le L2ARC persistant en staging, confirmé le comportement au reboot, et l’ont déployé avec des tunables choisis et une procédure documentée pour « désactiver la persistance ».
Puis est arrivé une semaine difficile : un déploiement applicatif a augmenté l’amplification de lecture et rendu les caches moins efficaces. Parce qu’ils avaient des baselines, ils ont pu prouver que ce n’était pas « le stockage qui vieillissait ». Ils ont ajusté les politiques de cache des datasets pour la charge bruyante et protégé le cache de la pollution. Pas d’héroïsme. Pas d’appels au constructeur. Juste de la compétence.
Ce n’était pas glamour, mais cela a empêché la boucle classique : « le stockage est lent » → « ajoutons du cache » → « toujours lent » → « ajoutons plus de cache ». Leur processus ennuyeux a sauvé des jours de travail.
Blague #2 : La seule chose plus persistante que le L2ARC est un acteur qui demande si on peut « juste ajouter plus de NVMe ».
Erreurs courantes : symptômes → cause → correctif
1) Symptom: L2ARC hit rate stays near zero
Cause : La charge est en streaming ou a peu de localité de relecture ; ou le dataset a secondarycache=none ; ou le cache est trop petit et thrash immédiatement.
Correctif : Vérifiez les propriétés des datasets avec zfs get secondarycache. Excluez les datasets en streaming. Si la localité est faible, retirez le L2ARC et investissez ailleurs.
2) Symptom: ARC size shrinks after adding L2ARC, misses increase
Cause : Le surcoût RAM pour les métadonnées L2ARC réduit la capacité ARC ; hôte sous pression mémoire ; L2ARC surdimensionné.
Correctif : Réduire la taille du L2ARC (partition/périphérique plus petit), ajouter de la RAM, ou retirer le L2ARC. Confirmez avec arcstat et free -h.
3) Symptom: NVMe utilization high, latency spikes, application gets worse
Cause : Débit d’alimentation du L2ARC trop agressif ; NVMe grand public avec comportement soutenu médiocre ; remplissage du cache qui concurrence le workload.
Correctif : Baisser l2arc_write_max/l2arc_write_boost. Utiliser un NVMe à performance cohérente. Envisager d’exclure les datasets bruyants du L2ARC.
4) Symptom: Performance great… until reboot, then awful for hours
Cause : L2ARC non persistant requiert une chauffe ; le workload dépend fortement des hits cache.
Correctif : Évaluer le L2ARC persistant dans votre version de ZFS. Si non disponible ou non souhaitable, planifiez les reboots et préchauffez, ou augmentez la RAM pour réduire la dépendance au L2ARC.
5) Symptom: You expected faster writes, but nothing changed
Cause : Le L2ARC est un cache de lecture. Les écritures dépendent du comportement ZIL/SLOG, du layout du pool et des sémantiques sync.
Correctif : Mesurez les écritures sync. Si nécessaire, évaluez le SLOG avec le bon périphérique et testez. Ne faites pas de cargo-cult « NVMe = plus rapide ».
6) Symptom: L2ARC helps some workloads, but backups slow everything down
Cause : Pollution du cache et pression d’éviction causées par des lectures/écritures séquentielles de sauvegarde.
Correctif : Mettez secondarycache=none (et parfois primarycache=metadata) sur les datasets de sauvegarde. Réservez le cache aux workloads interactifs/chauds.
7) Symptom: Lots of CPU usage in kernel during load after enabling L2ARC
Cause : Overhead de bookkeeping du cache plus activité d’éviction élevée ; possiblement trop de petits blocs, alimentations trop agressives.
Correctif : Réduire le débit d’écriture du L2ARC ; s’assurer que vous ne mettez pas en cache la prélecture ; envisager d’augmenter le recordsize ou repenser le pattern I/O du workload.
8) Symptom: NVMe wears out faster than expected
Cause : Churn constant dû à faible localité ; cache surdimensionné avec fort turnover ; tunables d’écriture agressifs.
Correctif : Mesurez le taux d’écriture, limitez l’alimentation, excluez les datasets en streaming, ou retirez le L2ARC. Achetez des périphériques à endurance supérieure si la charge le justifie.
Listes de contrôle / plan étape par étape
Plan A: Decide whether you should add L2ARC at all
- Confirmez que c’est un problème de lecture. Si votre pool est limité en écriture ou en sync, arrêtez et diagnostiquez cela plutôt.
- Mesurez le taux de miss ARC et la marge de RAM. Si l’hôte est sous pression mémoire, priorisez la RAM et le placement des workloads.
- Validez la localité de relecture. Le L2ARC sert les « lectures qui reviennent ». Si elles ne reviennent pas, ne les mettez pas en cache.
- Vérifiez le layout du pool et les douleurs métadonnées. Si les métadonnées sont le goulot, un vdev spécial peut surpasser le L2ARC.
Plan B: Implement NVMe L2ARC safely
- Baseline avant les changements. Capturez
arcstat,zpool iostat,iostat -xet la latence applicative. - Choisissez un NVMe raisonnable. Favorisez la latence cohérente et l’endurance plutôt que le débit peak.
- Commencez avec une taille de cache modeste. Prouvez la valeur avant d’augmenter.
- Attachez le périphérique en tant que
cache. Vérifiez aveczpool status. - Prévenez la pollution du cache. Mettez
secondarycache=nonesur les datasets en streaming. - Surveillez la chauffe et la charge du périphérique. Regardez
l2hit/l2misset leawaitdu NVMe. - Réglez prudemment. Réduisez le débit d’écriture L2ARC si cela concurrence l’I/O réelle.
- Documentez le rollback. Sachez comment
zpool removele périphérique cache et ce que « succès » signifie.
Plan C: Operational guardrails that keep you out of trouble
- Alertes sur l’usure NVMe et erreurs média. Le L2ARC peut être dur pour les disques ; traitez-le comme un composant consommable.
- Suivez les ratios de hit du cache dans le temps. Un cache utile peut devenir inutile après des changements applicatifs.
- Planification des reboots. Si le L2ARC n’est pas persistant, planifiez les reboots quand la chauffe ne posera pas de problème.
- Gardez les changements petits. Si vous changez la taille du cache, les tunables et les propriétés des datasets en même temps, vous ne saurez jamais ce qui a fonctionné.
FAQ
1) Is L2ARC the same thing as SLOG?
Non. Le L2ARC est un cache de lecture. Le SLOG est un périphérique de journal séparé utilisé pour accélérer les écritures synchrones en raccourcissant le chemin de commit du ZIL. Outil différent, problème différent.
2) Should I mirror L2ARC devices?
En général non, parce que le L2ARC ne détient pas de données uniques. S’il tombe, vous perdez du cache et les performances retombent sur le pool. Miroitez-le seulement si le coût opérationnel de perdre le cache est élevé et que vous avez les emplacements et le budget.
3) Can L2ARC make performance worse?
Oui. Les mécanismes habituels sont la réduction de taille de l’ARC (surcoût métadonnées), la contention d’écriture du remplissage du cache et la pollution du cache par des workloads en streaming. « Cache » n’est pas automatiquement synonyme de « plus rapide ».
4) How long does L2ARC take to warm up?
Ça dépend de votre working set, du taux d’éviction de l’ARC et des limites d’alimentation du L2ARC. Pour des systèmes chargés, cela peut prendre des heures ; pour des systèmes plus calmes, des jours. Si vous voulez des gains instantanés, achetez d’abord plus de RAM.
5) Should I cache prefetch in L2ARC?
La plupart du temps : non. La prélecture peut inonder le L2ARC de données séquentielles qui ne seront pas relues. Si votre workload est majoritairement séquentiel et rejoué, testez-le — ne supposez pas.
6) How do I prevent backups from wrecking my cache?
Mettez secondarycache=none sur les datasets de sauvegarde. Dans certains environnements, envisagez aussi primarycache=metadata pour les datasets en streaming afin que l’ARC garde les métadonnées mais pas les données en bloc.
7) Is persistent L2ARC worth enabling?
Si vos workloads sont sensibles à la chauffe post-reboot et que votre version de ZFS le supporte de façon fiable, cela peut grandement améliorer la qualité de service. Testez les reboots en staging et surveillez le comportement au boot et l’utilisation mémoire.
8) I have an all-NVMe pool. Do I still need L2ARC?
Rarement. L’ARC en RAM reste plus rapide que le NVMe. Mais si le working set est énorme et relu fréquemment, et que votre pool est suffisamment chargé pour que décharger les lectures aide, le L2ARC peut encore servir. Mesurez d’abord ; sinon vous ajoutez juste de la complexité.
9) What’s better: more RAM or more L2ARC?
Plus de RAM, presque toujours. Les hits ARC sont moins coûteux que les hits L2ARC, et la RAM ne s’use pas parce que vous avez relu le même fichier deux fois. Utilisez le L2ARC quand la RAM est déjà raisonnablement dimensionnée et que vous avez encore des misses.
10) How do I know if L2ARC is paying for itself?
Surveillez la latence applicative p95/p99 et le débit, pas seulement les ratios de cache. Une augmentation de l2hit est agréable, mais la métrique métier est « moins de requêtes lentes ». Si vous ne pouvez pas démontrer une amélioration, retirez-le.
Étapes pratiques suivantes
- Baselinez aujourd’hui. Capturez
arcstat,zpool iostat -vetiostat -xpendant une période identifiée comme « lente ». - Décidez si la charge relit. Si c’est du streaming, ne bâtissez pas un temple du cache.
- Corrigez la pression mémoire d’abord. Si vous swappez ou si l’ARC n’atteint pas une taille stable, le L2ARC est une distraction.
- Commencez par un petit NVMe L2ARC et protégez-le. Excluez les datasets en streaming, évitez de cacher la prélecture et gardez des débits d’alimentation raisonnables.
- Mesurez les résultats, pas les impressions. Si la latence p99 s’améliore et que l’usure NVMe est acceptable, gardez-le. Sinon, retirez-le et passez au changement de layout ou à plus de RAM.