Btrfs, c'est de la fucking black magic

Posted on mar. 07 septembre 2021 in adminsys

Contexte

J'ai chez moi un NAS fait avec un HP Proliant Gen7 N54L. C'est une belle bête, un peu vieille maintenant, mais toujours vaillante, avec en standard une capacité de 4 disques 3,5". J'ai mis l'OS sur un disque supplémentaire (on peut le tweaker pour en rajouter jusqu'à 4 en plus) et j'utilisais jusqu'à ce jour 3 disques ainsi :

  • sda : 3To (xfs) pour les gros fichiers de la maison (pensez vieux films non dispo en VOD que j'ai rippé pour notre usage familial, fichiers pour de l'animation 3D, etc.., ce genre de gros fichiers)
  • sdb : 3To (xfs) pour toutes les photos et les documents familiaux à garder le plus précieusement
  • sdc : 2To (ext4) backup manuel (mais cronné quand même) du sdb

Pour les trucs vraiment importants (présents sur le sdb), j'ai d'autres backups, avec la règle des 3-2-1. L'idée c'était de ne pas perdre mes données en cas de défaillance d'un disque (tous achetés à des moments différents en veillant bien à ce qu'ils ne fasse pas partie d'un même lot de fabrication).
Dernièrement, le sda s'est retrouvé quasiment plein. J'ai donc acheté un nouveau disque de 6To pour le remplacer. C'est là que je me suis dit que je pourrais basculer sur du Btrfs, qui est le FS par défaut sur certaines distrib' linux depuis pas mal de temps, mais que je n'avais jamais choisi.
Sur un disque tout seul, c'est relativement simple, et ça s'utilise comme les autres FS.

mkfs.btrfs /dev/sdX
mount /dev/sdX /media/ou_vous_voulez    # N'oubliez pas le fstab

Et après ça s'oublie.

Raid

Notes avant la suite : je suis sur un serveur perso chez moi, du coup, les reboot ne sont pas un problème, ce n'est pas de la prod en disponibilité 99,999%. Et je vais parler de "partitions", par abus de langage, même si le vrai terme n'est pas forcément celui-là.

Depuis maintenant plus de 10 ans, je cherche un système qui me permettrait d'avoir un FS unique et quand on manque de place, on rajoute un disque ou on en remplace un par un plus gros, et ça fonctionne sans plus de complications. Je me suis toujours tenu à l'écart de LVM et de mdraid. Au niveau perso, je trouve que ça rajoute des couches inutilement compliquées, avec pas mal de contraintes. Ça se justifie totalement dans un contexte professionnel, mais pour le serveur familial qui doit juste marcher dans un coin de la maison, ça me rebutait.
Et le problème, pour moi, au-dela de la complexité, c'était l'impossibilité d'utiliser un environnement hétérogène, en terme de disque. Je ne veux pas avoir à remplacer tous les disques du serveurs si je veux juste augmenter sa capacité. Je veux juste en acheter un plus gros et c'est tout.

Et c'est là qu'est la force de Btrfs. On lui donne un nombre de disque que l'on veut, de capacités différentes, il s'en fout, il fait au mieux (qui est même mieux que ce que je pourrais faire avec un LVM+mdraid). Et ça marche !

Du coup, voici ce que j'ai fait (en root, et de mémoire, donc vérifiez avant de copier-coller) :

mkfs.btrfs /dev/sdd # formattage du dernier disque de 6To ajouté en Btrfs
mount /dev/sdd /media/sdd
rsync -a /media/gros_fichiers /media/sdd
vim /etc/fstab  # suppression de la ligne de montage du /dev/sda, et rajout de la ligne de montage du /dev/sdd à la place du sda sur /media/gros_fichiers
reboot      # Ainsi, le nouveau disque sdd prend la place du vieux sda pour l'opérationel

btrfs device add -f /dev/sda /media/gros_fichiers   # le '-f' est là pour forcer, parce que sinon, ça ne se fait pas car l'outil détecte la présence de l'ancien formattage en xfs (et c'est bien)
screen btrfs balance start -dconvert=raid1 -mconvert=raid1 /media/gros_fichiers

Il faut que j'explique, là.
Après le formattage du sdd en Btrfs, j'ai donc une partition de 6To (je passe outre les pertes diverses, là n'est pas mon propos). Quand on fait le btrfs device add, ça étend la partition en utilisant le(s) disque(s) ajouté(s). Du coup, là, je me retrouve avec une partition de 6+3=9To. Un bon petit RAID0 les doigts dans le nez, sans rien faire d'autre. C'est magique !

Et ce qui est encore plus magique, c'est le btrfs balance start -dconvert=raid1 -mconvert=raid1. Ça convertit le RAID0 (6+3 To) en RAID1 (6+3 / 2 = 4,5 To). (Je reprécise, je m'en fous des chiffres exacts, ce n'est pas mon propos). Ça veut dire que Btrfs va s'arranger au mieux pour qu'une même donnée soit présente 2 fois sur des disques différents. Dans mon cas, c'est possible car justement toutes les data tenaient sur le disque de 3To.
Ça prend un peu de temps, car il faut tout dupliquer, mais quand j'y suis revenu le lendemain, c'était terminé.

La suite, c'est donc d'y rajouter le sdc de 2To. Oui, oui, c'est possible, et c'est ce que j'ai fait devant vos yeux ébahis :

btrfs device add -f /dev/sdc /media/gros_fichiers # toujours le '-f' car le disque était utilisé avant

Du coup, ça me donne en une seule commande un RAID1 sur 3 disques différents (6+3+2 / 2 = 5,5 To). Franchement, j'ai pas de mots pour dire à quel point je trouve ça merveilleux.
J'ai terminé en rajoutant tout le reste dessus et en reconfigurant le /etc/fstab et le /etc/exports pour que tout fonctionne avec une seule "partition".

