ZFS pour fichiers multimédia : gros blocs, grosse compression, gros gains

Cet article vous a aidé ?

Le stockage multimédia est souvent l’endroit où les bons systèmes de fichiers se mettent à dépérir en silence. Vous montez un joli pool, copiez quelques téraoctets de vidéo, ajoutez un second client, puis soudainement « ça allait bien hier » devient la phrase la plus répétée chez vous ou au bureau.

ZFS peut rendre les charges multimédia ennuyeuses—dans le meilleur sens du terme—si vous cessez de le traiter comme un système de fichiers générique et commencez à le régler pour ce que le multimédia est réellement : de grosses lectures séquentielles, de grosses écritures séquentielles, et des métadonnées qui explosent quand les bibliothèques grandissent.

Ce que les charges multimédia exigent vraiment (et ce qu’elles n’exigent pas)

Commençons par une chose claire : la plupart des « serveurs multimédia » ne sont pas limités par les IOPS. Ils sont généralement limités par le débit ou présentent des pics de latence liés aux métadonnées et aux petites lectures aléatoires. Un film typique est volumineux et lu principalement de manière séquentielle. Même plusieurs flux concurrents sont souvent des lectures séquentielles à partir de différents offsets.

Ce qui casse tout, c’est l’écosystème autour des médias :

  • Scans de bibliothèque : beaucoup de petites lectures et de requêtes de métadonnées ; un scan Plex/Jellyfin/Emby peut ressembler à une charge de petits fichiers déguisée en charge média.
  • Vignettes, aperçus, sous-titres : petits fichiers provoquant des E/S aléatoires et un turnover des métadonnées.
  • Téléchargements/transcodages : écritures séquentielles plus tâches CPU lourdes, parfois dans les mêmes datasets que les médias terminés (ne faites pas ça).
  • Sauvegardes et réplication : lectures séquentielles soutenues qui concurrencent le streaming.

Donc le but est : optimiser le chemin des gros fichiers sans saboter le chemin des petites métadonnées. ZFS vous donne des réglages par dataset pour faire exactement cela. Servez-vous en.

Baseline d’opinion : si vous stockez de gros fichiers multimédia principalement en lecture, vous devriez penser à recordsize, compression, sync, atime et à la localisation des métadonnées / special vdev avant de perdre du temps à débattre RAIDZ vs mirrors sur Reddit.

Première petite blague (1/2) : L’optimisation du stockage, c’est comme un régime : les gains les plus rapides viennent d’arrêter les mauvaises habitudes évidentes, pas d’acheter une balance plus sophistiquée.

Gros blocs : comment recordsize se comporte réellement

Recordsize n’est pas la « taille de bloc » et ce n’est pas une promesse

ZFS stocke les données des fichiers dans des blocs de taille variable jusqu’à un maximum. Pour les filesystems (datasets de type filesystem), ce maximum est recordsize. La valeur par défaut est souvent 128K. Pour le multimédia, c’est généralement conservateur.

Comportement clé : ZFS utilisera des blocs plus petits quand il le faut. Si vous définissez recordsize=1M, vous ne forcerez pas chaque E/S à faire 1M. Les petits fichiers et la partie finale des fichiers restent plus petits. Les réécritures aléatoires peuvent aussi produire des blocs plus petits à cause du copy-on-write.

Pourquoi les gros blocs aident le multimédia

La lecture multimédia adore les longues lectures séquentielles. Les plus grands recordsize peuvent apporter :

  • Moins d’opérations I/O pour le même débit (moins de surcharge par E/S).
  • Meilleures opportunités de compression (plus de données par décision de compression).
  • Moins de blocs indirects pour les gros fichiers (moins de métadonnées à suivre).

Mais les gros blocs ont un coût :

  • Amplification de lecture pire pour les petites lectures aléatoires (lire un bloc de 1M pour obtenir 4K peut être absurde).
  • Réécritures potentiellement plus douloureuses si votre charge édite en place (rare pour les médias finalisés, courant pour les images VM—problème différent).
  • Plus de pression sur la RAM dans certains schémas de cache (l’ARC garde des buffers plus grands ; ce n’est pas toujours un problème, mais ne l’ignorez pas).

Que définir pour le multimédia

Pour les fichiers multimédia finalisés (films, épisodes, archives audio), définissez recordsize=1M sur le dataset qui les contient. Si votre OpenZFS le supporte et que votre charge est extrêmement séquentielle, recordsize=2M peut fonctionner, mais 1M est le compromis pratique : gain important, minimal d’effets indésirables.

Ne définissez pas un recordsize global unique pour tout. Votre dossier de téléchargements, les vignettes et les métadonnées applicatives ne doivent pas être entraînés dans le monde des « gros blocs ». Conservez-les dans des datasets séparés avec un recordsize approprié (souvent 128K par défaut ou même plus petit pour des charges très axées métadonnées).

Et qu’en est-il de volblocksize ?

Si vous exportez des LUN iSCSI ou un stockage basé sur zvol, cet article ne s’applique que partiellement. volblocksize est fixe à la création du zvol et se comporte différemment. Le stockage multimédia est généralement basé fichiers (SMB/NFS), concentrez-vous donc sur recordsize.

