[Linux] Système de fichier Btrfs et compression : performances comparées des différentes possibilitésTemps de lecture : ~14 min

J’ai découvert récemment le système de fichier Btrfs, un système de fichier bien plus avancé et intéressant que le traditionnel Ext4 utilisé par défaut un peu partout côté Linux. Grâce au fait qu’il est maintenant intégré (certes basiquement) aux installeurs graphiques, j’ai pu m’y essayer.
Il n’en reste pas moins assez complexe a appréhender, et à paramétrer (essentiellement en ligne de commande, vivement un utilitaire graphique !).

Je ne détaillerai pas dans ce billet ce qu’est Btrfs ni comment l’utiliser, mais vous pouvez par exemple consulter ce billet de sebsauvage (que je remercie chaleureusement au passage).

En particulier, ce système de fichier propose une compression à la volée des fichiers – très pratique pour gagner “gratuitement” beaucoup d’espace de stockage !
Sauf qu’on a le choix entre 3 algorithmes de compression, et plusieurs niveaux de compression pour certains d’entre eux. Que choisir ? 🤔
Il y a un cruel manque d’explications accessibles et documentées sur la question.

En cherchant sur le Web, pas moyen de trouver grand chose de complet et pertinent à me mettre sous la dent… Il me faut signaler ce benchmark de compression et celui de décompression, mais c’est à peu près tout, et dans une configuration spécifique et assez différente de la mienne. Je restais sur ma faim…

J’ai donc cherché à comparer les différents algorithmes de compression en cherchant à déterminer quelle était la ou les options optimales, selon les cas d’usages.
On y va ? 😃

Avertissement

Ce test n’a pas la prétention d’être exhaustif, de couvrir tous les cas d’usage, ni de fournir des mesures très précises des performances ou une conclusion définitive sur le choix de “la meilleure option” (si tant est quelle existe…).
Faute de trouver les ressources suffisantes en ligne, j’ai voulu mesurer quelle option était la plus optimale dans mon cas particulier. Et je vous partage mes résultats car je trouve que c’est trop peu documenté en ligne.
Libre à vous de reproduire le même test dans vos conditions réelles, rien ne sera plus adapté à votre situation 😉

Méthodologie

Matériel utilisé

Côté processeur : un Ryzen 5 3600 (6 cœurs/12threads, autour de 4,1Ghz au maximum de ses performances d’usine).
Ce processeur est intéressant comme élément de comparaison, en effet il représente le milieu de gamme actuel d’AMD, et plutôt la tranche du haut de gamme du marché grand public, d’autant plus que c’est un processeur récent.
Dans le test cité plus haut, vous avez une idée des performances pour un vieux processeur haut de gamme d’AMD, qui correspond plus à l’entrée de gamme actuelle. Je note d’ailleurs que l’écart de performances est assez faible.

Côté stockage :

  • Un disque dur Seagate Barracuda 2To, 7200 tours/min.
  • Un SSD Intel 660p 512Go, de type NVMe c’est-à-dire un SSD branché sur un port PCI-E (3.0), qui permet des débits bien supérieurs au SATA 3.

Aparté

J’ai également un SSD branché en SATA 3 (donc limité à 550Mo/s par la connectique), que je n’ai pas testé (parce qu’il faudrait que j’y créé une partition dédiée).
Il serait intéressant d’observer quel gain la compression peut apporter : si l’on peut compresser les données assez vite, les 550Mo/s de données compressées donneront une vitesse “réelle” supérieure.
Je suis preneur de retour là-dessus 🙂

Conditions du test

Le test a été réalisé sur une distribution Linux (Kubuntu 20.10) avec un noyau en version 5.8 (ce qui semble compter vu les améliorations du support de Btrfs introduites par cette version).
C’est ma machine principale et non un serveur ou autre, elle était donc utilisée en parallèle (ex: Firefox était actif) ce qui introduit un peu de variabilité dans les résultats, mais est aussi plus fidèles aux conditions réelles d’utilisation (en multi-tâche sur un ordinateur grand public).

