CouchDB, une base de données mobile friendly

Depuis plusieurs mois, nous utilisons couchDB dans le cadre du développement des solutions Octopod. Proposant un fonctionnement assez atypique, cette base de données est aussi brillante que déconcertante à l'utilisation. Petit feedback sur sa mise en place en production.

Introduction : CouchDB, couchbase et cloudant

CouchDB est une solution de base de données moderne créée en 2005. La solution écrite en Erlang est distribuée sous Licence Apache depuis 2008. CouchDB a été ensuite forkée en 2012 par son créateur Damien Kratz pour devenir "Couchbase". Cette nouvelle version est le fruit de l'association avec un autre projet : Membase.

Le projet d'origine a été repris par la communauté qui a sorti une nouvelle version majeure (2.0) fin 2016. Cette dernière a implémenté le support de BigCouch (la technologie de clustering développée par cloudant, la solution couchDB SaaS d'IBM) ainsi que les Mango queries (langage de requête).

CouchDB

CouchDB et Couchbase sont à l'utilisation, des solutions proches comme peuvent l'être MySQL et MariaDB. Dans le détail, sachez que les plus grandes différences sont la gestion du cache (non présent dans couchdb) et le système de requête (proche du SQL pour couchbase et de MongoDB pour couchDB).

Pour finir, couchbase est aussi et surtout une solution développée par la société du même nom qui propose un écosystème sous licence Apache mais maintenu principalement par elle même. Ainsi l'orientation des développements est moins libre et ouverte.

Aujourd'hui, CouchDB reste une technologie sous utilisée (33ème au classement mondial(1)) sur le marché des bases de données avec toutefois, une réelle communauté de développeurs qui soutiennent et participent au projet.

CouchDB : à quoi ça sert ?

Les deux caractéristiques fortes sont le stockage sous forme de documents JSON et une utilisation par un API HTTP (interface REST). Il s'agit d'une base de données NoSQL (non relationnelle) et conçue dès le départ pour l'exploitation web. Sa promesse est d'être interopérable et agnostique à un quelconque langage client.

La philosophie de CouchDB est résumée dans son slogan : time to relax. Ici, tout se veut simple : l'installation, l'utilisation et le déploiement.

Le pari est réussi, la mise en place est facile. Par exemple, la mise en place d'un cluster se fait rapidement et sans paramétrages lourds. En revanche, au delà de l'initialisation et pour exploiter pleinement sa capacité, les choses se compliquent.

Tout d'abord, couchDB est schema-less, ce qui offre une flexibilité incroyable dans les manipulations et l'évolutivité de votre modèle. En contrepartie, c'est à la partie applicative d'assurer la cohérence et l'homogénéité de vos données. La structure est créée par les données.

Pouch Couch !

Un autre point intéressant réside dans son couplage avec PouchDB. En effet, avec cette dernière solution, vous aurez la possibilité de synchroniser automatiquement une/des base(s) de donnée(s) locale(s) (dans une appli mobile par exemple) avec une base de données couchDB.

Votre application locale exploite ainsi ses données d'une manière autonome tout en gardant la possibilité de se synchroniser automatiquement avec votre environnement distant centralisé. Un vrai mode online/offline natif !

Sans s'étendre sur le sujet, sachez que PouchDB est conçu autour du même API que CouchDB, ce qui simplifie forcément sa prise en main.

Attention toutefois, certaines routes ne sont pas implémentées (la purge par exemple).

Pour l'utiliser dans un système décentralisé (couplé avec pouchDB), vous pourrez exploiter la fonctionnalité "database_per_user". Grâce à cette option, une base de données est créée par utilisateur pour cloisonner les droits d'accès et ainsi la lecture/écriture des données. En pratique, à la création d'un utilisateur, une base de données sera créée automatiquement et accessible uniquement par cet utilisateur depuis son application.

Autre particularité, notons la gestion de l'écriture qui n'utilise pas de lock mais une solution de versioning MVCC(2) (même à la suppression). La base de données garde ainsi une trace des modifications faites sur les documents et lui permet de gérer les conflits de réplication. Ce mécanisme de révision est nécessaire au fonctionnement du cluster mais aussi des bases de données pouchDB déportées.

La structure d'un document comprend obligatoirement ces champs :

  • _id : l'identifiant unique du document. Vous devez aussi savoir que ces clés sont créées automatiquement. Il n'est donc pas recommandé de forcer ces valeurs.
  • _rev: le numéro de révision du document, géré automatiquement par le moteur CouchDB ;

En fonction des cas, d'autres champs seront obligatoires. Pour la base de donneés _users avec les champs (roles, derived_key, salt...).

Les requêtes avec couchDB

La récupération des données dans couchDB passe par son API.

