ūüóā Tirer parti de la d√©duplication de BTRFS: cas concret du versionnage

| ~ 6 mins | 1182 mots

Le problème

Il m’est arriv√© √† plusieurs reprises de travailler sur des projets utilisant la librairie python filedepot, cette librairie est bien pratique pour g√©rer le stockage de fichier notamment en combinaison avec Sqlalchemy.

Un point qui ne reste n√©anmoins pas forc√©ment √©vident √† g√©rer par-dessus ce type de librairie est la question du versionnage. Un cas que j’ai eu l’occasion de voir est le versionnage dans Tracim ou un contenu √† diverse r√©vision qui peuvent ou non avoir un contenu fichier associ√© diff√©rent.

Le fonctionnement du champ UploadedFileField propos√© pour Sqlalchemy par filedepot, fonctionne de sorte √† consid√©rer que le fichier est li√©e uniquement √† une ligne de base de donn√©e et il peut √™tre compliqu√© de tenter de partage un identifiant d’un m√™me fichier entre divers contenus, car par exemple, la suppression d’une ligne avec le contenu 1 supprimera le fichier associ√©, 2 pointant vers le m√™me contenu ne pourra plus y acc√©der.

Comment alors √©viter que pour une modification mineure non li√©e au fichier, que le fichier soit dupliqu√© inutilement consommant ainsi de l’espace inutilement ?

Je vois alors plusieurs approches :

  1. Mettre cette intelligence de ¬ę¬†versionnage¬†¬Ľ dans filedepot, mais cela demanderait un gros travail.
  2. Mettre cette intelligence de ¬ę¬†versionnage¬†¬Ľ dans l’application qui utilise filedepot notamment une table association entre l’identifiant du fichier pour l’application et le champ. Ce qui r√©duirait un peu l’int√©r√™t simplificateur de filedepot √† mon sens.
  3. Cr√©er une sorte de couche interm√©diaire d’intelligence entre filedepot qui g√®re cela. Cela pourrait √™tre aussi l’occasion de g√©rer d’autres features li√© au traitement du fichier¬†: indexation, g√©n√©ration de preview, …

Si la troisième solution me semble la plus intéressante a creusé, elle demande du temps à mettre en place.

Ayant envie de gagner un peu d’espace disponible sur mon serveur utilisant Tracim, j’ai trouv√© une solution de contournement √† partir du fait que btrfs supporte la fonctionnalit√© de d√©duplication.

La Déduplication Quézako ?

La d√©duplication est une fonctionnalit√© de syst√®me de fichier qui permet √† un syst√®me de fichier de dire qu’un certain contenu utilis√© par plusieurs fichiers est au m√™me endroit. Ainsi, il est possible de copier via cp --reflink=always sans utiliser d’espace suppl√©mentaire (sauf quelques meta-donn√©es). Seul certain syst√®me de fichier supporte cette fonctionnalit√© dont BTRFS.

√Ä noter que cette fonctionnalit√© est activ√© par default dans cp quand c’est possible √† partir de coreutils-9.0. Ainsi, si vous utilisez un simple cp dans un Gnu/Linux assez r√©cent et utilis√© un syst√®me de fichier comme btrfs, votre copie sera g√©rer automatiquement intelligemment sans r√©elle copie.

Revenons à nos moutons

Mais du coup, qu’est-ce que √ßa change pour nous ? Parce qu’on pourrait effectivement ajuster filedepot pour faire de la copie via reflink, mais il faudrait pour cela‚Ķ Qu’il soit conscient qu’il r√©alise une copie. Et donc on retombe dans une probl√©matique de d√©veloppement plus ou moins complexe‚Ķ

Oui ‚Ķ Sauf qu’il y a une astuce !

Il est possible de r√©aliser la d√©duplication a posteriori, quand on consid√®re que c’est n√©cessaire gr√Ęce √† un outil comme Duperemove. Ainsi, il m’est possible de r√©cup√©rer de l’espace disque sans avoir √† me soucier de l’optimalit√© ou non des solutions techniques de stockage utilis√© par le logiciel utilis√©.

L’autre grosse force est que cela fonctionne pour tous les fichiers sans la moindre distinction. Ainsi peu importe si la duplication est le fait d’un utilisateur qui aurait copi√© 2 fois le m√™me fichier, d’un m√©canisme de versionnage non intelligent, ou simplement le hasard de 2 utilisateurs qui ne se connaissent m√™me pas qui t√©l√©verse l’exacte, m√™me contenu, la d√©duplication s’effectuera.

Voici un exemple, Avec un tracim 4.5 tout neuf en conteneur et son contenu dans un syst√®me btrfs tout propre dans un fichier (gr√Ęce √† ce commentaire) :

Ajout d’un 1 fichier un peu gros sur l’instance¬†:

df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0        10G  219M  9,3G   3% /mnt/dsk

Création de 2 nouvelles révisions sans vraie modification du fichier :

Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0        10G  639M  8,9G   7% /mnt/dsk

