🗂 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à ! 😀