Vous travaillez sur des projets de reporting, Business Intelligence, Big Data et vous avez du mal avec vos requêtes ? Vos bases de données SQL prennent trop de temps pour s’exécuter ? Vos requêtes SQL sont trop lentes ? Vous connaissez certainement l’angoisse que ressentent les métiers lorsque la réponse aux questions qu’ils se posent prennent trop de temps. Vous souhaitez améliorer la performance de vos requêtes SQL ? Vous contempler l’idée de migrer votre base de données Teradata vers Hadoop ? Cette chronique a été rédigée pour vous. Vous comprendrez pourquoi vos requêtes sont lentes et comment les corriger.

Dans la chronique précédente Data Mining : les principes d’interrogation d’une base de données, nous vous avons expliqué que l’approche conceptuelle utilisée par les SGBD et les moteurs de bases de données SQL pour interroger les données repose sur l’indexation de contenu. Dans cette chronique, nous allons poursuivre dans cette lancée. Nous vous expliquerons comment est ce que cette approche est implémentée d’un point de vue technologique, ce qui à son tour vous permettra de comprendre où se positionnent Teradata et Hadoop.

1 – Approche technologique classique d’interrogation d’une base de données

Avant l’avènement des moteurs SQL/NoSQL capables de s’exécuter sur un cluster et les nouvelles approches innovantes d’indexation de contenu, l’interrogation d’une base de données se faisait par exécution des requêtes SQL sur un SGBDR.

Les data analysts et les métiers rédigent leurs requêtes d’interrogation de données dans le langage SQL. Ces requêtes sont exécutées sur le serveur de base de données selon un modèle d’architecture client/serveur. Entrons-y en profondeur.

1.1 – Le SQL comme langage d’interrogation de base de données

Les SGBDR disposent de fonctionnalités d’indexation textuelle. Le SQL incorpore dans sa norme ISO/IEC 13 249-3:2011 des extensions pour l’interrogation de contenu numérique et alphanumérique dans la base de données.

Mais ce qu’il ne faut pas perdre de vue (ce que beaucoup de professionnels data oublient malheureusement) c’est que le SQL est un langage « ensembliste », autrement dit, il permet d’exprimer et d’adresser des calculs ensemblistes au SGBDR. Les SGBD-R, qu’on appelle encore bases de donnéss relationnelles ou bases de données SQL, sont des SGBD « ensemblistes », ils gèrent des « relations » (ou les tables), des ensembles algébriques (ou mathématiques) de données de même domaine. C’est très important de comprendre cela pour comprendre l’interrogation des bases de données et l’amélioration de la performance de vos requêtes !

Ainsi, bien que le SQL permette aux utilisateurs d’exprimer leurs requêtes dans un langage assez proche du vocabulaire humain, il n’en demeure pas moins qu’il reste un langage ensembliste qui en réalité permet d’effectuer des opérations algébriques telles que les jointures, le produit cartésien, la restriction, ou la projection. Il offre également un ensemble de fonctions mathématiques qui permettent de construire des prédicats, d’effectuer des calculs agrégés (moyenne, somme, total, etc.) et des calculs élémentaires comme la concaténation de texte, le modulo de division de valeurs de deux colonnes, ainsi de suite.  A partir de la norme SQL-2003, il prend également en compte les fonctions de fenêtrage.

Donc, lorsque l’utilisateur exprime une requête d’interrogation de données telle que :

 SELECT name FROM tbl_clients ;

Il est en réalité en train d’indiquer au SGBDR, des opérations ensemblistes ou algébriques qu’il doit réaliser. Ce ne sont pas les clauses SQL qui en arrière-plan exécutent les calculs ensemblistes, mais le moteur du SGBDR.  Elles indiquent juste au moteur les opérateurs algébriques qu’il doit exécuter. Le moteur transforme ces clauses en plan d’exécution optimisé qui par la suite est transformé en instructions machines. Nous y reviendrons dans le point suivant. Le tableau ci-après montre les clauses SQL les plus couramment utilisées pour l’interrogation des données, ainsi que l’opération algébrique à laquelle chacune correspond.  

Clauses SQL et opérateurs relationnels correspondants.

Pourquoi est-ce que nous vous expliquons ceci alors que ce qui nous intéresse c’est l’approche technologiques d’interrogation des bases de données ? Tout simple ! C’est ce fonctionnement inhérent aux bases de données relationnelles et au SQL qui  est à la base de tous les problèmes de performances liées à l’interrogation de données. En fait, c’est de là que tout part !

Même si les SGBDR et le SQL nous ont très bien servi (et continue de nous servir) pour l’interrogation des bases de données,  il n’en demeure pas moins que les calculs ensemblistes, qui sont des opérations de la mathématique d’ensemble sont des opérations très très coûteuses [à réaliser] d’un point de vue CPU. Elles sont tellement coûteuses qu’en entreprise, l’interrogation de la BD pour des fins d’analyse décisionnelle  est réalisée dans des serveur de Data Warehouse, des serveurs qui abritent une copie dénormalisée de la base de données.

