Elasticsearch, une base de données NoSQL

MISE À JOUR : cet article fait référence à notre offre Elasticsearch hébergée par son ancien nom, à savoir Found. Il est à noter que Found est désormais connu sous le nom d'Elastic Cloud. Des essais gratuits de 14 jours de l'offre Elasticsearch hébergée sont disponibles sur Elastic Cloud.

Elasticsearch peut-elle être utilisée en tant que base de données NoSQL ? NoSQL a plusieurs significations selon les contextes. Fait intéressant, ce terme n'a pas grand-chose à voir avec SQL. Commençons par répondre "Peut-être !" à cette question. Ensuite, étudions les diverses propriétés d'Elasticsearch et celles qui ont été sacrifiées afin de devenir l'un des moteurs d'analyse et de recherche les plus flexibles, scalables et performants à ce jour.

Au fait, qu'est-ce qu'une base de données NoSQL ?

Dans l'expression base de données NoSQL, le mot NoSQL désigne des bases de données de nouvelle génération qui sont dotées pour la plupart de certaines des caractéristiques suivantes, à savoir être non relationnelles, distribuées, open source et à scalabilité horizontale. En d'autres termes, cette définition n'est pas très précise.

Plus spécifiquement, elle ne concerne pas SQL. Par exemple, le langage de requête de Hive s'inspire clairement de SQL. C'est également le cas du langage de requête d'Esper, qui fonctionne sur des flux au lieu des relations. En outre, saviez-vous que PostgreSQL s'appelait "Postgres" et que "Quel" était son langage de requête à l'époque ? Même s'il s'agit avant tout d'un système de gestion de base de données relationnel-objet, il est désormais doté de nombreuses fonctionnalités conçues pour en faire un système de stockage de documents sans schéma.

Il ne s'agit pas non plus des propriétés ACID. Hyperdex est un exemple de base de données NoSQL qui vise à fournir des transactions ACID. MySQL, sûrement une base de données SQL, a connu des interprétations douteuses de la signification exacte d'ACID.

S'agit-il d'une base de données relationnelle ? La plupart des bases de données NoSQL ne prennent pas en charge la mise en relation de la même manière que les bases de données relationnelles traditionnelles et laissent cette tâche aux internautes. Toutefois, ce n'est pas le cas de toutes. RethinkDB, Hive et Pig en sont quelques exemples. Neo4j, une base de données orientée vers les graphes, gère les relations (c'est-à-dire les liaisons) en les parcourant d'une manière remarquable dans les graphes. Elasticsearch est dotée d'un concept de "moment de la requête" associé à des relations parent-enfant et de "moment de l'indexation" associé à des types imbriqués.

S'agit-il d'une base de données distribuée ? Il existe des bases de données SQL et quelques projets visant à devenir NoSQLite. Or, les bases de données de génération plus récente tendent à être distribuées d'une manière ou d'une autre.

Pour résumer, il est illogique de définir précisément NoSQL ou d'affirmer tout simplement qu'Elasticsearch est une base de données NoSQL de stockage de documents. Au moment de la rédaction de cet article, le site nosql-database.org en répertorie plus de 20.

Dans les prochaines sections, nous allons passer en revue quelques propriétés importantes et découvrir comment Elasticsearch les implémente ou non.

Aucune transaction

Lucene, la base sur laquelle Elasticsearch se fonde, comprend un concept de transactions. En revanche, Elasticsearch n'est pas dotée de transactions au sens classique du terme. Il n'existe aucune méthode pour récupérer un document envoyé. En outre, vous ne pouvez pas envoyer plusieurs documents, puis les indexer tous ou aucun. Cependant, la solution configure un journal de transactions WAL (write-ahead-log) afin de garantir la longévité des opérations sans devoir réaliser une coûteuse validation Lucene. Vous pouvez également préciser le niveau de cohérence des opérations d'index, concernant le nombre de répliques devant reconnaître l'opération avant le renvoi du résultat. Par défaut, il s'agit d'un quorum, c'est-à-dire \(\lfloor\frac{n}{2}\rfloor + 1\).

La visibilité des modifications est contrôlée lors de chaque actualisation d'un index (qui a lieu une fois par seconde par défaut) sur chaque partition individuellement.

La version des documents envoyés est précisée en vue de contrôler la simultanéité optimiste.

Elasticsearch est une solution conçue pour être rapide. La mise en place des transactions distribuées est une tâche très lourde. Il est donc plus facile de ne pas en fournir. En acceptant que les informations lues puissent être relativement obsolètes et que l'ensemble des internautes ait accès à la même chronologie, Elasticsearch peut fournir de nombreux services à partir des caches, un élément fondamental pour garantir les époustouflantes performances que nous adorons.

Flexibilité des schémas

Elasticsearch ne vous oblige pas à spécifier en amont un schéma. Soumettez un document JSON. La solution va effectuer une estimation éclairée afin d'en déduire le type. Ce processus est efficace avec des éléments comme les données numériques, les caractères booléens et les horodatages. Pour les chaînes, la solution utilise un analyseur "standard", ce qui est un bon point de départ, en règle générale.