J’ai testé les compressions suivantes:

  • lzo : a priori le plus rapide, et le moins efficace côté compression.
  • Zstandard, abrégé zstd dans la suite de ce billet, du niveau de compression 1 à 15 (le niveau maximum géré par Btrfs). Et sans forcément tester tous les intermédiaires, vous verrez pourquoi ensuite.
  • zlib : aux niveaux de compression 1 (le minimum), 3 et 9 (le maximum).

J’ai utilisé l’option de montage compress-force car c’est la plus performante et celle que j’utilise au quotidien.

La plupart des tests on été reproduits plusieurs fois, généralement à la suite. J’ai pris la moyenne des valeurs (qui ne varient pas tant que ça, sauf utilisation du disque pour autre chose en même temps) en éliminant les éventuelles valeurs incohérentes.

À noter que j’ai utilisé le “gouverneur” performance (et non celui ondemand par défaut) qui grosso modo s’assure que le processeur tourne toujours au maximum de ses performances (et de sa consommation…) sans baisser en fréquence pour économiser de l’énergie et de la dissipation de chaleur. La différence est faible avec les conditions réelles d’usages, et le but est d’éviter les biais de mesure.

Le test en lui-même

Le fichier utilisé: un profil Firefox, regroupé dans un archive format .tar de 5,1Go. Il a l’avantage de mélanger des fichiers bien compressibles (texte, base de données…) et d’autres moins (images) et de représenter à peu près des fichiers courants sur un ordinateur.

→ Pour le test de décompression: j’ai réadapté le script du benchmark cité plus haut en utilisant mon propre fichier de test. il semble pertinent (même si je ne comprends pas tout bien 😅) pour éviter les effets de cache et autres qui fausseraient les résultats.

→ Pour le test de compression: j’ai adapté le même script, en y plaçant une copie (toujours via pv) vers une zone du disque au lieu de /dev/null. Faute d’y arriver pour le cas du disque dur, j’ai finalement réduit ça à une simple copie a la mano (les résultats sont similaires).

Limites de ma méthodologie:

  • Je ne sais pas trop si des paramétrages de cache, déduplication ou autre pourraient influer sur les résultats… J’ai tout de même écarté les résultats aberrants ou très loin des performances théoriques de mes disques (7Go/s sur le SSD à un moment, plus rapide que la RAM, j’ai des doutes :p )
  • Pour les tests d’écriture sur le SSD, je copiais un fichier du SSD vers lui-même. Ça a forcément ralenti l’opération, par contre ça ne fausse pas les ordres de grandeurs (c’est le principal).

Résultats

Une précision avant de détailler les résultats et de vous montrer les graphiques: ces graphiques montrent la vitesse réelle d’écriture (ou de lecture) sur le disque. C’est-à-dire: la vitesse à laquelle mon ordinateur (dé)compresse des données et les écrit (lit) sur le support de stockage. Ce n’est pas juste la vitesse de (dé)compression, ni celle d’écriture (lecture) seule, mais c’est ce que sont capables de faire le couple processeur+stockage – et c’est ce qui nous intéresse en pratique.

Aussi: certaines courbes comportent des barres d’erreurs, qui indiquent la variabilité entre les mesures (la taille des barres est d’un écart-type) quand il y en a plusieurs. De manière générale, je considère qu’une variation de <5% (50Mo/1Go par exemple) est négligeable et peut-être due aux conditions de test.

Ah et, pour les maniaques: oui, je sais que tracer des lignes sur des données discrètes n’a pas de sens, et qu’il faudra un diagramme en barre. Mais: 1) je n’ai pas mesuré chaque niveau de compression, ça me permet de mieux voir la tendance 2) c’est finalement plus lisible. Je vous rassure, vous vous en remettrez 😉

Le disque dur

