Conférence « Créer une base noSQL en une heure »

Comme je le disais dans mon billet précédent, j’ai donné samedi une conférence ayant pour thème la création d’une base de données par paires clé-valeur, dans le cadre de l’Open World Forum.

La conférence s’est très bien déroulée, et elle s’est poursuivie avec des discussions très intéressantes au sujet des bases de données, de la réplication et du clustering.

Voici les slides que j’ai présentés :

Vous pouvez retrouver l’intégralité du code source de ce serveur ultra-simplifié sur GitHub. Sans oublier le projet FineDB, qui a servi de source d’inspiration.

Lancement du projet FineDB

Je travaille depuis quelques semaines sur un projet de base de données noSQL, que j’ai nommé FineDB (après mon projet de système de fichiers redondé FineFS, je vous laisse trouver le dénominateur commun).

Plusieurs choses ont amené cette idée à germer dans mon esprit :

  • Comme vous le savez, j’aime le C. À force de ne faire quasiment que du PHP, ça me manquait de travailler sur un bon projet en C. Quelque chose d’assez pointu pour manipuler des concepts assez bas niveau (réseau, threads), et pour lequel les performances soient primordiales − pour justifier l’emploi du C.
  • Il existe plusieurs bibliothèques de fonction permettant de gérer des fichiers de données. La vénérable BerkeleyDB a trouvé des remplaçants de qualité avec LevelDB de Google et LightningDB du projet OpenLDAP.
  • Il existe quelques autres bibliothèques que j’avais envie d’utiliser, comme Snappy (compression ultra-rapide de Google), Nanomsg (communication réseau par le créateur de ZeroMQ), ou encore MessagePack (sérialisation binaire) et TinyCC (compilation à la volée).

À partir de là, les pièces du puzzle se sont assemblées rapidement.

FineDB, c’est quoi

FineDB est une base de données noSQL, utilisant des paires clé/valeur.

FineDB est codé en C et est multi-threads. Les threads communiquent entre eux grâce à Nanomsg. Le moteur de stockage utilise LightningDB. Les données sont compressées à la volée avec Snappy (elles peuvent l’être au niveau du client ou du serveur).

Pour le moment, les fonctionnalités sont très simples : PUT (ajouter ou mettre à jour une clé), GET (récupérer le contenu associé à une clé), DEL (effacer une clé ; en fait un cas particulier du PUT), LIST (lister les clés présentes dans la base).
Il est possible de ne pas spécifier de base, et les commandes concernent alors la base par défaut. Sinon, il est aussi possible de spécifier le nom de la base à laquelle la commande est associée.

La base est toujours dans un état cohérent. Grâce au moteur de stockage utilisé, il est impossible de récupérer des données « en cours d’écriture ».

Le protocole de communication client-serveur se veut le plus efficace possible. C’est un protocole binaire (à la différence des protocoles textuels comme le HTTP), très compact.

FineDB, ça sert à quoi

À la base, FineDB vise la même utilité que Redis, Cassandra, Dynamo, Riak, CouchDB, Couchbase, Project Voldemort, MongoDB et tant d’autres. C’est-à-dire d’offrir un moyen de stocker des données référencées à partir d’un identifiant unique, en étant le plus performant possible.
(oui, je sais que certaines bases que j’ai citées sont orientées document et pas seulement clé/valeur, mais le principe reste valable dans sa globalité)

J’ai fait quelques petits benchmarks, avec des cas d’utilisation réelles (j’ai repris des données que je stocke en production dans un serveur Redis). Comparé à Redis et Couchbase, FineDB est globalement 2 fois plus lent en écriture et 2 fois plus rapide en lecture.
Ces benchmarks m’ont donné envie d’aller plus loin. Être plus lent en écriture s’explique par une meilleure persistance des données, qui sont stockées sur disque et non pas en RAM comme le font les autres (même s’ils ont des stratégies configurables pour stocker les données sur disque au final). Par contre, le fait d’être deux fois plus rapide que Redis en lecture est en soi un exploit intéressant qui peut suffire à légitimer l’existence de FineDB.

Le projet n’en est encore qu’à ses balbutiements. Pour le moment, je me suis attaché à prouver son potentiel. Si mes tests avaient montré des performances désastreuses par rapport aux systèmes déjà existants sur le marché, je ne serais pas allé plus loin.
Maintenant que je sais qu’il y a un intérêt à pousser les choses, j’ai pas mal d’idées à mettre en œuvre, notamment en ce qui concerne les questions de réplication, de redondance et de répartition. L’idée serait d’avoir un système de base de données noSQL qui puisse servir aussi bien sur un petit serveur isolé que pour mettre en place un cluster avec un grand nombre de machines.