A ce problème inhérent de complexité d’interrogation des bases de données, rajoutez-y les accès concurrents à la base de données (le nombre de personnes qui exécutent en simultanée leurs requêtes d’interrogation de données à la BD) et le problème de plafond de verre que nous avons évoqué dans la chronique Introduction à Hadoop et l’écosystème Big Data devient immédiatement apparent !

Résoudre les challenges d’interrogation à large échelle des données et ceux associés à l’industrialisation de la data science sont les sujets les plus chauds du marché de la data ! Pourquoi la data science ? Parce que la data science, tout comme l’algèbre d’ensemble, c’est de la mathématique et la mathématique est gourmande en CPU. Ainsi, travailler dans le Big Data revient fondamentalement à résoudre l’un de ces 2 problèmes. Notre ouvrage  Maîtrisez l’utilisation des technologies Big Data a été rédigé pour vous aider à y parvenir.

A ce stade, vous ne réalisez peut-être pas encore en quoi les bases de données SQL sont problématiques d’un point de vue technologique pour l’interrogation de données. Nous allons y revenir. Mais avant, un point sur la façon dont un SGBDR exécute en interne les requêtes SQL.

1.2 – La recherche de contenu dans une base de données

Exécuter une requête d’interrogation de base de données SQL dans un SGBDR revient à retrouver des données contenant certains mots, expressions, formes fléchies de mots ou synonymes dans les lignes d’une table et pour des colonnes particulières. Le principe est le suivant : l’utilisateur définit une « requête » et spécifie, à l’aide de clauses SQL que nous avons mentionné plus haut et d’une fonction de recherche, les termes qu’il souhaite trouver dans une (ou plusieurs) table(s) de la base de données. Le SGBDR retourne les lignes qui répondent strictement aux critères de recherche, c’est-à-dire les lignes qui contiennent les mots recherchés. Le SGBDR évalue chaque ligne de façon binaire (« présent » ou « absent ») et retourne exclusivement les lignes qui satisfont les critères de recherche.

Techniquement, dans le SGBDR, l’indexation se fait sur la clé primaire de la table et la recherche de contenu se fait sur les lignes de la table indexée. En termes de clauses, le SQL fournit 4 opérateurs principaux pour la recherche : LIKE, CONTAINS, OR et AND. Il dispose également des fonctions de nettoyage comme TRIM, SUBSTR, etc. pour affiner la requête. Le tableau suivant donne le rôle de chaque opérateur et un exemple d’application. L’index textuel est donc composé de deux parties : la liste de tous les mots indexés, et la référence croisée entre les mots et leur position dans la table.

opérateurs SQL de recherche et de nettoyage de texte classiques pour les bases de données SQL

En fait, l’interrogation des bases de données en SQL classique est binaire, cela implique qu’elle ne tient compte ni de l’intention de recherche véritable de l’utilisateur, ni de la sémantique des termes (pour un SGBDR, « John Smith » diffère de « jon Smith« ). C’est à l’utilisateur d’être le plus précis possible dans sa requête. En plus de cela, les recherches dans les SGBDR ne peuvent se faire que sur les données structurées (les tables) et, étant donné que ce sont des opérateurs ensemblistes qui sont exécutées, la performance de traitement des requêtes ne peut que baisser avec l’augmentation du volume de données et du niveau de concurrence à la base de données. Maintenant le décor est planté. Place à l’exécution technologique d’interrogation des bases de données.

2 – Exécution technologique des requêtes d’interrogation de bases de données SQL

Comme nous vous l’avons expliqué précédemment, c’est avec le SQL que débute l’interrogation des données. Le SQL est un langage très expressif pour les utilisateurs métiers, il leur permet d’exprimer dans un style simple et non-mathématique, des requêtes ensemblistes. En réalité, comme nous l’avons expliqué dans le tutoriel le SQL sur Hadoop , le SQL n’est qu’un langage d’abstraction. Comme expliqué dans le tutoriel, il masque la complexité d’expression des requêtes directement en langage de bas niveau (type Java, Python, Scala, etc.) comme le ferait un développeur. Lorsque la requête SQL est soumise au système, elle est transformée plus bas en instructions machines exécutables par le CPU du serveur. Il est important que vous sachiez comment le SGBDR exécute ces requêtes pour comprendre pourquoi  l’interrogation des bases de données relationnelles est de façon inhérente très coûteuse. Gardez à l’esprit que la base de données relationnelle est un ensemble au sens mathématique du terme et non un fichier informatique. L’objectif de ce point est de vous expliquer comment les SGBDR transforment les requêtes SQL en opérations d’algèbre relationnelle et comment il les exécute. C’est la connaissance de ce processus seul qui vous permettra de comprendre comment résoudre techniquement les problématiques de recherche  de contenu et par l’occasion d’écrire un code SQL optimisé et performant.