Let’s go la d√©duplication¬†(en utilisant l’exemple de https://wiki.tnonline.net/w/Btrfs/Deduplication/Duperemove):

root@gnu:/mnt/dsk# chrt -i 0 duperemove -A -h -d -r -v -b128k --dedupe-options=noblock,same --lookup-extents=yes --io-threads=1 var/data/depot 
Using 128K blocks
Using hash: murmur3
Gathering file list...
Skipping small file /mnt/dsk/var/data/depot/2031c9c0-076e-11ee-9c12-0242ac110002/file
Skipping small file /mnt/dsk/var/data/depot/2031c9c0-076e-11ee-9c12-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/2032025a-076e-11ee-9c12-0242ac110002/file
Skipping small file /mnt/dsk/var/data/depot/2032025a-076e-11ee-9c12-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/cb00f218-076e-11ee-a461-0242ac110002/file
Skipping small file /mnt/dsk/var/data/depot/cb00f218-076e-11ee-a461-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/cb0142b8-076e-11ee-a461-0242ac110002/file
Skipping small file /mnt/dsk/var/data/depot/cb0142b8-076e-11ee-a461-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/e89f0f58-076e-11ee-827e-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/0f1a60a6-076f-11ee-a200-0242ac110002/metadata.json
Skipping small file /mnt/dsk/var/data/depot/55639ca8-076f-11ee-a315-0242ac110002/metadata.json
Using 1 threads for file hashing phase
[1/3] (33.33%) csum: /mnt/dsk/var/data/depot/e89f0f58-076e-11ee-827e-0242ac110002/file
[2/3] (66.67%) csum: /mnt/dsk/var/data/depot/0f1a60a6-076f-11ee-a200-0242ac110002/file
[3/3] (100.00%) csum: /mnt/dsk/var/data/depot/55639ca8-076f-11ee-a315-0242ac110002/file
Total files:  3
Total extent hashes: 3
Loading only duplicated hashes from hashfile.
Found 3 identical extents.
Simple read and compare of file data found 1 instances of extents that might benefit from deduplication.
Showing 3 identical extents of length 209.8M with id 54f11aa1
Start		Filename
0.0	"/mnt/dsk/var/data/depot/e89f0f58-076e-11ee-827e-0242ac110002/file"
0.0	"/mnt/dsk/var/data/depot/0f1a60a6-076f-11ee-a200-0242ac110002/file"
0.0	"/mnt/dsk/var/data/depot/55639ca8-076f-11ee-a315-0242ac110002/file"
Using 1 threads for dedupe phase
[0x56351b1f30c0] (1/1) Try to dedupe extents with id 54f11aa1
[0x56351b1f30c0] Add extent for file "/mnt/dsk/var/data/depot/e89f0f58-076e-11ee-827e-0242ac110002/file" at offset 0.0 (3)
[0x56351b1f30c0] Add extent for file "/mnt/dsk/var/data/depot/0f1a60a6-076f-11ee-a200-0242ac110002/file" at offset 0.0 (4)
[0x56351b1f30c0] Add extent for file "/mnt/dsk/var/data/depot/55639ca8-076f-11ee-a315-0242ac110002/file" at offset 0.0 (5)
[0x56351b1f30c0] Dedupe 2 extents (id: 54f11aa1) with target: (0.0, 209.8M), "/mnt/dsk/var/data/depot/e89f0f58-076e-11ee-827e-0242ac110002/file"
Kernel processed data (excludes target files): 419.5M
Comparison of extent info shows a net change in shared extents of: 629.3M

Après deduplication :

df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0        10G  219M  9,3G   3% /mnt/dsk

On a ainsi gagné pas moins de 419.5M !

Autres points intéressant de Duperemove:

Aller plus loin…

La solution Duperemove se conjugue bien avec le fonctionnement de Tracim, mais comment peut-on faire autrement ? Quelles solutions les autres logiciels utilisent pour conserver un historique sans surcharger les disques ?

Nextcloud¬†: De ce que je comprends de l’approche de nextcloud sur ce genre de probl√©matique, elle consiste √† tenter de r√©duire le nombre de versions sauvegard√©es ainsi le versionnage de nextcloud n’est √† ce sens pas tr√®s fiable dans une logique d’archivage, une approche hybride √† base de version par etiquette pour une gestion semi-automatique associ√© ou non ne sorte d’IA ou d’algorithme un peu malin pourrait faire l’affaire afin de limiter les versions stock√©e tout en gardant l’essentiel de l’historique.

Gestion de version¬†: L’approche des logiciels de gestion de versions comme git est int√©ressante et est clairement optimale en espace de stockage pour du fichier texte. Elle permet r√©ellement de l’archivage, de plus le principe de pouvoir associer un texte √† une modification commit, permet de s’y retrouv√© facilement. N√©anmoins l’approche ne se conjugue pas tr√®s bien avec du stockage de fichier binaire.

Voili Voil√† ! ūüėÄ