Grosse compression : quand ça marche, quand ça trompe

La compression n’est pas seulement pour économiser de l’espace

Sur les CPU modernes, la compression augmente souvent le débit parce qu’elle échange des cycles CPU contre moins de lectures/écritures disque. Pour le multimédia, cela semble inutile parce que « la vidéo est déjà compressée ». Vrai, mais incomplet.

Même dans des bibliothèques multimédia, vous trouverez :

  • Fichiers annexes textuels (sous-titres, métadonnées NFO) : compressibles.
  • Illustrations : parfois déjà compressées, parfois non (PNG peut encore se compresser un peu ; les images brutes se compressent beaucoup).
  • Artefacts de téléchargement (logs, fichiers temporaires) : hautement compressibles.
  • Formats audio : FLAC est compressé, WAV ne l’est pas.

Donc la compression « gagne » par défaut plus souvent qu’on ne le pense. Et quand elle n’économise pas beaucoup d’espace, elle peut quand même réduire les E/S pour les parties non vidéo et diminuer les pics de latence.

Choisissez l’algorithme comme un adulte

Mes choix habituels pour les datasets multimédia :

  • compression=lz4 pour une compression toujours active, faible risque et faible latence.
  • compression=zstd pour les datasets avec beaucoup de métadonnées, de documents ou de contenu mixte. Commencez autour de zstd-3 à zstd-6. Les niveaux plus élevés peuvent convenir, mais testez votre marge CPU.

Pour les fichiers vidéo purement finalisés, la compression ne réduira pas dramatiquement la taille des films. Mais en général elle ne nuira pas non plus. Le seul vrai « ne faites pas ça » est de choisir un niveau de compression lourd sur une machine déjà saturée par des transcodages CPU-intensifs.

Deuxième petite blague (2/2) : Si vous activez la compression au maximum sur un serveur qui transcode déjà du 4K, vous avez essentiellement inventé un radiateur électrique avec des sentiments.

Ce que la compression peut casser

La compression casse rarement l’exactitude ; ZFS est robuste ici. Ce qui casse, c’est votre budget de latence si vous transformez une machine légère en machine CPU-surchauffée. Les symptômes ressemblent à « le disque est lent » parce que tout se met en file d’attente derrière le CPU.

De plus : les ratios de compression peuvent induire en erreur. Un dataset peut montrer un ratio global « moyen » tout en économisant beaucoup d’E/S pour les parties non vidéo qui provoquent des pics de latence.

Organisation des datasets pour le multimédia : restez basique et rapide

Séparez les datasets selon le comportement I/O

Ne mettez pas tout sous un dataset appelé tank/media et n’en parlez plus. Vous voulez des propriétés différentes selon le comportement. Une organisation pratique :

  • tank/media — fichiers multimédia finalisés (grosses lectures séquentielles). recordsize=1M, compression=lz4 (ou zstd modéré), atime=off.
  • tank/downloads — écritures actives, fichiers partiels, décompression. Laissez recordsize par défaut ou 128K ; la compression aide beaucoup ici.
  • tank/app — état des applications (métadonnées Plex/Jellyfin). Bénéficie souvent du recordsize par défaut ; envisagez un special vdev si vous en avez un.
  • tank/backups — cibles de réplication ; réglez indépendamment pour correspondre aux schémas send/receive.

atime : désactivez-le pour le multimédia

atime met à jour les temps d’accès des fichiers. Sur le multimédia, ce ne sont que des écritures métadonnées supplémentaires sans bénéfice. Placez atime=off sur les datasets multimédia et tout dataset fortement lu. Le seul moment pour garder atime=on est si une application s’appuie dessus pour sa logique (rare aujourd’hui).

sync, dispositifs log et réalité multimédia

La plupart des ingestions multimédia sont asynchrones par nature : téléchargements, copies de fichiers, rip. Si vous servez du multimédia via SMB/NFS, le comportement client et les réglages de protocole dictent la pression d’écritures synchrones.

Guidance :

  • Ne mettez pas sync=disabled à la légère. Ça rend les benchmarks beaux et les rapports d’incident pires.
  • Si vous avez un SLOG SSD et que votre charge produit réellement des écritures sync (bases de données, images VM, NFS strict), sync=standard plus un bon SLOG peut aider. Pour des datasets multimédia majoritairement en lecture, c’est souvent négligeable.

Special vdev : la mise à niveau sous-estimée pour le multimédia

Les gros fichiers multimédia sont séquentiels, mais les métadonnées d’une grande bibliothèque ne le sont pas. Un special vdev (SSD rapides dédiés aux métadonnées et aux petits blocs) peut rendre la navigation et les scans de bibliothèque réactifs sans déplacer des téraoctets vers la flash.

Règles d’engagement :

  • Considérez le special vdev comme critique. S’il meurt et que vous ne l’avez pas en miroir, votre pool peut être compromis.
  • Réglez special_small_blocks consciemment si vous voulez y placer des petits fichiers, pas seulement des métadonnées.

Ashifts, tailles de secteur et pourquoi votre pool est pour toujours

ashift est défini à la création du vdev et est pénible à changer. Si vous utilisez des disques à secteurs 4K (la plupart), utilisez ashift=12 (ou plus si vous avez réellement 8K). Un mauvais réglage ne se manifestera pas toujours par « lent ». Il se montrera souvent comme « étonnamment plus lent que prévu » plus une amplification d’écriture supplémentaire.