Lorsque vous soumettez votre requête SQL au SGBDR, son exécution passe par 3 phases :

  • La vérification syntaxique : dans la première étape, la syntaxe du code SQL est vérifiée par le système. Le SGBDR s’assure que celui-ci est conforme aux spécifications de la norme SQL qu’il supporte (ANSI SQL-92, 2003, etc.). Si l’utilisateur a mal saisi une instruction, s’est trompé sur l’écriture d’une clause, ou a écrit une instruction non-supportée par la norme SQL utilisée par le SGBDR, alors le système génère une erreur et le programme s’arrête ;
  • La création d’un plan optimal d’exécution : dans une seconde étape, lorsque la syntaxe de la requête est validée, la requête SQL est transformée en plan d’exécution, un arbre de décision hiérarchique similaire à un graphe acyclique direct qui indique au moteur du SGBDR l’ordre dans lequel les clauses de la requête doivent être exécutées. Ne soyez pas intimidés par l’expression « graphe acyclique direct ».  Un graphe est simplement la description de l’ordre dans lequel les opérations d’un programme doivent être traitées pour répondre au besoin pour lequel le programme a été exécuté. Dans le cas d’une requête SQL, c’est l’ordre dans lequel les clauses de la requête doivent être traitées. Par exemple, considérons la requête suivante :
SELECT sum (vente) FROM customers WHERE age_client BETWEEN 25 AND 30 GROUP BY genre ;

Le plan d’exécution de cette requête est le suivant :

graphe acyclique direct SQL
figure : graphe d’exécution de la requête SQL

La requête est transformée en un plan de 5 étapes pour l’obtention des résultats souhaités. Au départ, une opération permet de lire la table Customers, par la suite le système effectue un filtre sur la colonne de l’âge du client pour conserver uniquement les clients dont l’âge est situé entre 25 et 30 ans compris, un regroupement de ces clients par genre sur la table filtrée est réalisé, le calcul de la somme des ventes sur les clients ainsi groupés par genre et filtrés par âge est effectué et enfin les résultats sont enregistrés dans une table temporaire puis restitués au client. 

Le plan d’exécution d’une requête SQL produit par un SGBR est un graphe acyclique Orienté ou acyclique direct (Directed Acyclique Graph – DAG), l’enchaînement des opérations entre les clauses est direct et sans détour, aucune opération n’est itérative (ou cyclique) (cf. TEZ – chapitre 2 Maîtrisez l’utilisation des technologies Hadoop). Remarquez dans l’exemple que l’ordre ou chemin du plan d’exécution n’est pas unique. Le système pourrait tout aussi bien commencer par regrouper les données par genre, avant de calculer la somme et de filtrer par âge. Ainsi, le système a plusieurs choix dans le cheminement du plan d’exécution d’une requête SQL. Ce constat soulève une question : comment le système fait-il pour choisir le cheminement des opérations du plan d’exécution de la requête ? Au passage, notez que chaque cheminement dans l’exécution des requêtes ne fournit pas la même performance. Le fait de faire une somme avant d’effectuer un filtre sur les données ne s’exécute pas aussi rapidement que le fait de filtrer avant d’effectuer la somme. Autrement dit, les cheminements possibles du plan d’exécution ne se valent pas en termes de performance. Pour répondre à la question, le système calcul le chemin optimal pour l’exécution de chaque requête SQL soumise. En d’autres termes, le SGBDR va déterminer la combinaison d’enchaînement des clauses SQL qui est la plus rapide à exécuter. C’est pourquoi nous parlons de la création d’un plan optimal d’exécution. Heureusement, ce calcul ne se fait pas de façon aléatoire. Il se fait selon des règles précises qui ont déjà été définies et qui ne laissent aucun hasard dans l’optimisation de la performance des requêtes SQL.

  • La compilation et l’exécution de la requête : une fois que le plan d’exécution est produit, la requête est compilée en instructions machine et ce sont ces instructions qui sont exécutées par le processeur de la machine sur laquelle le SGBDR est installé. Ces instructions sont exécutées dans l’ordre du cheminement séquentiel spécifié par le plan de la requête.

 La figure suivante illustre le processus globale d’exécution d’une requête SQL.

Graphe acyclique direct d'une requête SQL
Figure : processus d’exécution globale d’une requête SQL. La syntaxe de la requête est vérifiée ensuite si elle est valide, le chemin optimal de son exécution est déterminé et enfin elle est compilée et exécutée selon l’ordre spécifié par le chemin optimal.

3 – Nouvelles approches technologique d’exécution des requêtes d’interrogation de bases de données

Encore une fois, les requêtes SQL sont des opérateurs ensemblistes. Autrement dit, ce sont des opérations de la mathématique d’algèbre d’ensemble. Et en tant que tel, elles sont particulièrement coûteuses en termes de CPU et dégradent rapidement la performance du serveur avec l’augmentation de la taille de la base de données et le volume d’utilisateurs concurrents. C’est motivé par la recherche de solutions à ces deux problèmes que naquirent les  nouvelles architectures et  approches technologiques pour l’interrogation efficace des bases de données.