Cette solution est sans doute indépendante des schémas, car il n'y a aucune obligation d'indiquer un schéma. Au contraire, nous la considérons comme une solution flexible par rapport aux schémas. Pour développer de formidables recherches ou analyses, vous devez vraiment affiner vos schémas. Elasticsearch est dotée d'un vaste éventail d'outils performants et utiles, comme les modèles dynamiques et les objets à champs multiples. Ils sont décrits plus en détail dans notre article consacré au mapping.

Relations et contraintes

Elasticsearch est une base de données axée sur les documents. L'ensemble du graphe d'objet dans lequel vous souhaitez mener vos recherches doit être indexé. Par conséquent, avant d'indexer vos documents, ils doivent être dénormalisés. La dénormalisation augmente la performance de récupération (comme aucune association de requête n'est requise), utilise davantage d'espace (les objets devant être stockés plusieurs fois), mais rend la cohérence et l'actualisation plus difficiles (étant donné que toute modification doit être appliquée à toutes les instances). Toutefois, cette procédure est excellente pour les charges de travail qui sont écrites une seule fois, mais lues de nombreuses fois.

Imaginons que vous deviez configurer une base de données comprenant des informations sur la clientèle, les commandes et les produits, et que vous souhaitiez mener des recherches dans les commandes à partir du nom d'un produit et d'une personne. Pour y parvenir, vous pouvez indexer les commandes à l'aide de toutes les informations requises sur cette personne et les produits. La recherche en est ainsi facilitée. Cependant, que se passe-t-il lorsque vous voulez modifier le nom du produit ? Dans une conception relationnelle avec une normalisation appropriée, il vous suffit d'actualiser le produit. C'est une force de ce modèle. Dans une base de données de documents dénormalisés, il faudra actualiser chaque commande liée au produit concerné.

En d'autres termes, avec les bases de données orientées vers les documents comme Elasticsearch, nous concevons nos mappings et stockons nos documents afin qu'ils soient optimisés pour la recherche et la récupération.

Comme expliqué dans l'introduction de cet article, Elasticsearch est dotée d'un concept de "moment de la requête" associé à des relations parent-enfant et de "moment de l'indexation" associé à des types imbriqués. Nous aborderons probablement ce sujet plus en détail dans un prochain article. Entre-temps, nous vous recommandons de regarder la présentation de Martijn van Groningen intitulée "Document relations with Elasticsearch" (Relations entre les documents avec Elasticsearch).

La plupart des bases de données relationnelles vous permettent également de préciser des contraintes en vue de définir les cohérences et les incohérences. Par exemple, il est possible d'appliquer une unicité et une intégrité référentielles. Vous pouvez exiger que la somme des mouvements du compte soit positive et ainsi de suite. Les bases de données orientées vers les documents ont tendance à proposer ces options. Elasticsearch ne fait pas exception à la règle.

Solidité

Une base de données doit être solide, en particulier s'il s'agit de votre système officiel de dossiers. Dans l'idéal, une requête coûteuse devrait pouvoir être annulée et il n'est pas du tout dans votre intérêt que la base de données ne fonctionne plus, sauf lorsque vous le souhaitez.

Malheureusement, Elasticsearch (et ses composants) ne gère actuellement pas très bien les erreurs OutOfMemory. Nous abordons ce sujet plus en détail sur la page consacrée à la mise en production d'Elasticsearch et les pannes dues à une mémoire insuffisante. Il est très important qu'Elasticsearch soit dotée d'une mémoire suffisante. Il est aussi essentiel de faire preuve de prudence avant l'exécution dans un cluster de production de recherches dont les exigences en matière de mémoire sont inconnues.

La situation est susceptible de s'améliorer à mesure qu'Elasticsearch gagne en maturité. Cependant, il faut se rappeler qu'Elasticsearch est une solution conçue pour être rapide, en supposant qu'elle dispose d'une mémoire importante.

Une base de données distribuée

Lisez également l'article consacré à la mise en production d'Elasticsearch et au réseautage.

Avant que Shay Banon crée Elasticsearch, il travaillait sur Compass. Il s'est rendu compte qu'il serait difficile d'en faire un moteur de recherche distribué. Il a donc revu sa copie et créé Elasticsearch1. Elasticsearch est une solution conçue pour être distribuée et facile à scaler afin de gérer d'énormes quantités de données sur du matériel courant.

Elasticsearch est une solution incroyablement facile à utiliser et à installer en tant que système distribué. Or, les systèmes distribués sont compliqués. Nous en parlons plus en détail dans notre article consacré à la mise en production d'Elasticsearch et au réseautage. Les informations fournies ci-dessous en sont une brève synthèse.