C’est un de ces réglages « payez maintenant ou payez pour toujours ».

Une citation sur la fiabilité (idée paraphrasée)

Idée paraphrasée (Werner Vogels) : Tout échoue, tout le temps—donc concevez des systèmes qui s’attendent à l’échec et continuent de fonctionner.

Faits intéressants et contexte historique (parce que ça compte)

  1. ZFS est né chez Sun Microsystems comme un système de fichiers « pool de stockage », fusionnant gestion de volumes et sémantique filesystem en un seul modèle administratif.
  2. Le copy-on-write n’était pas une astuce ; il a permis des snapshots cohérents sans geler le système de fichiers, d’où des workflows de réplication propres.
  3. Les checksums de bout en bout sont fondamentaux : ZFS vérifie l’intégrité des données du disque jusqu’au chemin de lecture applicatif, pas seulement « le RAID dit que tout va bien ».
  4. L’ARC n’est pas « juste un cache » ; c’est un cache adaptatif en mémoire qui peut stocker données et métadonnées et influence fortement la performance perçue.
  5. LZ4 est devenu le défaut dans beaucoup de distributions parce qu’il est suffisamment rapide pour être essentiellement « gratuit » sur les CPU modernes pour des charges générales.
  6. Les valeurs par défaut de recordsize étaient conservatrices parce qu’un filesystem polyvalent doit bien se comporter pour des charges mixtes, pas parce que 128K est magiquement correct pour la vidéo.
  7. RAIDZ existe en partie pour réduire la pénalité d’écritures de parité comparé au RAID5 classique dans certains schémas, mais il a toujours des compromis pour les E/S aléatoires.
  8. La fonctionnalité de special vdev est relativement nouvelle comparée au ZFS classique ; elle a changé l’économie d’accélération des charges lourdes en métadonnées.

Tâches pratiques : commandes, sorties et décisions (12+)

Chaque tâche ci‑dessous inclut : une commande, une sortie réaliste, ce que cela signifie et la décision à en prendre. Hypothèses : Linux avec les outils OpenZFS installés, pool nommé tank, et datasets comme décrits plus haut.

Task 1: Confirm pool health and obvious red flags

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
status: Some supported features are not enabled on the pool.
action: Upgrade the pool to enable all features.
  scan: scrub repaired 0B in 06:12:31 with 0 errors on Sun Dec 15 03:10:12 2025
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          raidz2-0                  ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0
            ata-WDC_WD140EDFZ-...   ONLINE       0     0     0

errors: No known data errors

Signification : Le pool est en ligne ; le scrub est propre ; pas d’erreurs de lecture/écriture/checksum. « Some supported features not enabled » est informatif.

Décision : Si l’état n’est pas ONLINE ou si vous voyez des erreurs CKSUM, arrêtez le tuning et commencez par réparer le matériel/le câblage. L’optimisation de performance sur un pool malade, c’est du spectacle.

Task 2: Check dataset properties that matter for media

cr0x@server:~$ zfs get -o name,property,value -s local,default recordsize,compression,atime,sync tank/media
NAME       PROPERTY     VALUE
tank/media recordsize   128K
tank/media compression  off
tank/media atime        on
tank/media sync         standard

Signification : Ce dataset est avec des valeurs génériques : recordsize 128K, compression désactivée, atime activé.

Décision : Pour des médias finalisés, changez vers recordsize=1M, compression=lz4, atime=off. Laissez sync tel quel sauf si vous comprenez le comportement d’écritures synchrones des clients.

Task 3: Apply media-friendly settings (safely, per dataset)

cr0x@server:~$ sudo zfs set recordsize=1M compression=lz4 atime=off tank/media

Signification : Les nouveaux fichiers utiliseront jusqu’à 1M de recordsize ; les blocs existants ne sont pas réécrits magiquement.

Décision : Si vous voulez que les fichiers existants profitent des nouveaux réglages, planifiez un workflow de réécriture (Task 8).

Task 4: Verify settings took effect

cr0x@server:~$ zfs get -o name,property,value recordsize,compression,atime tank/media
NAME       PROPERTY     VALUE
tank/media recordsize   1M
tank/media compression  lz4
tank/media atime        off

Signification : Le dataset est maintenant réglé pour de grandes lectures séquentielles avec une compression à faible overhead.

Décision : Passez à la validation : voit‑on réellement des blocs plus gros et un meilleur débit ?

Task 5: Observe real-time I/O patterns during playback or copy

cr0x@server:~$ iostat -xm 2 3
Linux 6.8.0 (server)  12/25/2025  _x86_64_  (16 CPU)

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   w_await wareq-sz  aqu-sz  %util
sda              18.0   2400.0     0.0    0.0    8.1   133.3        0.5     64.0     2.0   128.0      0.2    14.0
sdb              17.5   2320.0     0.0    0.0    7.9   132.6        0.6     80.0     2.1   133.3      0.2    13.5
md0               0.0      0.0     0.0    0.0    0.0     0.0        0.0      0.0     0.0     0.0      0.0     0.0

Signification : Des lectures ont lieu avec des tailles de requête moyennes autour de ~128K au niveau des périphériques blocs. Ce n’est pas forcément « mauvais », mais cela suggère que ZFS émet encore des E/S plus petites (ou que la charge n’est pas purement séquentielle).

Décision : Vérifiez les statistiques côté ZFS (ARC, prefetch, tailles de record) et si les fichiers ont été écrits avant le changement de recordsize.

Task 6: Check ARC and memory pressure

cr0x@server:~$ arcstat 2 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
12:01:10   520    40      7     8   20    30   75     2    5   48.2G  52.0G
12:01:12   610    55      9    10   18    42   76     3    5   48.3G  52.0G
12:01:14   590    60     10    12   20    45   75     3    5   48.3G  52.0G

Signification : L’ARC est autour de ~48G avec une cible c ~52G. Le taux de miss est faible ; il y a des misses de prefetch (le streaming multimédia déclenche le prefetch).

Décision : Si l’ARC est minuscule ou se réduit constamment, enquêchez sur les limites mémoire et autres services. Les serveurs multimédia qui exécutent aussi des conteneurs et du transcodage peuvent affamer l’ARC et ensuite accuser les disques.

Task 7: Confirm actual on-disk block sizes of a media file

cr0x@server:~$ zdb -bbbb tank/media "movie.mkv" | head -n 12
Indirect blocks:
               0 L0  512K  1/1/200  16384L/32768P F=1 B=1000/1000
               1 L0  512K  1/1/200  16384L/32768P F=1 B=1000/1000
               2 L0  512K  1/1/200  16384L/32768P F=1 B=1000/1000
               3 L0  512K  1/1/200  16384L/32768P F=1 B=1000/1000

Signification : Ce fichier utilise des blocs de 512K, pas 1M. C’est quand même plus grand que 128K et peut refléter la manière dont il a été écrit (ou des réglages antérieurs).

Décision : Si vous avez besoin de blocs de 1M, réécrivez ou recopiez le fichier après avoir placé recordsize=1M (Task 8). Ne courez pas après des fantômes : recordsize est un maximum, pas une garantie.

Task 8: Rewrite existing media to adopt new recordsize/compression

cr0x@server:~$ rsync -aH --inplace --no-whole-file /tank/media/ /tank/media_rewrite/
sending incremental file list
movie.mkv
episode01.mkv
episode02.mkv

sent 119,845,232,110 bytes  received 1,842 bytes  112,394,820.31 bytes/sec
total size is 119,842,001,002  speedup is 1.00

Signification : Vous copiez les fichiers dans un nouveau dataset (ou répertoire) afin qu’ils soient réimplantés avec les nouvelles propriétés. (Utilisez un dataset séparé comme tank/media_new pour une sémantique propre.)

Décision : Après vérification, échangez les points de montage ou renommez les datasets. Évitez de réécrire en place sauf si vous êtes confiant et avez des sauvegardes ; les bibliothèques multimédia sont suffisamment volumineuses pour rendre les erreurs coûteuses.

Task 9: Check compression effectiveness on the dataset

cr0x@server:~$ zfs get -o name,property,value compressratio,compression tank/media
NAME       PROPERTY       VALUE
tank/media compression    lz4
tank/media compressratio  1.08x

Signification : Les économies globales sont ~8%. Pour un dataset « majoritairement vidéo », c’est plausible : les fichiers annexes et métadonnées se compressent ; la vidéo peu.

Décision : Gardez la compression activée. Vous obtenez des gains avec peu de CPU. Si le CPU est contraint, restez sur lz4 plutôt que des niveaux zstd lourds.

Task 10: Measure real throughput with a read test (and interpret it carefully)

cr0x@server:~$ dd if=/tank/media/movie.mkv of=/dev/null bs=8M status=progress
40097546240 bytes (40 GB, 37 GiB) copied, 38 s, 1.1 GB/s
48273149952 bytes (48 GB, 45 GiB) copied, 46 s, 1.0 GB/s
50331648000 bytes (50 GB, 47 GiB) copied, 49 s, 1.0 GB/s

Signification : Vous lisez autour de 1.0 GB/s. Ça peut venir de l’ARC (cache) ou des disques, selon la répétition et l’état du système.

Décision : Répétez après éviction des caches n’est pas trivial avec ZFS. Testez plutôt avec plusieurs gros fichiers et surveillez zpool iostat pour confirmer des lectures physiques (Task 11).

Task 11: Observe ZFS vdev throughput and queueing

cr0x@server:~$ zpool iostat -v tank 2 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        48.2T  26.1T    320     12  1.02G  45.3M
  raidz2-0  48.2T  26.1T    320     12  1.02G  45.3M
    sda         -      -     55      2   174M  7.5M
    sdb         -      -     54      2   171M  7.4M
    sdc         -      -     53      2   170M  7.6M
    sdd         -      -     54      2   171M  7.6M
    sde         -      -     52      2   168M  7.6M
    sdf         -      -     52      2   167M  7.6M
----------  -----  -----  -----  -----  -----  -----

Signification : Les lectures sont réparties sur les disques, agrégat ~1.02 GB/s. C’est physique. Bien.