Globalement, toutes les solutions ont la même base : quitter l’architecture client/serveur classique dans laquelle l’exécution de toutes les requêtes d’interrogation de la bases de données est centralisée sur un seul serveur pour adopter une approche distribuée dans laquelle l’exécution des requêtes est parallélisée sur plusieurs nœuds d’un champs de serveur ou d’un cluster. Les pionniers dans l’implémentation de cette approche aujourd’hui sont Teradata et Hadoop. Cette approche est aujourd’hui la plus efficace pour l’interrogation de base de données. Nous en avons déjà longuement parlé dans les différentes chroniques que nous avons rédigées, mais savez-vous véritablement comment cette approche fonctionne ?

Teradata a choisi de l’implémenter avec les SGBDR MPP, tandis que Hadoop a choisi de l’implémenter à travers le cluster Computing. Nous allons voir le fonctionnement de ces 2 approches, mais avant, intéressons-nous à la fondation commune à ces deux approches : le CPU Shared-Nothing.

3.1 – Le CPU Shared-Nothing : la fondation de l’approche distribuée de traitement des requêtes d’interrogation de bases de données

Le problème technologique véritable avec les opérations ensemblistes c’est l’accès concurrent. Si le serveur central doit traiter une seule requête SQL, alors il n’y aura aucun problème. Par contre, si plusieurs personnes envoient des requêtes ensemblistes au serveur, alors c’est le crash assuré du serveur ! Dans le passé, les serveurs étaient équipés de CPU synchrones, c’est-à-dire des CPU qui exécutent les traitements de façon séquentielle. Cela signifie que lors d’accès concurrents, les requêtes SQL des utilisateurs étaient mises en attente et exécutées une à une.  Bien évidemment, cela génère une latence qui finit par frustrer les utilisateurs. Pour résoudre ce problème, les fabricants de micro-processeurs (Intel et AMD principalement) se sont concentrés pendant plusieurs années à fabriquer des CPU à fréquence de plus en plus élevée (la fréquence d’un CPU, souvent mesuré en temps de l’horloge, c’est le nombre d’instructions que le CPU peut traiter par seconde). On est ainsi quitté des CPU de 1 Ghz à 2.2 Ghz, de 2.2 à 3 Ghz, etc…. Malheureusement, au niveau des bases de données, cette augmentation de fréquence CPU n’était pas visible car contrebalancée par la croissance des données et le nombre d’utilisateurs connectés à Internet.

Les entreprises se sont alors mises à faire de l’Upsizing pour faire passer leur serveur à l’échelle. Parallèlement, les fabricants de CPU ont procédé à un changement de paradigme dans le développement des CPU ; ils sont passés du mode synchrone au mode distribué pour résoudre les problèmes soulevés par leurs clients. Cela a donné naissance aux CPU Asynchrones, encore appelés techniquement CPU SMP (Symmetric Multi Processing). Les CPU asynchrones ont une architecture différentes des CPU classiques. Ils possèdent plusieurs unités de calculs (les cœurs – ou Core en anglais) qui se partagent la même mémoire (les régistres du CPU). Cette architecture est appelée l’architecture Shared-Memory. Ils divisent le travail à traiter en tâches (threads) qui sont exécutées en concurrence (en même temps) sur toutes les unités de calcul du CPU. On qualifie ce type d’exécution de « multi-threading » (mutli-tâches). C’est ainsi que naquirent des CPU dual-core, CPU core i3, des CPU quadri-core, des Core i7, etc. La figure suivante représente l’architecture d’un processeur SMP.

CPU SMP à architecture Shared Memory
Figure : Processeur à architecture SMP. Le processeur (CPU) possède plusieurs unités de calcul qui partagent la même mémoire. Attention ! Même si la figure présente chaque unité de calcul comme un CPU séparé, en réalité, le schéma représente le même CPU.

Au sein du processeur, chaque unité de calcul a une cadence identique. Par exemple un CPU quadri-core de 2 Ghz est un CPU qui possède 4 unités de calcul cadencées chacune à 2Ghz. Normalement, avec cette logique, un CPU SMP de 6 cœurs devrait théoriquement être capable de traiter 6 fois plus d’instructions à la seconde qu’un CPU synchrone classique n’est ce pas ? En fait ce n’est pas le cas ! Le multi-threading fonctionne bien uniquement sous la condition que le tâche soit divisible en tâches indépendantes. En réalité les tâches dans le multi-threading ne sont pas indépendantes, elles sont interdépendantes. Les traitements sont coopératifs, et non indépendants. Le traitement dans un CPU asynchrone simultané est un traitement coopératif ou plusieurs processus de calcul se synchronisent sur l’utilisation et la mise à jour d’un ensemble de variables partagées en vue de traiter  le problème.