Une foule de problèmes peut survenir avec un système distribué, à cause de sa nature. En effet, différents systèmes de bases de données sont orientés vers divers points forts. Certains s'efforcent de fournir de solides garanties tandis que d'autres s'appliquent à être toujours disponibles, même s'ils contiennent parfois (voire la plupart du temps) des erreurs. En outre, les solutions qu'un système de base de données affirme pouvoir apporter lorsqu'un problème survient correspond rarement à la réalité à gérer, comme le souligne Kyle Kingsbury dans son excellente série d'articles dédiés aux dangers relatifs aux partitions réseau. En résumé, selon ses observations, même si les bases de données distribuées fonctionnent très bien quand tout va pour le mieux, la plupart rencontrent des difficultés lorsqu'elles doivent gérer le vaste éventail d'échecs possibles.

Concernant la cohérence, la disponibilité et la tolérance aux partitions, Elasticsearch est un système cohérent, mais non disponible dans les partitions réseau, ce qui correspond à une définition relativement insuffisante de "cohérent". Si vous gérez des charges de travail en lecture seule, Elasticsearch vous permet de bénéficier de comportements disponibles, mais non cohérents dans les partitions réseau, grâce à une exigence peu stricte quant au nombre minimal de nœuds maître, c'est-à-dire ne nécessitant pas de quorum. Or, en règle générale, la majorité des nœuds contenus dans le cluster doivent être disponibles. Tout processus d'écriture envoyé à un cluster mal configuré sans ces nœuds, c'est-à-dire un cluster doté d'un "split brain", peut engendrer une perte de données irrémédiable. Cette vulnérabilité n'est pas spécifique à Elasticsearch.

En matière de scaling, un index est divisé en une ou plusieurs partitions, qui sont précisées lors de la création de l'index et ne peuvent pas être modifiées. Par conséquent, un index devrait être partitionné de manière équitable afin de gérer la croissance attendue. À mesure que des nœuds supplémentaires sont ajoutés au cluster Elasticsearch, il réaffecte et déplace les partitions de manière efficace. Ainsi, Elasticsearch est une solution très facile à scaler.

Sécurité

Lisez également l'article consacré à la mise en production d'Elasticsearch et la sécurité.

Elasticsearch n'est dotée d'aucune fonctionnalité pour l'authentification ou l'autorisation. Vous devriez envisager d'attribuer des droits de "super utilisateur" à toute personne en mesure de se connecter à votre cluster Elasticsearch en particulier si les fonctionnalités de script performantes de cette solution sont activées.

Résumé

Il est certainement possible d'utiliser Elasticsearch en tant que stockage principal, lorsque les limites décrites dans cet article ne constituent pas un obstacle majeur. L'utilisation de Logstash en constitue un bon exemple. Logstash est un formidable outil de gestion des logs et d'intégration dans Elasticsearch, qui les archive peut-être aussi à un autre emplacement par sécurité. Les logs sont écrits une seule fois, mais lus de nombreuses fois. Aucune mise à jour, aucune transaction, aucune contrainte relative à l'intégrité ni aucune autre exigence n'est requise.

Qu'en est-il des systèmes comme Postgres qui sont dotés de la recherche full-text et des transactions ACID ? (D'autres exemples peuvent être cités, comme les fonctionnalités full-text de MySQL, MongoDB et Riak.) Lorsque vous pouvez implémenter la recherche de base avec Postgres, cela entraîne une importante lacune concernant les éventuelles performances et les fonctionnalités. Comme expliqué dans la section consacrée aux transactions, Elasticsearch peut "tricher" et mettre une grande quantité de données en cache, sans tenir compte du contrôle de la simultanéité des diverses versions ni d'autres éléments créant des complications. En outre, la recherche ne consiste pas seulement à trouver un mot-clé dans un texte : il s'agit d'appliquer des connaissances spécifiques à un domaine afin d'implémenter de bons modèles de pertinence tout en donnant un aperçu de tous les résultats générés, mais aussi en effectuant diverses opérations, comme la vérification orthographique et la saisie semi-automatique, le tout rapidement.

Elasticsearch est souvent utilisée en parallèle d'une autre base de données. Un système de base de données, qui est davantage orienté vers les contraintes, l'exactitude, la solidité, mais aussi la capacité à être facilement mis à jour sur un plan transactionnel, contient l'enregistrement maître qui est ensuite envoyé de manière asynchrone à Elasticsearch (ou extrait si vous utilisez une des rivières ou "rivers" d'Elasticsearch). La synchronisation des données sera abordée en détail dans un prochain article. Chez Found, nous utilisons habituellement PostgreSQL et ZooKeeper en tant que systèmes fiables, que nous intégrons à Elasticsearch afin de fournir une recherche remarquable.

Bien entendu, il n'existe pas de solution miracle, ni aucune base de données magique. Cette quête étant vaine, il est préférable que vous connaissiez bien les points forts et faibles de vos systèmes de stockage.

Références

Banon, Shay, The future of compass & elasticSearch, https://thedudeabides.com/articles/the_future_of_compass


  1. Shay Banon, The future of compass & elasticSearch, https://thedudeabides.com/articles/the_future_of_compass.