Décision : Si le débit est faible mais que les clients tamponnent, vérifiez le réseau et le CPU. Si les disques montrent beaucoup d’opérations mais peu de bande passante, vous faites des E/S aléatoires de petites tailles et devez vous concentrer sur les métadonnées/special vdev/réglage des datasets applicatifs.

Task 12: Find whether metadata is the real bottleneck (directory traversal pain)

cr0x@server:~$ sudo zpool iostat -r tank 1 5
                            read IOs
pool        raidz2-0   sda   sdb   sdc   sdd   sde   sdf
----------  -------  ----  ----  ----  ----  ----  ----
tank            900   150   148   151   149   151   151
tank           1200   200   198   201   199   201   201
tank           1100   184   182   185   183   184   182

Signification : Des IOPS élevées sans mention de bande passante suggèrent beaucoup de petites lectures (métadonnées, vignettes, petits fichiers).

Décision : Envisagez un special vdev ou de déplacer les métadonnées applicatives vers un pool/dataset sur SSD. Vérifiez aussi primarycache et la taille de l’ARC.

Task 13: Check for pathological fragmentation and free space pressure

cr0x@server:~$ zpool list -o name,size,alloc,free,frag,cap,health tank
NAME  SIZE  ALLOC   FREE  FRAG  CAP  HEALTH
tank  74.3T 48.2T  26.1T   38%  64%  ONLINE

Signification : 38% de fragmentation et 64% de capacité utilisée n’est pas alarmant. La fragmentation compte davantage à forte occupation et en présence d’écritures aléatoires.

Décision : Si vous dépassez ~80% de capacité et que la frag augmente, attendez‑vous à des chutes de performance lors des écritures et des resilvers. Planifiez l’extension avant que le pool ne devienne une valise trop pleine.

Task 14: Validate sector alignment (ashift) on vdevs

cr0x@server:~$ zdb -C tank | grep -E "ashift|vdev_tree" -n | head
56:        vdev_tree:
72:            ashift: 12

Signification : ashift=12 indique des secteurs 4K. Bien pour les disques modernes.

Décision : Si ashift est 9 sur des disques 4K, la performance et l’endurance en pâtissent. Corriger nécessite de reconstruire vdevs/pool ; décidez‑en tôt, pas après 50TB.

Task 15: Check whether sync writes are unexpectedly killing ingest

cr0x@server:~$ zpool iostat -w tank 2 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        48.2T  26.1T     10    220   4.2M   38.0M
----------  -----  -----  -----  -----  -----  -----

Signification : Beaucoup d’écritures mais une bande passante modeste peut indiquer des écritures synchrones petites ou un turnover de métadonnées.

Décision : Vérifiez votre charge (SMB durable, NFS sync, comportement applicatif). Si vous avez vraiment des écritures sync et que l’ingest est critique, envisagez un SLOG miroir sur SSDs avec protection contre la perte de puissance. Si vous ne savez pas, ne touchez pas à sync=disabled.

Task 16: Confirm snapshots aren’t silently ballooning space

cr0x@server:~$ zfs list -o name,used,usedbysnapshots,refer,avail -r tank/media | head
NAME        USED  USEDBYSNAPSHOTS  REFER  AVAIL
tank/media  22.1T 3.4T             18.7T  26.1T

Signification : 3.4T est retenu par des snapshots. Ce n’est pas « mauvais », mais cela explique pourquoi des suppressions ne libèrent pas d’espace.

Décision : Si la pression d’espace augmente, implémentez une politique de rétention des snapshots (conservez quelques points, purgez le reste) surtout pour les datasets avec churn comme downloads et app metadata.

Feuille de route de diagnostic rapide : trouver le goulot en minutes

Voici la checklist que j’utilise vraiment quand quelqu’un dit « le streaming s’interrompt » ou « les copies sont lentes ». L’objectif est d’éviter des heures de réglages quand le problème est un câble, un pool plein ou un unique disque mauvais qui fait la danse interprétative.

Premier point : le pool est‑il sain et non en cours de résilver ?

  • Exécutez zpool status -v. Si vous voyez DEGRADED, resilvering, ou des erreurs de checksum, la performance est secondaire. Réparez la santé d’abord.
  • Vérifiez si un scrub/resilver tourne et sature les I/O.

Deuxième point : disques, CPU ou réseau ?

  • Disques : zpool iostat -v 2 et iostat -xm 2. Cherchez un périphérique avec un await/%util élevé par rapport aux autres.
  • CPU : top ou mpstat -P ALL 2. Cherchez un goulot mono‑thread, ou un CPU total saturé (transcodage + compression + checksums peuvent s’additionner).
  • Réseau : ip -s link et compteurs du switch. Cherchez erreurs/paquets perdus ou une négociation à 1Gb alors que vous pensiez avoir du 10Gb.

Troisième point : faites‑vous accidentellement des E/S aléatoires de petites tailles ?

  • Des IOPS élevés et une faible bande passante dans zpool iostat sont l’indicateur.
  • Métadonnées applicatives et génération de vignettes : déplacez vers SSD/special vdev, ou isolez en datasets.
  • Vérifiez atime et désactivez‑le pour les datasets en lecture‑lourde.

Quatrième point : le pool est‑il trop plein ou trop fragmenté ?

  • zpool list pour la capacité et la fragmentation.
  • Si vous êtes au‑dessus de ~80–85% d’utilisation, n’attendez pas de miracles. Planifiez une extension, supprimez avec conscience des snapshots, ou ajoutez des vdevs.

Cinquième point : confirmez que votre tuning correspond au dataset

  • zfs get recordsize,compression,atime pour le dataset concerné.
  • Si vous avez changé recordsize récemment, vérifiez les nouveaux fichiers, pas les anciens. Les anciens blocs persistent.

Trois mini-récits d’entreprise depuis le terrain

1) Incident causé par une fausse supposition : « Ce sont juste des lectures séquentielles, RAIDZ c’est OK »

Une équipe de production multimédia a construit un NAS partagé pour des monteurs. La charge « ressemblait au multimédia », donc ils l’ont dimensionnée pour le débit : grand pool HDD, RAIDZ2, beaucoup de disques, un lien réseau généreux. Tout le monde était content lors du premier import et de la première semaine de lecture.

Puis la bibliothèque a grandi. Le gestionnaire d’assets a commencé à générer des proxies, des vignettes, des aperçus de forme d’onde et des index de métadonnées. Les monteurs ont commencé à scrubber les timelines et à sauter dans les fichiers. Le patron d’E/S est devenu un mélange désordonné : lectures séquentielles pour la lecture, lectures aléatoires pour les vignettes, écritures aléatoires pour les mises à jour de métadonnées.

La fausse supposition était que « multimédia = séquentiel ». Multimédia plus outils = charge mixte. RAIDZ2 n’était pas « mauvais », mais le pool n’avait pas d’endroit rapide pour les métadonnées, et les pics de latence rendaient l’interface utilisateur cassée. Cela avait l’air d’un problème réseau parce que les clients tamponnaient et les sessions SMB restaient connectées. Tout le monde a naturellement blâmé le switch.

La solution fut ennuyeuse mais efficace : séparer les datasets, déplacer les métadonnées applicatives sur SSDs, ajouter un special vdev en miroir, et arrêter de frapper le même dataset à la fois avec des médias finalisés et des métadonnées en mutation constante. Le réglage de recordsize a aidé, mais le véritable gain a été d’offrir une voie rapide aux métadonnées.

Après cela, la performance est devenue prévisible. Pas « prévisible au maximum des benchmarks »—vraiment prévisible. Le type qui fait taire les fils Slack.

2) Optimisation qui a échoué : désactiver sync pour « accélérer l’ingest »

Un groupe de communication a ingéré des centaines de Go par jour de rushes caméra. Quelqu’un a lancé un benchmark rapide, constaté des écritures lentes, et trouvé le fameux réglage : sync=disabled. On le retourne, l’ingest double. Un héros est né.

Quelques semaines plus tard, un événement d’alimentation électrique touche le bâtiment. L’UPS a fait ce qu’il pouvait, mais l’hôte a perdu l’alimentation en plein ingest. Au redémarrage, le pool a été importé correctement. Le système de fichiers a monté. Mais les fichiers les plus récents étaient corrompus de manière subtile—des clips avec des artefacts, des segments manquants, des échecs de vérification de somme dans l’application de montage.

Aucune erreur « ZFS cassé » évidente n’apparaissait. C’est le piège. Désactiver sync ne casse pas le pool ; ça casse vos promesses. Les applications qui croyaient que fsync() signifiait « sur stockage stable » ont été trompées. Elles ont fait ce qu’elles devaient faire ; le stockage ne l’a pas respecté.

La remédiation a pris du temps : ré-ingest depuis les sources, mise en place d’une protection contre la perte de puissance adéquate, et restauration de sync=standard. Ils ont ajouté un petit SLOG en miroir sur SSDs avec protection contre la perte de puissance, ce qui a rendu la plupart des performances d’ingest tout en gardant la sémantique intacte.

L’optimisation qui repose sur le mensonge aux applications n’est pas de l’optimisation. C’est une dette avec intérêt.

3) Pratique ennuyeuse mais correcte qui a sauvé la mise : scrubs mensuels + alerting

Une archive de streaming interne tournait sur un grand pool ZFS. Rien d’extraordinaire : bons contrôleurs, boot en miroir, données en RAIDZ2, et un special vdev en miroir pour les métadonnées. L’équipe avait une pratique religieuse : scrubs planifiés et alertes qui réveillaient quelqu’un qui s’en préoccupait vraiment.

Un mois, un scrub a signalé quelques erreurs de checksum sur un disque. Le système a réparé les données en utilisant la redondance, mais l’alerte a déclenché. Le disque n’était pas visiblement HS ; SMART semblait « correct », parce que SMART aime l’optimisme.

Ils ont remplacé le disque pendant les heures ouvrables, calmement, avant que cela n’escalade en une défaillance multi‑disques lors d’un resilver. Une semaine plus tard, un second disque du même lot a commencé à renvoyer des erreurs de lecture. Sans le premier remplacement, cela aurait pu être une très mauvaise journée.

Pas de tuning héroïque. Pas de sysctl secret. Juste des scrubs, des alertes et la volonté de remplacer un disque qui se dénonçait tôt. La fiabilité, c’est surtout refuser d’être surpris.