Premièrement, les performances d’écriture sans compression du disque dur sont impressionnantes (pour un disque dur), 300Mo/s (pas si loin d’un SSD SATA, notamment bas de gamme). Après recherche sur le net, il est plutôt donné à 170Mo/s, ce qui me fait émettre un doute sur la fiabilité de mon résultat…
En lecture et sans compression, il monte à 180Mo/s.

Performances en lecture 📖

On note une augmentation des performances en lecture de 66% grâce à la compression ! L’écart est d’autant plus gigantesque sur un support de stockage “lent” !

Comme vous pouvez le voir, la vitesse de décompression est très similaire quelque soit le niveau de compression (ce qui est une bonne nouvelle :). Je ne le savais pas avant de tester, mais en fait c’est un attendu pour cet algorithme.
Par contre, on pourrait s’attendre à une augmentation de la vitesse de lecture due au fait qu’une plus forte compression permet d’extraire plus de données de disque, pour un même volume lu. Hors vous verrez plus loin que la compression ne varie quasiment pas pour zstd. Cependant ceci est valable pour lzo, qui écrit un fichier nettement plus gros,

Performances en écriture 💾

On voit ici que la compression permet au disque dur d’écrire 30% plus vite. Idem que pour la lecture, l’écart est d’autant plus considérable que ce support est “lent”.

Lzo ne fait même pas mieux que la vitesse d’écrire sans compression, et zlib est loin derrière zstd, et pour que la vitesse sans compression pour zlib-9.

Le SSD

Performances en écriture 💾

On voit ici que la compression permet au SSD d’écrire au mieux 40% plus vite.
L’écart est très important, mais à relativiser, un SSD NVMe est un stockage très rapide, très peu de cas d’usage bénéficieront d’un SSD 3 fois plus rapide (1,7Go/s) qu’un SSD SATA (déjà très rapide, 0,55Go/s) au lieu de 2,3 fois (1,26Go/s).

La preuve ? 😉

Lzo fait aussi bien que les plus faibles niveaux de compression zstd . Zlib est complètement à la ramasse, on repasse sur les performances d’un SSD SATA…

Performances en lecture 📖

Je ne présente pas de graphique pour les résultats en lecture : comme pour le disque dur, la courbe est quasiment plate, les variations sont négligeables autour de 2Go/s… Et 1,4Go/s sans compression.
NB: Une valeur surprenante pour un SSD donné à 1Go/s, même si d’après de nombreux benchmark (ici 1,4Go/s) il est fréquent qu’il fasse mieux que la valeur annoncée par le constructeur (en fonction des conditions de test).
Le cache (fait de mémoire plus rapide, mais limité à quelques Go) doit aussi jouer. Ainsi un fichier plus petit (1,1Go) est transféré à 2,34Go/s.

Je note toutefois une légère augmentation des performances (+6%) au niveau de compression 15, qui est peut-être due à la compression très légèrement supérieure (~1% de 5Go, soit 50Mo… question d’arrondi ?).

Au vu des résultats en écriture, je n’ai pas pris le temps de tester les compression lzo et zlib. Elles ne me semblent rien apporter.

Le taux de compression

De façon surprenante, le taux de compression est très stable entre les différents niveaux de compression zstd (2% entre 1 et 15…). Dans mon cas, autour de 66-67%. J’ai essayé avec d’autres fichiers, ça ne semble pas lié à mon fichier de test (et d’autres ont fait la même observation). Je n’ai pas d’explication à ce phénomène.

Zlib n’est pas intéressant, le niveau minimum de compression est moins bon que zstd (68%) et le meilleur à peine équivalent à la pire valeur (67%).
Lzo est hors-jeu avec 82%, c’était attendu.

Comparaison SSD / HDD