L’inconvénient avec cette approche est que la ressource partagée sur laquelle sont démarrés les threads limite le nombre de processus concurrents qui peuvent y être exécutés. De plus, l’écriture des programmes asynchrones simultanés peut être très compliquée et les risques de verrous sont très élevés, dû à l’accès concurrents à la mémoire partagée du CPU. A cause de ces problèmes, les CPU SMP ne sont adaptés qu’à deux types de problématiques : les problématiques nécessitant le parallélisme Asynchrone Simultané tel que le traitement des bases de données orienté Graphe, et les problématiques nécessitant le parallélisme pipeline (Pipeline Parallel Processing) tel que le traitement de certains calculs mathématiques (par exemple le calcul des déciles). Nous avons traité ces types de parallélismes plus en profondeur dans le premier ouvrage du projet Hadoop – Devenez opérationnel dans le monde du Big Data. Nous vous recommandons vivement de vous le procurer si ce n’est pas encore le cas pour mieux comprendre les concepts associés au parallélisme.

L’architecture Shared-Memory des CPU SMP n’est pas adéquate  pour l’interrogation des bases de données à haute concurrence car la mémoire partagée finit par devenir un goulot d’étranglement qui annule le multi-threading. Malgré ces challenges, les fabricants de CPU n’avaient pas dit leur dernier mot. Ils  ont conservé la structure asynchrone des CPU SMP (les cores), mais les ont doté d’un nouveau type d’architecture : l’architecture Shared-Nothing. Dans un architecture Shared-Nothing (encore appelé architecture MPP – pour Massively Parallel Processing ou architecture à traitement massivement parallèle),  chaque core ou unité de calcul possède sa propre mémoire et ne partage aucune ressource avec les autres. De cette façon, les threads sont COMPLETEMENT indépendantes les unes des autres.

CPU MPP
Figure : CPU à architecture MPP. Chaque unité de calcul ou core du processeur possède sa propre mémoire et ne partage aucune ressource avec les autres cœurs. De cette façon, les traitements peuvent être divisés en tâches qui s’exécutent de façon complètement indépendante.

Avec cette architecture, les traitements peuvent être parallélisé simplement en attribuant à chaque unité de calcul, un bloc ou « shard »  de données. La scalabilité est atteinte simplement en augmentant le nombre d’unité de calcul dans le CPU. Cela implique que les requêtes peuvent être exécutées localement par chaque unité de calcul qui contient une partie de la Base de données interrogée. Grâce à cette caractéristique, les CPU Shared-Nothing (CPU MPP) apparaissent comme la fondation parfaite (car scalable à l’infini théoriquement) pour l’interrogation des bases de données à haute concurrence. Ils sont devenus la fondation technologique des problématiques de recherche de contenu. Pour plus de détails sur les architectures de CPU, notamment CPU Shared-Nothing, Shared-Memory ou encore Shared-Disk, les caractéristiques de CPU et les types de parallélisme, nous vous recommandons de lire le chapitre 2 de votre copie de Hadoop – Devenez opérationnel dans le monde du Big Data.

2 éditeurs ont repris les principes des CPU MPP à large échelle pour les appliquer aux SGBD : Pivotal GreenPum (racheté par EMC, elle-même récemment rachetée par Dell) et Teradata. Plus tard, dès 2002, en constatant la baisse des coûts du matériel IT, Google s’est inspiré de ces mêmes principes pour les appliquer à ce qui deviendra plus tard Hadoop. Nous allons vous montrer comment chacune de ces 2 approches  procèdent pour appliquer les principes des CPU MPP pour l’interrogation de bases de données.

3.2 – Les SGBDR MPP : l’approche de Teradata

Teradata et GreenPlum ont été les pionniers des SGBDR MPP. Ces SGBD s’appuient sur les principes de l’architecture Shared-Nothing pour résoudre les problématiques d’interrogation d’une base de données. Teradata est aujourd’hui le leader dans cette approche. Nous l’utiliserons donc en guise de représentant pour toutes les solutions de SGBD MPP.

En mi-décembre 1999, l’entreprise Deutsche Telecom a  annoncé que son DataWarehouse stockait 100 Téraoctets de données (soit 102 400 Go). La question qui se pose alors est : comment faire pour qu’un SGBDR qui héberge un DataWarehouse d’une telle volumétrie réponde efficacement aux requêtes  SQL des utilisateurs ?

Pour résoudre les problèmes similaires à celui de Deutsche Telecom, Teradata propose :

  1. de partir sur un champ de serveurs, un ensemble de serveurs (entre 4 et 8) très puissants  qui ne partagent aucune ressource et sont auto-suffisants. Les serveurs du champs sont comme les unités de calcul d’un CPU shared-nothing. Un serveur Leader est désigné dans le champ pour agir comme celui qui réceptionnera les requêtes et les partagera aux autres serveurs (configuration réseau Maître-esclave).
  2. Dans chaque serveur du champ, on place une réplique de la structure de la base de données identique et vide (concrètement, on exécute le même script SQL de création de la base de données dans chaque serveur du champ).
  3. ensuite on partitionne les données de la base de données et on distribue les partitions à tous les serveurs du champ contenant la réplique de la structure de la base de données. 