Erreurs courantes : symptôme → cause racine → correctif

1) « Le streaming s’interrompt quand quelqu’un lance un scan de bibliothèque »

Symptôme : La lecture se met en pause ou l’interface devient lente pendant les scans, la génération de vignettes ou le rafraîchissement des métadonnées.

Cause racine : Le workload métadonnées/petits fichiers concurrence les lectures de streaming sur les mêmes vdevs ; l’ARC est thrashé par des lectures aléatoires.

Correctif : Séparez les datasets ; déplacez les métadonnées applicatives sur SSD ou ajoutez un special vdev en miroir ; gardez les fichiers média dans un dataset gros-bloc ; envisagez de limiter la concurrence des scans dans l’application.

2) « J’ai mis recordsize=1M mais rien n’a accéléré »

Symptôme : Aucun changement mesurable après le réglage.

Cause racine : Les fichiers existants conservent leur ancien layout de blocs ; recordsize s’applique principalement aux nouvelles écritures.

Correctif : Réécrivez/re-copiez les fichiers dans un dataset avec les nouveaux réglages (rsync ou zfs send/recv). Vérifiez avec zdb sur un échantillon de fichier.

3) « Les écritures sont lentes et iostat montre des petites écritures avec une latence élevée »

Symptôme : L’ingest semble limité à quelques dizaines de Mo/s ; pics de latence.

Cause racine : Écritures sync provenant de SMB/NFS/du comportement applicatif, pas de SLOG, ou disques lents forcés à commettre fréquemment.

Correctif : Gardez sync=standard. Si les écritures sync sont réelles et importantes, ajoutez un SLOG miroir sûr en cas de perte de puissance ; sinon, ajustez les réglages clients/app qui forcent le sync.

4) « Le pool est devenu plus lent avec le temps même si les disques sont sains »

Symptôme : Dégradation progressive des performances, surtout sur les écritures et pendant la maintenance.

Cause racine : Forte occupation du pool et fragmentation ; beaucoup de churn sous snapshots ; amplification d’écriture RAIDZ qui s’aggrave avec l’utilisation élevée.

Correctif : Gardez les pools sous ~80–85% d’utilisation ; purgez les snapshots ; ajoutez des vdevs avant d’être désespéré ; isolez les datasets churny comme downloads.

5) « L’exploration SMB est lente mais le streaming va bien »

Symptôme : Lister les répertoires et ouvrir des dossiers prend des secondes ; la lecture une fois démarrée est correcte.

Cause racine : Latence des métadonnées. La traversée de répertoires et les appels stat sont des petites lectures aléatoires ; peut‑être que atime est activé.

Correctif : atime=off ; special vdev pour les métadonnées ; assurez-vous que l’ARC dispose de suffisamment de RAM ; n’hébergez pas l’état applicatif lourd en métadonnées sur les mêmes disques rotatifs que le bulk media si vous pouvez l’éviter.

6) « Des erreurs de checksum apparaissent pendant un scrub »

Symptôme : zpool status montre des octets réparés ou des comptes CKSUM croissants.

Cause racine : Disque défaillant, câble/backplane instable, problèmes de contrôleur, ou (moins souvent) instabilité mémoire.

Correctif : Traitez‑le comme un incident matériel. Reseat/remplacez les câbles, déplacez les disques de baie, lancez des tests SMART longs, remplacez les disques suspects. Ne « tunez » pas les erreurs de checksum.

Listes de vérification / plan étape par étape

Plan A : Nouveau pool multimédia, fait correctement

  1. Choisissez la topologie vdev selon le domaine de défaillance et le temps de rebuild : RAIDZ2 pour de grands pools HDD est un bon défaut ; mirrors si vous avez besoin de meilleures I/O aléatoires et de resilvers plus rapides.
  2. Réglez ashift correctement à la création (typiquement 12 pour les HDD 4K modernes).
  3. Créez des datasets par charge : media, downloads, métadonnées applicatives, backups.
  4. Définissez les propriétés des datasets :
    • Media : recordsize=1M, compression=lz4, atime=off.
    • Downloads : compression activée ; recordsize par défaut ; considérez sync=standard toujours.
    • App : recordsize par défaut ; envisagez SSD/special vdev.
  5. Implémentez des snapshots avec rétention (surtout pour app et downloads). Gardez la politique simple pour qu’elle soit effectivement exécutée.
  6. Scrubs programmés + alertes. Si vous n’alertez pas, vous ne faites pas de scrub ; vous écrivez votre regret.
  7. Testez avec des workflows réels : flux simultanés + scan + ingestion. Les tests synthétiques ne vous disent que comment serait votre vie synthétique.

Plan B : Pool existant avec réglages génériques

  1. Confirmez la santé : zpool status. Corrigez les erreurs d’abord.
  2. Séparez les datasets : créez tank/media, tank/app, tank/downloads si vous ne les avez pas déjà.
  3. Appliquez les propriétés multimédia à tank/media seulement.
  4. Réécrivez ou recopiez les fichiers pour adopter recordsize/compression.
  5. Déplacez les métadonnées applicatives hors des disques rotatifs si la navigation est lente (pool SSD ou special vdev).
  6. Réévaluez la capacité et la fragmentation ; planifiez une extension avant d’être à 90% d’utilisation.