rsync -a /media/fichiers_importants /media/gros_fichiers
vim /etc/fstab      # Pour monter la partition unique Btrfs sur /media, maintenant (relisez les rsync et vous comprendrez)
reboot

btrfs device add -f /dev/sdb
screen btrfs balance start /media

On attend un petit moment, que toutes les données soient rebalancées sur les 4 disques. Une fois la redistribution faite, on a donc une seule "partition" Btrfs d'une capacité de 6+3+3+2 / 2 = 7To. Tout ça en RAID1 sur 4 disques de capacitées différentes.

Ai-je mentionné qu'hormis les reboot, tout le reste s'est fait pendant que les disques étaient utilisés ? Je bossais sur des documents/fichiers présents sur ces disques, exportés en NFS depuis un autre PC, sans rien remarquer.

C'est scandaleux tellement c'est facile. À ce niveau-là, on frole la magie.

Futur nouveau disque

Si d'aventure je voulais rajouter un nouveau disque, il me suffirait d'acheter celui qui me convient le mieux en terme de coût et capacité à ce moment-là et de faire un btrfs device add, éventuellement un btrfs balance start et c'est tout.

Si je veux augmenter la capacité en remplaçant un disque, c'est un peu plus compliqué et risqué, mais en planifiant ça comme il faut ça devrait fonctionner. Par exemple, si je veux remplacer le disque de 2To par un de 6To. Les commandes suivantes me le permettront (WARNING : non-testé, à l'inverse des commandes précédentes. Ca devrait marcher, mais je ne l'ai pas encore vérifié) :

btrfs device delete /dev/sdc /media
# Enlèvement du disque physique, et branchement du nouveau à la place
btrfs device add /dev/sdX /media
screen btrfs balance start /media

Je répète, on ne sait jamais, je n'ai pas encore testé ça. Il y a des choses à considérer avant d'enlever un disque d'un RAID, quel qu'il soit. Par exemple (non-exhaustif, et en plus d'un backup), il faut que la "partition" Btrfs ne soit pas pleine et que tous les autres disques puissent se répartir ce que contient le disque qu'on enlève, sinon, problèmes. Il ne faut pas que les autres disques tombent en panne pendant l'opération, non plus, sinon, vous êtes bon pour la perte de données.

EDIT : Au final, j'ai décidé de rester sur 3 disques (donc 6+3+3 / 2 = 6To) pour le moment, pour faciliter l'augmentation de capacité par remplacement (au fait, le btrfs device delete marche super bien, même en cours d'utilisation de la "partition"). Plutôt que de faire un delete puis add, le moment venu, je ferais l'inverse add d'un nouveau disque plus gros puis delete d'un des anciens disques. Ainsi je n'aurais pas à me soucier de vérifier trop régulièrement si j'ai la possibilité/capacité de faire le delete. Et aussi, ça me simplifiera la vie en cas de défaillance d'un des disques actuels. Dans un cas comme dans l'autre, il suffira de brancher un nouveau disque dans le 4e compartiment vide et de l'add, puis de retirer le disque crashé ou trop petit. Rester sur 3 disques et faire ainsi, me semble le mieux, vu mon use-case.

Snapshot

On verra la gestion des snapshot dans un autre temps, mais forcément, vu mon setup et mon besoin, ça ne sera pas forcément un truc très standard (pas envie de gérer des subvolumes, par exemple). Je ferais sûrement quelque chose à base de cp -r --reflink=auto /media/fichiers_importants /media/snapshot/fichiers_importants-$(date +'%Y-%m-%d'), écrasé/rotaté régulièrement (Oui, ce cp --reflink=auto est une autre magie de Btrfs).

Pour finir, un peu de doc qui m'a bien aidée : https://btrfs.wiki.kernel.org/index.php/Using_Btrfs_with_Multiple_Devices (en anglais).
La page sur le wiki de Sebsauvage (en français) peut aussi apporter des info/explications/retour d'expérience : https://sebsauvage.net/wiki/doku.php?id=btrfs

EDIT : après quelques mois d'utilisation

Ca marche super bien.

J'ai besoin d'en dire plus ?

J'ai modifié mon /etc/fstab comme ça : UUID=6......1-1f3a-4922-a...............6 /mnt btrfs defaults,noatime,autodefrag,compress=zstd 0 0. Du coup, avec le compress=zstd, tout ce qui peut être compressé le sera de manière transparente (et c'est intelligent : ça n'essayera pas de re-compresser un fichier .zip ou .tgz ou autre). Mine de rien, ça se prend. Plus de place disque sans changer/rajouter de disque, c'est super !

Je cite le site FedoraProject :

Compression saves space and can significantly increase the lifespan of flash-based media by reducing write amplification. It can also increase read and write performance.

Du coup, effet de bord non envisagé/cherché spécifiquement : après vérification, grâce au RAID intégré à Btrfs + la compression, la vitesse des transferts depuis et vers le NAS a été décuplée. Youhou !

Pour la maintenance, j'ai juste cronné une défragmentation mensuelle (avec vérification de la compression) btrfs filesystem defragment -r -v -czstd /mnt. C'est l'un des rares points noirs de Btrfs : contrairement à ext4/xfs, ça fragmente. Même si on met l'option de montage autodefrag, il faut penser à dégramenter régulièrement.

Bilan

Ca tourne bien, ça tourne plus vite et avec plus d'espace disque dispo, en RAID1 compressé transparent sur des disques hérérogènes, sans rien avoir eu à faire depuis que c'est installé. Moi, ça me va !

Btrfs, c'est de la fucking black magic, sérieusement.