Git, MariaDB and Python3

Post at — Sep 01, 2015

Pour un projet perso top secret, je me suis retrouvé dans une situation où je souhaitais être capable de :

  • stocker un grand nombre de petits dépôts Git
  • les avoir en haute-disponibilité (99.9% d’uptime)
  • encaisser une forte charge en lecture sur ces dépôts
  • être capable de monter en charge verticalement mais aussi horizontalement rapidement si besoin est
  • toujours avoir un contenu apparent cohérent : Quand on fait un push sur une des machines du cluster et qu’on enchaîne sur un pull depuis une autre, il faut que le contenu du push soit systématiquement apparent
  • accéder et manipuler ces dépôts depuis un programme en Python 3.

Autrement dit, il me fallait essentiellement un moyen de répliquer des dépôts Git sur plusieurs machines efficacement.

Je n’ai rien trouvé qui semble répondre à ce cahier des charges. Donc j’ai regardé si je ne pouvais pas assembler des briques logiciels déjà existantes pour obtenir ce résultat. Les briques suivantes ont attirées mon attention:

À partir de là, après presque 1 mois et demi de travail, ça a donné ça:

Et ça fonctionne ! :D

Malheureusement je l’ai fait un peu vite, et du coup ce n’est pas intégrable upstream en l’état :

  • L’historique Git est dégueu (je pensais d’abord tout faire dans Pygit2)
  • J’ai fait des modifications dans Libgit2 pour réutiliser une grosse partie du code de src/transport/local.c. Pour l’instant, ça ne peut pas être fait en dehors de la librairie Libgit2.
  • Les dev Libgit2 préfèrent que le code pour d’autres backend que le FS reste en dehors de la libgit2 officielle.

Concernant les performances, sans surprise, je constate une dégradation assez importante : À la louche, c’est généralement 2 à 3 fois plus lent que le FS en brut pour des dépôts de petite taille. C’est surtout beaucoup plus lent pour les gros dépôts Git. Je suis entrain de tester avec le dépôt de Linux. Je pense qu’un peu de tuning MariaDB et de mes changements permettront d’améliorer (.. sans faire de miracle non plus). Il est aussi intéressant de noter que, avec mon implémentation actuelle, les dépôts Git prennent beaucoup plus d’espace disque dans MariaDB que dans un dépôt Git classique. La raison est simple : Git “pack” les commits ensemble en utilisant un algorithme de compression delta. Sans surprise, cet algorithme est très efficace avec les fichiers textes qui changent progressivement. Mais il n’est pas supporté par mon implémentation (ça compliquerait … tout). Pour le dépôt Git du noyau Linux, on passe ainsi d’un dépôt de 1.1Go à .. >= 30Go (sans parler du temps d’insertion dans la BDD qui est en conséquence).

Plus qu’à faire quelques statistiques pour estimer les performances de cette solution.