On pourrait s’attendre à ce que les performances de compression limitent plus le SSD que le disque dur, c’est-à-dire que la vitesse de compression soit plus souvent supérieure à la vitesse d’écriture du disque qu’à celle du SSD.
Dans ce cas, on devrait voir la courbe de l’écriture côté disque dur s’écrouler au niveau de compression où les performances d’écritures sont identiques sur le SSD (par rapport à une copie brute sur le disque dur) : la compression n’arrivant pas à débiter autant que ce que le disque peut écrire, le disque dur devrait écrire moins vite.
Chose étonnante, ce n’est pas le cas. Les perfs du disque s’écroulent au niveau 11, alors que côté SSD il faut attendre le niveau 13 pour descendre sous les performances maximales du disque dur (400Mo compressés/s).

Pourquoi ? 🤔

Données non mesurées

Je n’ai pas mesuré précisément la charge du processeur, pour voir quelle compression est plus coûteuse et potentiellement gênante (un gains de performances en lecture/écriture contre une perte en vitesse de calcul n’est pas forcément intéressant selon ce qui est le plus limitant dans votre cas).
Je n’ai fait que garder sous l’œil le pourcentage de charge du processeur pendant mes tests. J’observe 3 éléments:

  • Une simple copie sur le SSD (le plus rapide, donc le plus demandeur en calcul du processeur) de ces 5Go consomme environ 5% de la puissance disponible. On peut grosso modo soustraire cette valeur “de base” liée à la copie aux données ci-dessous.
  • Les compressions les plus légères consomment 10-20%.
  • Les compressions Zlib (sauf peut-être zlib1 ?) et les compressions zstd les plus élevées (niveaux 13~15) consomment jusqu’à 80% de la puissance du processeur.

On peut voir qu’il y a une forte variation de la charge selon le niveau de compression… Et que les valeurs les plus élevées sont très coûteuses. Pour moi c’est assez prohibitif, car cela concurrencera certaines tâches lourdes (encodage vidéo, rendu 3D…) en cas d’écriture prolongée. La surconsommation d’énergie sera problématique sur un portable.

NB: À noter qu’on parle là d’un fichier relativement gros, 5Go, et que pour des écritures plus classiques l’impact doit-être quasi-invisible tellement il est bref. Et que de toute façon la copie sur SSD de ce fichier est très courte (quelques secondes), et assez courte sur un disque dur (10-20s).

Je n’ai pas mesuré la consommation en mémoire, donnée comme supérieure en zstd qu’en lzo (et probablement encore supérieure en zlib). La différence semble assez faible, et m’importe assez peu dans mon usage courant (j’ai 16Go de RAM, rarement saturés ou alors par plusieurs Go). Ma RAM est aussi en compressée via zram, ce qui réduit d’autant plus l’importance de ces différences.


Conclusion

Pour un SSD comme pour un HDD, la compression zstd est toujours bénéfique pour les vitesses de lecture et d’écriture, sachant que le processeur n’est pas un facteur limitant dans ce cas – s’il l’avait été la compression pourrait être problématique. On lit et écrit plus rapidement et on gagne de l’espace de stockage !

Comme on pouvait s’y attendre, Zstandard est le format de compression le plus intéressant, à tel point qu’il ne me semble même pas intéressant d’envisager les autres: lzo compresse peu et le supplément de données à lire/écrire fait perdre plus de temps, il n’a d’intérêt que si le processeur est vraiment très limitant ; et zlib est trop lent et ne compresse pas mieux, voir moins bien.

Le taux de compression est très similaire entre les différentes compressions zstd, à tel point que la différence est négligeable sauf pour de très gros volumes de données (quelques Go tous les 100Go). La vitesse de lecture est similaire pour tous les niveaux de compression.
Étant donné l’impact sur les performances des niveaux de compression les plus élevés, je recommande fortement de rester entre zstd 1 et 2, ou zstd 3-5 (à tester…) pour un gain léger en compression avec une faible perte en vitesse d’écriture. Pour compresser un maximum (pour de l’archivage par exemple), on passera en zstd 15, au prix d’une perte massive de performances en écriture et d’un fort surcoût en calcul.

Personnellement j’ai mis mes archives en ztsd 4, mes dossiers courants en zstd 2. Mes sauvegardes sur d’autres supports sont plus compressées.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *