PROJET AUTOBLOG


Planet-Libre

source: Planet-Libre

⇐ retour index

Ulrich Van Den Hekke : Woodstock Backup - Utilisation de Btrfs et son remplacement

mardi 12 janvier 2021 à 00:00

Bonjour à tous,

La version 1 de mon programme de sauvegarde Woodstock Backup utlise Btrfs et Rsync pour effectuer une sauvegarde. Je l'utilise depuis quelques mois pour sauvegarder mes differentes machines (7 machines).

Voici un premier compte-rendu de l'utilisation de la première version de cet outil dont je suis l'auteur:

En effet rsync ne permet pas de détecter les déplacements de fichiers et btrfs ne permet pas de dédupliquer à la volée les données.

Les fichiers ont donc été considérés comme étant nouveau.

La suppression de la snapshot a commencé à prendre énormément de temps, puis la machine est devenue inaccessible.

En me connectant en direct sur la machine (KVM), j'ai découvert que la suppression du dernier volume Btrfs remplissait la mémore. Les 8Go octets de mémoire ont été remplis. Et le noyaux linux a utilisé OOM Killer pour détruire tous les processus.

Bref la machine n'était plus dans un état lui permettant de faire les sauvegardes.

On parle déjà de problème avec btrfs et la suppression de snapshot (https://www.spinics.net/lists/linux-btrfs/msg52088.html). On trouve aussi pas mal d'article si les problèmes de btrfs quand il n'y a plus d'espace.

Cela me fait penser que btrfs ne me permettrait pas de gérer mes sauvegardes sur le long terme (tant sur le nombre de snapshots que cela allait créér que sur la déduplication).

Cela m'amène à la conclusion suivante, il faut que je repense la gestion du pool et de la déduplication. C'est d'ailleurs ce que font beaucoup de logiciel de sauvegarde (UrBackup proposer Btrfs et une version interne ; BackupPC gère son pool interne, Borg gère son pool interne ...)

Je vais donc repenser la manière dont je gère la déduplication dans l'application de sauvegarde. Si je réécris la manière dont est géré le stockage, je ne pourrais plus me baser sur rsync pour la sauvegarde. Il faudra donc que je développe mon propre outil pour générer la sauvegarde.

Par contre cela à l'avantage de ne plus être dépendant d'un système de fichier.

Le pool

Diviser pour réigner

Nous allons donc commencer par construire ce qui doit être le pool des données. Permettant de faire la déduplication.

Afin de faire de la déduplication, nous allons découper les fichiers en plusieurs morceaux. Cela permettra de faire des sauvegardes de gros fichiers dont seule une partie change:

Quelle est la bonne taille pour un morceau de fichier. Si on découpe le fichier de taille trop petite alors le découpage ne sert à rien. J'ai donc pris un échantillon de tous les fichiers que j'ai sur mes différentes machines pour déterminer la taille de cet échantillon.

find . -type f -print0 | \\
xargs -0 ls -l | \\
awk '{ n=int(log($5)/log(2)); if (n<10) { n=10; } size[n]++ } END { for (i in size) printf("%d %d\\n", 2^i, size[i]) }' | \\
sort -n | \\
awk 'function human(x) { x[1]/=1024; if (x[1]>=1024) { x[2]++; human(x) } } { a[1]=$1; a[2]=0; human(a); printf("%3d%s: %6d\\n", a[1],substr("kMGTEPYZ",a[2]+1,1),$2) }'

Voici le resultat de ce test d'échantillon.

File size Number Repartition
1k 29126558 37,36 %
2k 8649088 48,45 %
4k 7915884 58,60 %
8k 6394302 66,81 %
16k 4839627 73,01 %
32k 3606949 77,64 %
64k 3477900 82,10 %
128k 5158625 88,72 %
256k 3601985 93,34 %
512k 971108 94,58 %
1M 875574 95,71 %
2M 1698194 97,88 %
4M 1046430 99,23 %
8M 309027 99,62 %
16M 105271 99,76 %
32M 65211 99,84 %
64M 50832 99,91 %
128M 33947 99,95 %
256M 21338 99,98 %
512M 8066 99,99 %
> 1G 10068 100,00 %

La conclusion que l'on peut tirer de cela est que si on prend un chunk de 4Mo, alors 99% des fichiers ne seront pas découpés. Dans le lot rentrerons la plupart des fichiers textes, des photos, ... . Tous des fichiers qui s'ils ne sont pas des copies, sont normalement unique.

Dans une première version, je pense que cette taille ne sera pas paramétrable, mais il faudra la rendre dynamiquement paramétrable dans le futur (si le type des fichiers d'autres personnes a pour conséquence une répartition différente).

La table de hashage

Ces différents morceaux de fichiers (chunk) doivent ensuite pouvoir être identifiés facilement sans pour autant relire le contenu du fichier à chaque fois.

L'idée est d'utiliser une table de hashage où avec une clé on peut retrouver le contenu d'un morceau de fichier.

Il faut pouvoir, à partir de la clé:

Quelle clé peut-on utiliser ?

Après quelque recherches je vais partir sur un SHA-256. Quels sont les avantages et les inconvénients d'une telle clé ?

L'avantage est qu'il est possible, quand on connait le hash de faire le lien direct avec le morceau de fichier associé. La clé est facile à générer et le lien entre la clé et le chunk est facile à connaître.

Le plus gros inconvénient est le risque de collision. Le but d'une fonction de hash est de calculer un nombre "court" qui permet de representer un texte beaucoup plus long. Ce type de fonction de hashage est généralement utilisé pour:

Ce qui est le propre d'une fonction de hash est sa non réversibilité. En effet s'il était possible de retrouver facilement à partir d'un hash le texte contenu associé, les algo de compression n'utiliseraient que ca ;). Mais la plus grosse conséquence de tout cela est que deux textes (de contenus et de longueurs différentes) peuvent arriver au même hash.

Pour un logiciel de sauvegarde, cela pose alors un gros problème. Si parcequ'il possède le même hash qu'un autre fichier, on ne sauvegarde pas un document, la restauration ne sera pas faite à l'identique et cela engendrera de la perte de fichier.

Je me suis donc renseigné sur ce qui se faisait ailleurs.

Borg

Je trouve borg intéressant dans son fonctionnement, ses performances, ainsi que son stockage interne. Ce qui est dommage, c'est que dans mon cas, je n'ai pas une vue centralisée des machines dont j'organise la sauvegarde.

Dans la partie Internals on retrouve la structure interne du pool de Borg.

Borg utilise HashIndex, qui si j'ai bien compris calcule un hash sur un contenu dont la taille peut varier. Des utilisateurs se sont déjà posés la question du risque de collision.

La réponse faite par l'équipe de Borg a été de rejeter la demande. L'explication qui est faite est que la probabilité qu'une telle collision arrive est faible sur un hash de 256. Très faible.

UrBackup

Même chose pour UrBackup. Dans le manuel d'administration, partie 6.3, on retrouve l'information suivante:

UrBackup uses SHA512 to hash the files before file deduplication. In comparison ZFS uses SHA256 for block deduplication. The choice of SHA512 is safer. The Wikipedia page for “Birthday attack” has a probability table for SHA512. According to it one needs 1.6 _ 1068 different files (of same size) to reach a probability of 10-18 of a collision. It also states that 10-18 is the best case uncorrectable bit error rate of a typical hard disk. To have 1.6 _ 1068 different files of 1KB you need 1.4551915 * 1056 EB of hard disk space. So it is ridiculously more likely that the hard disk returns bad data or the data gets corrupted in RAM, rather than UrBackup linking the wrong files to each other.

Bref, on y explique sur la probabilité de collision pour un SHA512 est plus faible que celle utilisé pour la déduplication dans ZFS. On y explique également qu'elle est ridicule par rapport au risque de panne d'un disque dur.

BackupPC

BackupPC utilise un MD5 pour gérer son les clés de son pool. En cas de collision (ce qui est beaucoup plus probable avec un MD5 qu'avec un SHA-256) une extension est ajoutée à la fin du fichier.

Cela necessite alors de ré-envoyer le fichier sur le réseau pour comparer, mais permet de s'assurer qu'en cas de collision on ait une solution de repli.

Un MD5 fait 4 octets contrairement à un SHA-256 qui en fait 32.

Du coup, est-ce qu'avec un md5, j'ai beaucoup de collision sur mon instance BackupPC ? Pour un pool qui contient 3 464 397 fichiers, j'ai 0 collision.

> find . -type f | wc -l
3464397
> find . -type f | awk 'length($0) > 40' | wc -l
0

Ce qui est plutôt rassurant sur le risque de collision sur un SHA-256

Woodstock Backup

Pour mon propre logiciel, je vais partir sur un SHA-256. Je vais partir du principe qu'il n'y a pas de collision (et je ferais un test pour vérifier cela). Dans une version future il pourrait être intéressant d'ajouter une extension au fichier dans le cas où il y a une collision, et laisser la possibilité à l'utilisateur de demander à retransférer le fichier pour être sûr qu'il n'y a pas de collision.

Structure du pool

Maintenant que l'on connaît la taille des différents morceau de fichier ainsi que la clé qui nous servira à les classer. Nous allons maintenant voir comment les organiser dans notre système de fichier.

Derrière le stockage j'ai les idées suivantes:

Voici la structure que j'imagine utiliser pour le stockage des chunks.

 pool
   ├── aa
   │    ├── aa
   │    │    ├── aa
   │    │    │    ├── REFCNT
   │    │    │    │     ├── sha256 cnt
   │    │    │    │     ├── sha256 cnt
   │    │    │    │     └── sha256 cnt
   │    │    │    ├── LOCK
   │    │    │    │     └── host backupNumber
   │    │    │    └── aaaaaacdefghih-sha256.zlib

Pour les 3 premiers niveaux, nous allons avoir une structure de dossier qui est constituée des 3 premiers octets du SHA-256. Ce qui permet de réduire le nombre de fichiers par dossier, mais aussi de limiter le nombre de LOCK lors de la création du pool.

Ensuite dans chaque dossier, nous aurons un fichier de LOCK qui sera créé lors de l'ajout d'un nouveau morceau de fichier. Il sera également utilisé lors de la lecture.

Un fichier REFCNT sera utilisé pour compter le nombre de référence. Cela permettra de supprimer les morceaux quand ces derniers ne seront plus utilisés.

Enfin les morceaux de fichiers sont stockés dans des fichiers dont le nom contient le hash. Ces fichiers peuvent être compressés pour réduire l'espace utilisé.

Structure des fichiers de sauvegardes

Une fois les morceaux de fichiers déposés dans le pool, il nous faut un fichier permettant de référencer l'ensemble des fichiers qui composent la sauvegarde.

Il y aura un fichier par sauvegarde.

Ces fichiers de sauvegarde seront stockés dans les dossiers des différents serveurs sauvegardés. Ce fichier contient l'ensemble des fichiers d'une sauvegarde et pour chaque fichier, le hash de l'enssemble des morceaux de fichiers.

Ce fichier doit avoir un format lisible facilement et rapidement par un programme. Ce fichier sera dans un format binaire (pour que le fichier soit lisible rapidement et qu'il ne prenne pas trop de place).

Afin de simplifier la mise en place de ce fichier, nous allons utiliser protocol-buffers. Ce dernier permet d'avoir un format de fichier compatible quel que soit le language de l'application. Voici un premier jet de format de fichier qui sera utilisé pour stocker chaque fichier d'une sauvegarde.

message FileManifest {
  message FileManifestStat {
    int32 ownerId = 1;
    int32 groupId = 2;
    int64 size = 3;
    int64 lastRead = 4;
    int64 lastModified = 5;
    int64 created = 6;
    int32 mode = 7;
  }

  message FileManifestAcl {
    string user = 1;
    string group = 2;
    int32 mask = 3;
    int32 other = 4;
  }

  bytes path = 1;
  FileManifestStat stats = 2;
  map<string, bytes> xattr = 5;
  repeated FileManifestAcl acl = 6;
  repeated bytes chunks = 3;
  bytes sha256 = 4;
}

Le fichier sera constitué d'une liste de FileManifest. Ce fichier est de la forme :

int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest
int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest int32 FileManifest
(vous avez compris le principe)

où chaque int32 est la taille de chaque FileManifest.

Lors de la sauvegarde, le serveur repartira de la sauvegarde précédente et écrira toute modification dans un journal. Le journal indiquera, les fichiers ajoutés, supprimés, et modifiés. Une fois la sauvegarde terminée, le journal sera fusionné dans le fichier de sauvegarde (et le comptage de référence sera mis à jour).

Conclusion

Maintenant que j'ai une idée de la forme du nouveau de format de stockage, il ne me reste plus qu'à développer le pool de stockage. Si vous avez des retours à me faire sur le format de stockage alors n'hésitez pas à me contacter. Vous pouvez le faire par exemple sur https://github.com/phoenix741/woodstock-backup.

Gravatar de Ulrich Van Den Hekke
Original post of Ulrich Van Den Hekke.Votez pour ce billet sur Planet Libre.

Articles similaires

Mathias : Firefox : le chant du cygne

lundi 11 janvier 2021 à 09:36

Les statistiques d’utilisation de Firefox ne sont pas bonnes. Des choix contestables, des performances parfois juste acceptables et une stratégie pour le moins incompréhensible.

Mais une dernière partie de ses soutiens risque de quitter le navire. Ces utilisateurs utilisent Firefox pour améliorer le respect de la vie privée et disposer d’une certaine garantie concernant la neutralité du net.

Hors voilà que Firefox prône la censure. De quel droit un éditeur ou même un acteur privé se permet de censurer qui que ce soit. Le fait de bloquer une personne une organisation ne doit-être le fait que d’une décision de justice. J’ai perdu confiance dans Firefox. Adieu Firefox !

Cet article Firefox : le chant du cygne est apparu en premier sur Blog des télécoms - Par Mathias, expert télécom rédigé par Mathias.

Gravatar de Mathias
Original post of Mathias.Votez pour ce billet sur Planet Libre.

Journal du hacker : Liens intéressants Journal du hacker semaine #1

lundi 11 janvier 2021 à 00:01

Pour la 1ère semaine de l'année 2021, voici 10 liens intéressants que vous avez peut-être ratés, relayés par le Journal du hacker, votre source d’informations pour le Logiciel Libre francophone !

Pour ne plus rater aucun article de la communauté francophone, voici :

De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !

Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. Rejoignez-nous pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !

Et vous ? Qu’avez-vous pensé de ces articles ? N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)

Gravatar de Journal du hacker
Original post of Journal du hacker.Votez pour ce billet sur Planet Libre.

Articles similaires

Littlewing : Gérer « efficacement » les fichiers de configuration dans les charts HELM

samedi 9 janvier 2021 à 15:21

Dès qu’on veut déployer des environnements Kubernetes, Helm devient une des solutions à considérer.
Le déploiement des objets standards tels que deployment, autoscaler et autres se fait aisément car ces derniers ne changent pas d’un environnement à l’autre. Généralement on déploie la même infrastructure sur tous les environnements du développement à la production.

Bien évidemment on pourra limiter la taille des replicas sur l’environnement de développement par exemple mais au fond, le contenu des charts sera identique. Une des difficultés que l’on pourra rencontrer c’est dans la gestion des fichiers de configuration.

Je vais essayer d’exposer dans cet article comment j’ai réussi à gérer +/- efficacement (en tout cas pour moi) les fichiers de configuration dans les charts HELM.

Les config maps et secrets

Logiquement dans ce type d’architecture, les configmaps et secrets permettent le chargement des variables d’environnement et autres mots de passe. Cependant si vous utilisez certains frameworks qui nécessitent des fichiers de configuration, vous devrez charger les fichiers dans des volumes. Pour ces derniers, les volumes n’ont pas besoin d’être persistents.

Par exemple dans la configuration de votre deployment, vous pourrez configurer le montage d’un volume de la manière suivante:

  volumeMounts:
            - mountPath: /config
              name: configuration-volume
              readOnly: true
            - mountPath: /secrets
              name: secret-volume
              readOnly: true
      [...]
      volumes:
        - configMap:
            defaultMode: 420
            name: configuration
          name: configuration-volume
        - name: secret-volume
          secret:
            defaultMode: 420
            secretName: secrets

Pour intégrer un fichier binaire, on pourra le faire de la manière suivante dans le template HELM:

apiVersion: v1
# Definition of secrets
kind: Secret
[...]
type: Opaque
# Inclusion of binary configuration files
data:
  my_keystore.jks: {{ .Files.Get "secrets/my_keystore.jks" | b64enc }}

Vous pouvez définir les fichiers directement dans vos configmaps. Cependant, si vos fichiers sont volumineux, vous aurez du mal à les maintenir. Personnellement, j’opte pour mettre les fichiers de configuration à coté et les charger dans le configmap.

On pourra procéder de la manière suivante:

apiVersion: v1
kind: ConfigMap
[...]

data:
  my.conf:   {{- (.Files.Glob "conf/*").AsConfig | nindent 2 }} 

Livrables agnostiques

Une bonne pratique de développement logiciel est d’externaliser la configuration de vos environnements (ex. l’URL JDBC de la base de données) des livrables. Les charts HELM n’échappent à la règle.

On peut stocker la configuration de chaque environnement dans le chart, mais dans ce cas, on perdra beaucoup de souplesse lors des mises à jour des propriétés et cela nous imposera une nouvelle version.

On a plusieurs niveaux d’externalisation. Le premier est dans le chart. Vous pouvez externaliser les différentes valeurs dans le fichier values.yml. Ci dessous un exemple avec un autoscaler:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  labels:
  [...]
spec:
  maxReplicas: {{ .Values.myapp.maxReplicaCount }}
  minReplicas: {{ .Values.myapp.minReplicaCount }}
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
   [...]
  targetCPUUtilizationPercentage: {{ .Values.myapp.replicationThreesold }}

Les valeurs sont décrites comme suit:

myapp:
  minReplicaCount: "2"
  maxReplicaCount: "6"
  replicationThreesold: 80

Pour externaliser les valeurs d’environnement, vous pourrez donc externaliser un autre fichier values.yml qui sera appliqué au déploiement. Les valeurs de ce dernier surchargeront les valeurs définies dans le chart.
Il est important de noter également que les données présentes dans les fichiers de configuration (ex. fichier application.properties) peuvent être « variabilisées » et surchargées par le même mécanisme. Vous aurez à utiliser la commande tpl.

apiVersion: v1
kind: ConfigMap
metadata:
  name: configuration
  labels:
    [...]
data:
  application.properties: 
    |- 
    {{ tpl (.Files.Get "conf/application.properties") . | nindent 4}} 

Conclusion

Vous l’aurez compris, les charts HELM n’échappent pas aux règles déjà connues de gestion des environnements et des livrables. Même si il y a quelques subtilités à connaître pour intégrer des fichiers de configuration par exemple, les grands principes restent les mêmes.

Gravatar de Littlewing
Original post of Littlewing.Votez pour ce billet sur Planet Libre.

genma : Mon instance Peertube

vendredi 8 janvier 2021 à 09:00

Introduction

Suite à mon billet de blog de fin d'année 2020 Réflexion - une instance Peertube pour mes conférences et aux retours (en commentaire, sur les réseaux sociaux) que j'ai pu avoir, j'ai confirmé un projet que je murissais depuis quelques semaines (mois) : j'ai lancé mon instance Peertube !

Mise en place de l'instance Peertube

J'ai donc installé Peertube sur une instance Yunohost, sur un serveur qui me sert de demo/bac à sable. C'est pour moi l'occasion de tester le package Peertube et d'avoir une installation rapide et facilité. Rien à dire de particulier, installation simple et rapide.

Quelles vidéos ?

Au fil des années, j'ai donné de nombreuses conférences (plus d'une centaines) dans différents endroits (événements, salons, médiathèques) et j'en ai gardé une liste. Certaines de ces conférences ont été filmées - surtout celles des grands événements - et mises en lignes (la plupart sur Youtube, quelques unes sur Peertube). Je ne suis pas l'auteur de la vidéo mais je suis l'intervenant de la conférence et l'auteur du support de la conférence ; je pense que je suis donc en droit de récupérer et diffuser moi-même ces vidéos...

J'ai donc pris le temps de récupérer une à une ces vidéos et je les ai mise en ligne sur mon instance Peertube.

Il y a quelques vidéos inédites liées à mon projet AI2. J'ai écrit deux articles sur mon projet de vidéo et le retour suite à cette expérience Faire des vidéos sur Youtube ? Pas pour moi. En résumé, je n'étais pas satisfait du résultat (filmé en condition de direct, en une seule prise, sans montage post production derrière) et ça n'avait jamais été mis en ligne.

Je pense que je mettrai par la suite d'autres vidéos, mais pour l'instant, ce sont uniquement des vidéos de mes conférences.

Etat des lieux de l'instance : encore en beta

J'ai chargé les vidéos une à une sur mon instance, j'ai tagué un minimum avec les noms et fait des groupes par événement. Il me reste un certain nombre de choses à faire : ajouter des descriptions, les liens vers les supports des conférences... Il va falloir que je me plonge dans le paramétrage / partie administration de Peertube, pour comprendre comment bien faire les réglages. Du coup mon instance porte clairement la mention de beta pour préciser que ce n'est pas encore fini (la version de Peertube est la dernière version stable ; le beta c'est le fait que la peinture n'est pas finie et pas fraîche).

Et donc on peut voir ça où ?

Le lien est simple et facile https://peertube.genma.fr

Conclusion

Voilà, un projet / instance de plus pour le réseau fédérée de Peertube. Je ne reviens pas sur tout l'intérêt de faire ça ; mais comme ça je décentralise Internet à mon niveau et je continue de perpétuer l'esprit Framasoft (bises à l'ami Goofy si il lit ce mots). Je pourrais tester les fonctionnalités plus avancées de Peertube dans les prochaines semaines et mois. Mais surtout, je pérennise aussi les vidéos qui me sont liées : je les ai en ligne et j'ai un contrôle relatif sur leur mise à disposition ; je les ai aussi enfin sur un disque dur dans un coin chez moi.

Gravatar de genma
Original post of genma.Votez pour ce billet sur Planet Libre.

I'm richer than you! infinity loop