La figure suivante illustre cette solution.

Architecture base de données SQL Teradata
Figure : architecture globale d’un SGBDR MPP (dans ce cas de figure, un champ de 4 serveurs). La structure de la base de données est répliquée dans les serveurs du champs de calcul de sorte que chacun en ait une copie. Ensuite, les données de la BD sont partitionnées selon une méthode de partitionnement et chaque partition est affectée à un serveur du champ. Cela signifie que vous installez Teradata sur le serveur maître du champ, et une instance du logiciel tournera automatiquement dans les autres serveurs du champ ; ensuite vous jouez le script SQL de création de la BD dans chaque serveur et enfin vous utilisez une méthode de partitionnement pour fragmenter la BD et affecter chaque partition à un serveur.

Avec ce mode de fonctionnement, les requêtes SQL qui arrivent dans le système pour interroger la base de données sont parallélisées et exécutées de façon concurrente comme des processus indépendants sur les serveurs contenant les partitions de la base de données. Comme chaque nœud contient une partie de la base de données, il s’en suit que la charge de calcul (les 100 To par exemple) est répartie à travers tout le champ et que les processus de la requête s’exécutent directement In Situ (en local) dans le serveur.

La figure suivante illustre le partitionnement et la distribution de la base de données dans les serveurs du champ.

base de données SQL distribuée
Figure : distribution et partitionnement de la base de données dans les serveurs du champ.

Tous les SGBD MPP qui permettent de répondre aux requêtes d’analyse décisionnelle (Teradata, GreenPlum, HP Vertica, etc…) fonctionnent pratiquement de cette façon. Maintenant que vous avez compris cette approche, il faut comprendre comment les requêtes SQL y sont exécutées.

Exécution des requêtes SQL dans les SGBDR MPP

Lorsque la base de données est développée pour des besoins de Reporting à grande échelle et est installée sur des SGBDR parallèles capables de s’exécuter sur plusieurs machines dans un environnement distribué, le schéma d’exécution que nous avons vu précédemment ne s’applique pas.  Le processus général reste le même, mais le schéma d’exécution change.  Les requêtes SQL sont décomposées en processus parallèles, et exécutées de façon concurrente sur tous les serveurs contenant une copie de la base de données.  La vérification syntaxique et la construction du plan d’exécution sont faites au niveau du serveur central de l’environnement distribuée, tandis que la compilation et l’exécution du code sont faites par les serveurs de calcul. La figure suivante illustre cette exécution.

Teradata hadoop
Figure : schéma d’exécution du SQL en environnement distribuée. La vérification syntaxique et le calcul du plan d’exécution sont effectués par le serveur central du champ, tandis que la compilation et l’exécution sont faites par les serveurs de calcul.

L’exécution des requêtes SQL en environnement distribué et les bases de données parallèles sont un vaste sujet auquel nous avons consacré tout un ouvrage entier : Maîtrisez l’utilisation des technologies Hadoop.  Maintenant que nous avons couvert l’approche SGBDR MPP d’exécution des requêtes SQL d’analyse décisionnelle, nous allons couvrir maintenant l’approche cluster computing d’Hadoop

3.3 – Le cluster Computing : l’approche d’Hadoop

Nous espérons que vous avez compris que les SGBDR MPP exécutent uniquement des requêtes ensemblistes, c’est-à-dire des requêtes SQL sur des tables relationnelles. Ils profitent des effets d’échelle produits par la mise en parallèle de plusieurs serveurs MPP. Malheureusement, malgré les avantages de performance qu’elle fournit, l’approche SGBDR MPP possède 2 grandes limites :

  • Premièrement, elle ne fonctionne que pour des données relationnelles (ou données « structurées »). La grande majorité de contenu produit sur Internet aujourd’hui est textuel (les pages web). On dispose de plus en plus de contenu enrichi, qualifié de données « non-structurées » (fichiers JSON, XML, vidéos, etc.). Il n’est pas possible d’exécuter des requêtes ensemblistes (le SQL) sur ce type de contenu.  Il faut donc un autre modèle pour interroger ces types de données ;
  • Deuxièmement, les SGBDP MPP ont des coûts de licence très élevés ☹ En plus du logiciel, il faut souvent se procurer une infrastructure informatique spécialisée, mise à disposition par l’éditeur. Le plus souvent, l’entreprise n’a pas la main sur la montée en charge de cette infrastructure. Toute demande d’augmentation de performance est coûteuse et l’extension des licences du logiciel aux utilisateurs est particulièrement coûteuse. Ceci est un autre frein pour l’adoption à large échelle de l’approche SGBDR MPP comme approche technologique par excellence pour l’interrogation des bases données.