Plan C : Vous êtes déjà en feu (buffering en production)

  1. Arrêtez les tâches en arrière‑plan : suspendez les scans, suspendre les sauvegardes, reportez scrubs/resilvers si c’est sûr et que la politique le permet.
  2. Lancez zpool iostat -v 2 et trouvez tout disque clairement lent ; remplacez/déplacez s’il est manifestement défaillant.
  3. Vérifiez la négociation réseau et les erreurs.
  4. Confirmez la charge : transcodez‑vous ? Le CPU peut être votre « problème disque ».
  5. Après stabilisation, implémentez la séparation des datasets et l’accélération des métadonnées.

FAQ

1) Dois‑je toujours définir recordsize=1M pour les médias ?

Pour les gros fichiers multimédia finalisés, oui. Pour tout ce qui implique de petites lectures/écritures aléatoires (métadonnées d’app, téléchargements en cours, vignettes), non. Séparez les datasets et réglez par charge.

2) La compression va‑t‑elle nuire au streaming vidéo ?

Généralement pas avec lz4. La vidéo est déjà compressée, donc les économies sont faibles, mais le coût CPU est bas. Le risque vient d’utiliser des niveaux zstd lourds sur un CPU déjà occupé par du transcodage.

3) Si le ratio de compression n’est que 1.02x, est‑ce inutile ?

Non. Même de petits gains globaux peuvent cacher des économies significatives sur les fichiers annexes et les métadonnées. Aussi, des blocs compressés peuvent réduire les octets lus sur disque pour les parties compressibles, réduisant les pics de latence.

4) Quelle est la meilleure topologie : RAIDZ2 ou mirrors ?

Pour le stockage de masse sur HDD, RAIDZ2 est un défaut sensé pour la capacité et la sécurité. Les mirrors donnent souvent l’impression d’être plus rapides pour les I/O aléatoires et les resilvers, mais coûtent plus en disques. Si votre goulot est la latence des métadonnées, un special vdev peut rapporter plus que de changer la topologie.

5) Ai‑je besoin d’un L2ARC pour un serveur multimédia ?

Rarement. Le streaming est souvent séquentiel et ne profite pas beaucoup d’un L2ARC sauf si vous relisez souvent le même contenu et manquez de RAM. Si la navigation est lente, corrigez la localité des métadonnées d’abord.

6) Dois‑je désactiver atime partout ?

Sur les datasets multimédia et en lecture‑lourde, oui. Sur les datasets où un workflow dépend de la sémantique atime (peu commun), laissez‑le activé. Si vous ne savez pas, désactivez‑le pour le multimédia et laissez les valeurs par défaut pour les datasets applicatifs jusqu’à preuve du contraire.

7) sync=disabled est‑il acceptable un jour ?

Seulement si vous acceptez explicitement le risque de perte de données en cas de coupure de courant et que vous connaissez la sémantique de la charge. Pour un usage professionnel ou tout ce que vous ne voulez pas pleurer, gardez sync=standard et utilisez du bon matériel (UPS, SLOG si nécessaire).

8) Jusqu’à quel niveau de remplissage puis‑je faire tourner un pool ZFS ?

Tâchez de rester sous ~80–85% pour des performances et une résilience prévisibles. Au‑delà, la fragmentation et les contraintes d’allocation peuvent amplifier la latence, surtout sur RAIDZ lors des écritures et des maintenances.

9) Puis‑je changer ashift après création du pool ?

Pas in‑place de manière raisonnable. La méthode pratique est de reconstruire : remplacer les vdevs par des unités correctement dimensionnées ou migrer les données vers un nouveau pool. Choisissez ashift correctement dès le départ.

10) Comment les snapshots affectent le stockage multimédia ?

Les snapshots sont bon marché jusqu’à un certain point. Les fichiers média changent rarement, donc les snapshots n’augmentent pas beaucoup—sauf si vous stockez des téléchargements churny ou des bases applicatives dans le même dataset. Utilisez des datasets séparés et une rétention de snapshots adaptée au churn.

Conclusion : étapes pratiques suivantes

Si vous voulez les « gros gains » sans transformer votre stockage en projet artistique expérimental, faites trois choses :

  1. Séparez les datasets par comportement : médias finalisés, téléchargements et métadonnées applicatives ne doivent pas partager les mêmes propriétés.
  2. Rendez le multimédia ennuyeux : recordsize=1M, compression=lz4, atime=off sur le dataset multimédia.
  3. Diagnostiquez avec des preuves : zpool status, zpool iostat, iostat, stats ARC, et capacité/fragmentation avant de tripoter des réglages.

Puis, si la navigation et les scans ressemblent encore à de la boue, arrêtez de blâmer vos disques et commencez à traiter les métadonnées comme une charge à part entière : datasets applicatifs sur SSD ou un special vdev en miroir peuvent transformer l’expérience plus que n’importe quel réglage de recordsize.

← Précédent
Ubuntu 24.04 : ballooning mémoire — imposez des limites sensées et stoppez les swap storms (cas n°76)
Suivant →
Sauvegardes MySQL vs PostgreSQL dans les conteneurs : comment éviter les fausses sauvegardes

Laisser un commentaire