Si je schématise, on utilise Redis sur un seul serveur, qu’on va parfois répliquer (en maître-esclave). Par contre, les clusters Redis sont encore instables et fonctionnellement dégradés. À côté de ça, on ne met en place du Hadoop que sur des infrastructures imposantes ; personne n’imagine installer un serveur Hadoop autonome, en dehors d’un cluster servant à du big data.
J’avoue m’intéresser de près à Couchbase, qui fait beaucoup d’efforts pour réunir le meilleur des deux mondes ; il est installable sur un serveur seul, mais il permet aussi de constituer des clusters facilement (avec une interface web absolument bluffante). Mais certains choix de design me feraient réfléchir par deux fois avant de l’utiliser sur mes applications professionnelles, j’imagine ne pas être le seul dans ce cas. Sans oublier que Couchbase n’est pas sous licence libre (même leur « Community Edition »), ce qui me gêne quand même un peu.

Les contraintes

Certaines contraintes de fonctionnement sont imposées par mes choix de design et par ceux des bibliothèques que j’utilise.

Les clés peuvent être longues de 64 KO au maximum.
Les données peuvent faire 4 GO au maximum.
(par comparaison, FoundationDB limite les clés à 10 KO et les données à 100 KO ; sur Amazon DynamoDB, clés et données sont limitées à 64 KO ; dans Couchbase, les clés sont limitées à 250 octets et les données à 20 MO)

Le nom des bases de données est limité à 255 caractères.

La taille des bases de données n’est limitée que par l’espace d’adressage virtuel. Concrètement, ça veut dire que c’est l’espace disque qui détermine la limite, et non pas la RAM disponible. LMDB se débrouille pour mapper les données en RAM pour accélérer leur accès (merci mmap). Par contre, il faut déclarer la taille maximal autorisée ; elle est de 10 MO par défaut (ce qui ne veut pas dire pour autant qu’un fichier de 10 MO est créé dès le départ).

Je ne pense pas que FineDB puisse être porté sous Windows ; trop d’appels POSIX sont employés (peut-être que ça pourrait marcher avec Cygwin mais j’en doute). Pour Mac OS X, ça devrait être possible, mais personnellement je n’ai que du Linux…

Le futur

FineDB évolue très vite en ce moment. J’ai revu certains aspects plusieurs fois, et cela va continuer un bon moment avant de se stabiliser. Je pense que le protocole va encore être modifié en profondeur une ou deux fois avant de prendre sa forme définitive.

Quand l’aspect mono-serveur sera pleinement opérationnel, je vais m’attaquer à la réplication maître-esclave. Une fois qu’elle sera en place, je passerai à la réplication maître-maître.
Si j’arrive à concrétiser les idées que j’ai en tête, je devrais pouvoir proposer quelque chose qui soit relativement simple à mettre en place et à administrer, mais aussi à coder.
Cela servira ensuite de support à un système de cluster, mais on verra ça en temps et heure.

Je réfléchis encore à la possibilité de faire évoluer FineDB vers un système orienté documents. Je me tâte encore beaucoup sur cette question, car cela pourrait faire chuter les performances. D’un autre côté, cet aspect pourrait être optionnel.

Je réfléchis aussi à un moyen d’ajouter des fonctionnalités au cœur du serveur. C’est quelque chose de complexe, mais TinyCC est tellement sexy (j’en ai déjà parlé l’an dernier) que je pourrais l’utiliser pour faire un système de plugins.

Où ça se passe ?

Comme pour mes autres projet, vous pouvez trouver les sources de FineDB sur GitHub : http://github.com/Amaury/FineDB

Comme je l’ai dit plus haut, le projet est encore en phase expérimentale. Je ne cherche pas spécialement de contributeurs, mais n’hésitez pas à me faire part de vos idées.

Conférences au PHP Tour les 29 et 30 novembre à Nantes

Le PHP Tour est la deuxième grosse manifestation nationale organisée par l’AFUP chaque année. Contrairement au Forum PHP, qui se tient à Paris, le PHP Tour change de lieu chaque année ; c’était à Lille l’an passé, c’est à Nantes cette année.

Je vais y participer en donnant 2 conférences :

  • Une sur l’hybridation de bases de données, le jeudi 29 novembre à 14h45. J’y expliquerai pourquoi et comment nous utilisons conjointement des bases de données SQL et noSQL dans mon entreprise.
  • Une lightning talk sur le projet FineFS, le vendredi 30 novembre à 15h45.

Si vous suivez bien mon blog, vous savez que j’ai déjà présenté ce lightning talk à l’Open World Forum, et qu’une vidéo est disponible.
Par contre, ce sera la première fois que je présenterai la conférence sur l’hybridation de bases ; j’espère que je rendrais le sujet intéressant.

Venez nombreux, il reste encore quelques places disponibles. Pour rappel, l’accès au PHP Tour coûte 130 € pour une journée, 200 € pour les deux jours (130 € si vous êtes membres de l’AFUP, étudiant ou demandeur d’emploi). En plus, Nantes est une ville sympa  🙂