L’approche adoptée initialement par Google, puis repris par la communauté open source pour surmonter ces deux problèmes tout en interrogeant efficacement tout type de données consiste à :

  • Conserver l’aspect MPP des architectures shared-nothing, mais réduire la facture IT (le TCO) en partant sur un cluster de machines commodes, bon marché. Ici, on essaye de profiter de la baisse des coûts IT pour constituer un cluster qui peut passer à l’échelle à l’infini, puisqu’on reste sur des machines bon prix. Dans les SGBDR MPP, les champs vont être de quelques serveurs, car les serveurs coûtent très chers, sont très lourds à administrer et ne peuvent pas passer à l’échelle aussi simplement qu’un cluster de machines commodes. La figure suivante illustre l’approche cluster computing
cluster computing hadoop
Figure : La configuration Shared-Nothing, utilisée dans le cluster computing. A la place des serveurs, chaque nœud dans le cluster est une machine commode, bon marché. Ce qui permet de faire passer le cluster à l’échelle à théoriquement à l’infini. Une telle souplesse serait très difficile à obtenir avec un champ de serveurs de SGBDR MPP.
  • Pour l’interrogation des données, partir sur un algorithme générique, facilement parallélisable pour l’interrogation des données, structurées comme non-structurées.  Le modèle algorithmique qui a été développé à cet effet est le MapReduce. Etant donné que le but du modèle algorithmique est d’interroger les données structurées comme les données non-structurées et sachant qu’il va s’exécuter sur un cluster, il est indispensable de disposer d’un nouveau type de système de fichiers, un système de fichiers hybride, aussi bien adapté pour l’interrogation des données structurées que non-structurées et capable de fonctionner sur un cluster. Ce système est appelé « système de fichiers distribué ». L’un des plus connu est le HDFS.

Un mot sur le MapReduce

Le MapReduce est un modèle algorithmique généraliste qui s’exécute sur un cluster. Il s’exécute en trois étapes lors d’une interrogation de données ou une recherche de contenu : la lecture des termes du dictionnaire de l’index sur chaque nœud (le Map), la récupération des documents de ces termes (Shuffle) et l’agrégation des documents en fonction de la liste des valeurs (Reduce).  Dans le premier ouvrage du projet Hadoop – Devenez opérationnel dans le monde du Big Data, nous parlons du fonctionnement du MapReduce dans l’indexation des pages Web en profondeur.

  • le Map : dans cette étape,  le noeud principal du cluster assigne à chaque tâche une partition de document. La fonction Map s’exécute sur chaque noeud de calcul et transforme le contenu de la partition de documents en paires de clés/valeurs  où la clé est le terme de la requête dans le dictionnaire de l’index et la valeur est l’identifiant du document, par exemple son nom, son URL, etc. ;
  • le Shuffle : dans cette étape, les paires de clé/valeurs précédemment générées sont triées par ordre de clé, autrement dit par ordre de terme, ce qui permet de regrouper l’ensemble des documents qui contienne chaque terme. Cette étape est optionnelle ;
  • le Reduce : ici, le nœud principal du cluster récupère les résultats de l’étape Shuffle et les agrège en fonction de la technique définie par le programmeur pour obtenir les résultats finaux qui vont être renvoyés à l’utilisateur.

Pour plus de détails sur le fonctionnement du MapReduce, n’hésitez pas à vous procurer l’ouvrage Hadoop – Devenez opérationnel dans le monde du Big Data. L’avantage du modèle MapReduce dans la recherche de contenu et l’interrogation des données est qu’il masque la complexité de l’exécution parallèle des tâches aux yeux du développeur et passe facilement à l’échelle avec l’accroissement de la complexité du système et des ressources disponibles. De plus, en cas de panne d’un nœud, le nœud principal du cluster peut simplement re-planifier les tâches qui s’exécutaient sur ce nœud vers d’autres nœuds. Tout ceci se fait sans l’intervention du développeur.

Cette approche Cluster + Système de fichiers distribué + Modèle algorithmique parallèle, est plus adéquate au contexte Big Data actuel et est l’approche technologique utilisée aujourd’hui pour la recherche de contenu et l’interrogation des données. C’est grâce à cette approche que le moteur de recherche de Google traite plus de 200 million de requêtes par jour sur plus de 20 Téra octet de données, en utilisant un cluster de plus de 20 000 nœuds. Le Système de fichier distribué permet de gérer le stockage et la redondance des documents indexés, tandis que l’algorithme profite du parallélisme et de la scalabilité du cluster pour faire l’indexation et la recherche de contenu dans les documents. Nous allons finir cette deuxième chronique de la série avec un exemple pratique de l’exécution de deux requêtes d’interrogation de base de données avec le MapReduce sur un cluster.

Exemple #1 : calcul d’un Index Inversé

