• # Petites précisions

    Posté par (site web personnel) . En réponse au journal Camlistore, système de stockage universel, opensource et protégeant de la vie privée?. Évalué à 10.

    Merci pour le journal. J'avais moi-même jeté un oeil là-dessus il y a peu et j'aimerais apporter de petites précisions sur son fonctionnement interne pour démystifier un peu la chose :

    Dans camlistore, tout est blob. Un blob est une suite d'octets. Lorsqu'on la rentre dans camlistore, celui-ci va nous sortir le hash SHA1 du blob et identifier ce blob avec ce hash; ce sera son identité (et elle a le bon goût d'être stable, puisqu'elle dépend uniquement du contenu de la suite d'octets).

    Seulement voilà, une suite d'octets c'est bien gentil mais pas très flexible. Par exemple, je sais pas si c'est un fichier texte ou un fichier image... Pour résoudre ça, je vais donc ajouter un autre blob, qui sera une structure spécifiant tous les attributs de ma suite d'octets :

    • type: c'est un fichier
    • objet en question: le hash du contenu pur
    • taille: 1234 kO
    • utilisateur UNIX: rakoo
    • groupe UNIX: users
    • et d'autres paramètres selon l'envie

    Cette structure est à mettre au format JSON et à stocker dans camlistore, qui va nous ressortir... un hash SHA1. Et oui, cette structure sérialisée est en soi un blob, donc je la stocke en tant que blob dans camlistore ! Et si je veux accéder au contenu, je vais voir dans le champ "objet en question", j'y lis le hash du contenu et je vais lire ce contenu !

    Et on peut monter comme ça au dessus, en décrivant un dossier comme un ensemble de fichiers avec quelques attributs, et cet ensemble de fichiers sera décrit comme une liste de fichiers, et chacun de ces fichiers sera décrit comme précédemment...

    Maintenant, ça marche bien pour des fichiers immutables, mais comment on fait pour des fichiers que l'on souhaite modifier ? "Simple": on va créer un permanode, un noeud totalement au hasard, qui aura donc un hash SHA1 totalement au hasard, disons "hash-permanode". On va ensuite créer une autre structure JSON avec comme attributs:

    • type: modification
    • lié au permanode: hash du permanode
    • modification: ajout du tag "demo"

    et je vais stocker ça dans camlistore qui va là encore me donner un hash, disons "hash-ajout-tag". Ce hash représente ainsi un objet mutable auquel j'ai ajouté un tag et celui-là uniquement. Je peux ensuite apporter une modification, et dire que je veux que cet objet ait comme contenu le fichier précédemment entré dans camlistore. Je vais alors avoir un nouveau hash, disons "hash-ajout-contenu", qui représentera mon fichier avec le tag "demo" et avec un pointeur vers le contenu du fichier. On voit donc qu'on a tout naturellement un système de versionnement qui vient se mettre en place: j'ai 2 versions d'un objet unique qu'on peut appeler "hash-permanode", la première étant "hash-ajout-tag" et la deuxième étant "hash-ajout-contenu" ! Et si je veux accéder à la dernière version de l'objet, je vais directement demander "hash-permanode", qui est en fait une indirection vers l'ensemble des modifications mergées jusqu'à la dernière version !

    L'approche tout-hash n'est pas nouvelle, et le système le plus connu qui fait ça est certainement git. git utilise un système beaucoup plus basique, puisque les types d'objets sont fixés (contrairement à camlistore où c'est totalement dynamique), il n'y en a que 4, et chacun est très simple... mais le principe est exactement le même : un fichier est hashé et son contenu brut stocké, la liste des fichiers avec le nom et les droits UNIX et un pointeur vers leur contenu brut est hashé et son contenu stocké, et un commit avec les informations importantes et un pointeur vers la liste des fichiers est hashé et son contenu stocké. Tout pareil.

    Maintenant qu'on a posé les bases, on peut s'amuser à faire tout plein de choses :

    • toutes les données sont auto-vérifiées, puisque leur identifiant est leur hash SHA1.
    • on l'a vu, par construction l'historique complet depuis la création du fichier est là. En fait, ça crée un autre problème : comment vider les anciennes versions pour faire de la place.
    • la synchronisation est "triviale" : il "suffit" d'envoyer les hash qui ne sont pas présent de l'autre côté.
    • le partage avec un autre utilisateur est trivial : il suffit d'envoyer le hash de la donnée, l'autre peut prendre la donnée d'où elle veut (avec le bonus qu'elle est auto-vérifiée): mon serveur de stockage, son serveur de stockage, un serveur de stockage tiers qui fournirait ce service, peu importe...

    Camlistore c'est aussi plein de bonnes idées :

    • C'est du HTTP+JSON. On n'est certes que lundi, mais le HTTP et le JSON sont compréhensibles par à peu près tous les langages existants.
    • La gestion des données du point de vue utilisateur se fait via un moteur de recherche (venant de gens de Google, rien d'étonnant là-dedans): celui-ci va indexer par exemple tous les objets JSOn qui ont un attribut "tag", et qui ont "fichier" comme "type", pour que l'utilisateur puisse chercher ses fichiers avec un certain tag. On retrouve là l'un des concepts de CouchDB, à savoir que tout est JSON et que les données se trouvent à posteriori via des requêtes bien placées, mais en étant un peu plus générique.
    • Certains blobs peuvent être gros, et ça peut être sous-efficace de tout stocker d'un coup. Du coup ils ont implémenté le protocole de split de bup. Pour résumer, le principe est d'avoir une somme de contrôle spéciale dans laquelle on met tous les octets un par un et on regarde le résultat après chaque octet. Dès que le résultat a une forme spéciale (aujourd'hui, lorsque les 13 derniers bits sont à 1), on dit qu'on a atteint un octet frontière, et on casse le fichier entre l'octet frontière précédent et celui-ci. On a comme ça un découpage du fichier en blocs de taille variable qu'on va stocker dans camlistore en lieu et place du fichier complet, en général assez faible (quelques centaines de kO tout au plus), mais au moins si le fichier change peu, il n'y a pas besoin de stocker tout le nouveau fichier, juste les nouveaux blocs. On en avait déja parlé ici.
    • Il y a une gestion des droits pour le partage avec d'autres utilisateurs, et d'identités. Plutôt que de réinventer la roue, les auteurs ont décidé d'utiliser PGP.
    • Un seul et unique binaire pour le serveur. Yapasplusimple.