Depuis la route (/find/)[http://docs.couchdb.org/en/2.2.0/api/database/find.html], vous allez conditionner votre recherche grâce à des opérateurs de combinaison ($and,$or,$not,$nor,$elemMatch) ou des opérateurs de condition ($eq, $lte, $ne, $in...).

Vous aurez aussi les instructions nécessaires à la gestion d'une pagination de résultats (limit/skip), les trier ou restreindre les champs récupérer dans vos résultats.

Une requête simple ressemblera donc à (tous les champs pour les années supérieur à 2018 ) :

{
    "year": {
        "$gt": 2018
    }
}

Étant basé sur du noSQL, couchDB ne sait pas gérer des jointures. Vos données sont stockées à plat sans possibilités de les associer entre elles. Prenez le en compte lors de la conception. Vous devez prévoir comment vos données seront exploitées (recherches poussées ou des croisements de données).

C'est un fait, vous n'aurez pas beaucoup de flexibilité dans son système de requête. Il est essentiel taillé pour réaliser des recherches simples sur des données volumineuses (comparable à un data lake). Selon la situation, prévoyez une consolidation de vos données en amont pour vous permettre ouvrir les possibilités de recherche.

Les requêtes find ont des comportements par défaut qu'il faut connaître. Parmi ceux la, il y a la limitation à 25 résultats et les attachements qui ne sont pas remontés. Regardez donc bien la documentation pour ne pas vous faire piéger !

Vues, index et map reduce

Comme nous le disions dans la partie précédente, il y a une certaine rigidité à réaliser certaines requêtes. Par exemple, trier des résultats n'est possible que par la création d'un index.

{
    "index": {
        "fields": ["foo"]
    },
    "name" : "foo-index",
    "type" : "json"
}

Le système de vue est au cœur de couchDB. Il permet de retrouver des données préfiltrées avec un ordre défini et d'une manière très rapide.

Malgré cela, la fonctionnalité mapReduce écrite en JavaScript permet le traitement rapide d'un grand volume de données par segmentation des tâches de calcul (MapReduce).

La fonction map va subdiviser les traitements pour une exécution segmentée puis la fonction reduce va reconsolider les résultats. Dans le détail, l'opération map itère sur tous les documents de la base, et permet d'y appliquer un algorithme, puis d'exporter la réponse sous forme de valeurs associées à des clés. L'opération reduce permet d'itérer sur les ensembles clés-valeurs créées par l'opération map, pour en ressortir une valeur unique (par exemple des sommes, des moyennes).

Map Reduce CouchDB

Si cet exemple vous parait trop théorique, continuons donc avec un exemple simple :

Dans cette fonction map, on décide pour les documents du type "player" de renvoyer uniquement les valeurs createdAt et name

function(doc) {
  if (doc.type == "player") {
    emit([doc.createdAt, doc.name], doc);
  }
}

Puis dans le reduce on réalise une somme des résultats :

function(keys, values) {
  return sum(values);
}

Certaines fonctions reduce sont natives à couchDB tel que _sum, _count et _stats

Je vous ai dit précédemment que couchDB ne permettait pas de jointure. Il y a une petite subtilité à cela avec la possibilité de joindre des données sur un niveau via cette méthode : https://docs.couchdb.org/en/stable/ddocs/views/joins.html. Une technique toutefois très limitée.

CouchDB, faut pas se tromper.

CouchDB est une base de données assez singulière qui demande du temps pour comprendre ces mécanismes. Pour obtenir, par exemple, des performances satisfaisantes, vous devrez passer par les indexes et les vues. Idem au niveau de la taille de stockage qui devient rapidement importante et demande quelques réglages.

En effet, la base garde, par défaut, 1000 révisions par entrée et donc prend nécessairement plus de place que les données réelles. Il vous est donc possible de baisser ce seuil du nombre de révisions via la configuration setLimit. Attention toutefois car ce paramètre est sensible et peut avoir des conséquences directes sur le bon fonctionnement de vos réplications.

Sur le même thème, pensez aussi à bien paramétrer la compaction qui va vous permettre de compresser et d'éliminer les données obsolètes.

En résumé, nous avons listé les avantages et les défauts de couchDB selon notre utilisation.

Les avantages :

  • La synchronisation ;
  • la flexibilité ;
  • le mode database par utilisateur ;
  • réplication et cluster simple à mettre en place.

Les défauts :

  • Documentation un peu expéditive ;
  • Configuration moitié fichier et moitié par API par évidente pour du provisionning automatique ;
  • Une base de données qui prend de la place disque ;
  • Un système de requête trop léger.

Le slogan de couchDB ne ment pas (time to relax). Oui, on est détendu voir très détendu au niveau de la sécurité. Par défaut, l'API est ouvert à tous les vents et les bases de données facilement accessibles. Prenez donc le temps de bien vérifier les permissions et le type d’authentification.

La dernière couche !

CouchDB est une base de données spécifique qui ne propose pas la même polyvalence qu'un mongoDB par exemple. Sa propension à simplifier la synchronisation avec des bases de données locales, à stocker facilement des fichiers et son couplage avec pouchDB la rend efficace pour la création d'app mobile ou de systèmes d'applications distribuées.

Elle est puissante et capable de stocker une grosse volumétrie de données.

Côté administration, son déploiement reste délicat mais les roadmapd des prochaines features va dans le bon sens sur ce point.

Finalement, nous pouvons vous conseiller cette base de données dans le cadre d'une application client-serveur avec une contrainte d'offline. N'oubliez pas que sa simplicité apparente cache des techniques plus complexes nécessaires au bon fonctionnement en production.

Pour vous lancer, je vous invite à consulter la documentation Française. Bonne découverte !

(1) https://db-engines.com/en/ranking (2) https://fr.wikipedia.org/wiki/Multiversion_Concurrency_Control

Tags de
l'article

Performance

Catégories de l'article

Développement

Commentaires

Il n'y a actuellement aucun commentaire. Soyez le premier !

Articles liés