Comme nous l’avons dit dans la chronique précédente (lien), un index inversé est une page d’index qui, pour chaque mot d’un document (par exemple un livre ou une page Web) énumère l’ensemble des numéros de pages dans lesquelles il est apparu. Il est très utile dans des applications de recherche Web, dans l’édition et autres domaines où on doit gérer d’énormes quantités de texte. Ici, la fonction map () transforme chaque page et émet une séquence de paires  de :

(mot,document ID),avec mot=la clé de la paire et document ID=la valeur de la paire.

La fonction reduce () trie les paires par mot et émet une paire de. Les sorties de la fonction reduce () constituent l’index inverse. L’application du MapReduce donne ceci :

mapreduce Hadoop
Figure: Calcul d’un index inversé à l’aide du MapReduce

Exemple #2 : Jointure de 2 tables relationnelles

Les jointures de tables relationnelles sont monnaie courante dans le monde du traitement de données. Par définition, celles-ci sont des requêtes ensemblistes, donc des opérations algébriques qui s’exécutent sur des SGBDR. Pour exécuter une jointure dans un cluster en utilisant le modèle algorithmique MapReduce, il faut trouver le moyen de la paralléliser, c’est-à-dire de la découper en opérations indépendantes qui peuvent s’exécuter de façon isolées. Une technique simple permet de paralléliser une jointure. Nous allons illustrer cette technique  à l’aide d’un exemple. Supposons que nous avons les 2 tables suivantes :

tables pour jointure

Nous souhaitons avoir pour chaque employé, la liste des départements dans lesquels il est assigné. En d’autres termes, nous souhaitons obtenir la table suivante :

table Teradata jointe

Pour effectuer cette opération et faire une jointure de table de façon générale à l’aide du MapReduce, il faut procéder par 3 étapes :

  • Rajouter dans chaque table la colonne du nom de la table  et faire une concaténation verticale des tables ;
  • Passer Le fichier obtenu à la fonction map() et la clé de la paire sera la colonne qui lie les 2 tables ;
  • Le Reduce obtient en entrée les clés  avec leur liste de valeurs, ensuite il les regroupe par clé de façon à obtenir les lignes des 2 tables correspondant à la même clé (la jointure).

Le schéma ci-après illustre l’application du MapReduce à la jointure des 2 tables :

Process jointure avec mapreduce
Figure : Jointure de tables à l’aide du MapReduce

Voilà ! Nous sommes arrivés à la fin de cette seconde chronique de la série sur l’interrogation des bases de données. Nous espérons que vous avez compris les différentes approches technologiques d’interrogation d’une base de données ainsi que leur fonctionnement et leurs limites. Ce que vous devez retenir principalement est que traditionnellement, l’interrogation des bases de données se fait par exécution de requêtes SQL sur les bases de données SQL. En réalité, les requêtes SQL sont des opérateurs ensemblistes, des opérations de mathématique d’algèbre d’ensemble qui s’exécutent selon des règles définies par un arbre de décision. Le problème avec les requêtes SQL est qu’en tant opérations ensemblistes, elles sont particulièrement coûteuses en termes de CPU et dégradent rapidement la performance du serveur avec l’augmentation de la taille de la base de données et le volume d’utilisateurs concurrents. C’est motivé par la résolution de ces problèmes que des approches plus performante ont été développées, notamment l’approche SGBD MPP (portée par Teradata ou Greenplum, Vertica) et l’approche Cluster computing (porté par Hadoop). Ces deux approches ont pour similarité de profiter du parallélisme des architectures de CPU Shared-Nothing pour répartir l’exécution des requêtes d’analyses décisionnelles sur un ensemble de machines. Quoique conceptuellement les deux approches s’équivalent, l’approche Cluster Computing open source sur laquelle est basée Hadoop est plus adaptée pour l’interrogation des données et la recherche de contenu dans le contexte du big data, car plus souple en matière de scalabilité, plus flexible en matière de variété de données et moins coûteux en matière de licences.  Les ouvrages Maîtrisez l’utilisation des technologies Hadoop et Hadoop – Devenez opérationnel dans le monde du Big Data ont été rédigés pour vous accompagner dans l’interrogation des bases de données dans un contexte Big Data.

Alors, quelle approche utilisez-vous pour rendre vos requêtes plus rapides ? Que pensez-vous de Teradata et d’Hadoop ? préférez-vous Téradata à Hadoop ? Indiquez-nous votre position dans les commentaires.


Juvénal JVC

Juvénal est spécialisé depuis 2011 dans la valorisation à large échelle des données. Son but est d'aider les professionnels de la data à développer les compétences indispensables pour réussir dans le Big Data. Il travaille actuellement comme Lead Data Engineer auprès des grands comptes. Lorsqu'il n'est pas en voyage, Juvénal rédige des livres ou est en train de préparer la sortie d'un de  ses livres. Vous pouvez télécharger un extrait de son dernier livre en date ici : https://www.data-transitionnumerique.com/extrait-ecosystme-hadoop/

  • Celime dit :

    Merci Juvenal. Les explications sont très claires ! Merci encore.

  • >