L’objectif ultime du Big « Data », c’est l’information, l’extraction de l’information pertinente pour la prise de décision, ce que beaucoup qualifient par « valeur » ou « insights« . L’objectif du « Big » Data est l’information. Malheureusement, malgré la disponibilité des technologies du Big Data, beaucoup d’entreprises et d’organisations ont encore du mal à obtenir l’information dont ils ont besoin. Comme nous vous l’avons expliqué dans notre chronique précédente sur les principes d’extraction de connaissance d’une base de données, on sait comment répondre aux requêtes d’interrogation d’une base de données. Mais ce qu’on ne sait pas faire c’est y répondre de façon opportune, et être capable d’effectuer des analyses de corrélation entre les données lorsque son volume est important.
L’un des raisons qui explique cette incapacité se situe dans l’architecture qui était utilisée jusqu’à présent pour développer les applications de [base de] données. A titre de rappel, le système informatique d’une entreprise est composé de plusieurs types de logiciels (logiciel de traitement de texte, tableur, SGBD, ERP, Data Warehouse) qui d’une manière ou d’une autre coexistent pour former un tout cohérent qui aide l’entreprise à atteindre ses objectifs de gestion. Techniquement, il existe deux façons de faire coexister les logiciels dans un système : soit par interfaçage (une architecture SOA), soit par intégration (une architecture monolithique). Malheureusement, le choix qui a été fait jusqu’à présent pour le développement applicatif, c’est la seconde, l’approche monolithique.
Dans cette chronique, nous allons voir ensemble comment l’approche architecturale utilisée pour développer une application de données influence sa performance et l’intérêt de l’architecture SOA en Big Data. Commençons par comprendre en quoi consiste l’intégration ou l’approche monolithique.
Sommaire
1- Intégrer le SI de l’entreprise : Développer une application comme un monolithe
L’approche par défaut utilisée pour développer une application de données, que ce soit en Big Data ou pas, est l’intégration logicielle. L’intégration logicielle est une stratégie de cohésion d’applications au sein d’un système informatique qui consiste à faire converger les applications à un standard. Cela est très fréquent lorsque des applications informatiques utilisent la même base de données par exemple comme support de fonctionnement. Dans ce cas de figure, le SGBD hôte de la base de données offre une API spécifique à laquelle doit se conformer toutes les applications qui veulent exploiter ses bases de données. L’intégration exige la conformité des applications à un standard ou à des conditions imposées par une autre application, parce que cette application centralise les données dont les autres applications ont besoin. L’intégration logicielle s’est imposée de fait pour le développement d’applications de données parce que les SGBD, à leur arrivée sur le marché, centralisaient les bases de données et les fonctions nécessaires pour leur manipulation. L’intégration logicielle exige de fait de développer les applications comme des monolithes, c’est-à-dire comme des applications « One-Size-fits-all » dans lesquelles les fonctionnalités de périmètres métiers entiers sont développées dans la même application. Par exemple, vous aurez la même application qui fournit des fonctionnalités de marketing, de gestion, de comptabilité, etc. L’exemple le plus typique d’applications monolithiques ou « One-Size-fits-alls » c’est l’ERP. L’ERP est un type de solution logicielle qui embarque pleins de modules qui permettent de gérer plusieurs périmètres fonctionnels d’une entreprise.
1.1- Le développement applicatif selon le modèle client/serveur
Revenons dans le monde de la data. Traditionnellement, le développement d’applications qui exploitent ou consomment la data est généralement fait selon le modèle client/Serveur (qui est une forme d’intégration logicielle). L’application se connecte à la base de données à travers un protocole compatible avec le SGBD tel que JDBC ou ODBC. La consommation des données se fait essentiellement à travers des requêtes envoyées par l’application au serveur. Le développement d’application consiste à encapsuler dans une interface utilisateur, des requêtes qui répondent au besoin d’un métier. Dans l’application, les requêtes sont écrites et envoyées au serveur de données à travers une API d’accès aux données telle que ADO, ADO.net, JDBC, etc. La figure ci-après illustre bien ce modèle de développement applicatif.
Lorsque l’application doit être déployée dans une architecture client/serveur à 3 niveaux, le développement devient un peu plus complexe et ces 3 composants doivent être encapsulés dans des packages différents. La partie UI (appelée dans ce cas de figure front-end) se développe avec du HTML, et des frameworks web tels que Angular, Skeleton, GroundCSS, etc… qui pour le coup ont besoin d’un serveur web pour l’interprétation du code HTML (par exemple Apache Tomcat, ASP.NET, etc.). La partie applicative encapsule les requêtes et la logique métier de l’application et s’appelle désormais serveur applicatif (IBM WebSphere, JBoss, etc…). C’est le serveur applicatif qui communique seul avec le serveur de base de données. Il reçoit les requêtes de la partie UI pour les transmettre au serveur de données à travers l’API de la base de données.
Le modèle Client/Serveur fonctionne très bien et a l’avantage de créer une indépendance logicielle entre les différents composants de l’architecture ; par exemple le développeur UI concentre son attention uniquement sur la partie UI sans que cela n’affecte les autres composants du système, pareil pour le développeur applicatif. Les packages de déploiements sont indépendants d’une partie à une autre. Ce cloisonnement de fonctionnalités facilite grandement le développement d’application de données, qui ne se résume plus qu’à l’établissement de la connexion avec la couche de données et l’écriture de requêtes. Le développeur d’application de données n’a quasiment aucun développement de fonctionnalités à faire car celles-ci sont déjà soit intégrées dans le SGBD, soit alors encapsulées dans les autres couches de l’architecture. L’avantage majeur de la répartition de ces fonctionnalités entre les couches est de créer l’indépendance entre la base de données et les applications qui l’exploitent. Cette indépendance favorise la standardisation du développement d’applications de base de données et permet aux développeurs de coder les applications métier sans avoir à encapsuler la structure de la base de données dans le code ou de se soucier de la façon dont le SGBDR gère la base de données.
1.2- Couplage fort entre la base de données et les applications
Quoique le développement d’application de données soit plutôt facile dans le modèle de développement Client/Serveur, le problème majeur qu’il rencontre provient justement de son avantage : l’encapsulation de toutes les fonctionnalités majeures dans la couche de données crée un couplage très fort entre la base de données et les applications. Les applications sont certes indépendantes de la base de données, mais elles dépendent fortement de sa structure. En d’autre termes, si un changement dans la structure de la base de données venait à être réalisée (par exemple ajout d’une nouvelle colonne, modification de la structure d’une table, changement du type d’une colonne, suppression d’une colonne, etc…), ce sont des applications entières qui devront être modifiées.
D’un point de vue organisationnel, ce type d’architectures dans lesquelles les applications sont fortement couplées à la base de données ou entre elles requiert une coordination importantes entre les différentes équipes de l’entreprise pour les maintenir et les faire évoluer. Le déploiement applicatif n’est pas indépendant. Le cycle de vie des applications ne peut pas être géré par des entités autonomes de l’entreprise, ce qui a un impact majeur sur le niveau de disponibilité des applications.
C’est à cause de ce couplage fort qui existe entre les applications et la base de données qu’on qualifie ce modèle de développement de « monolithe » ou « application monolithique », soit application tout-en-un (ou modèle d’application « one size-fits-all »). Ce type de développement ne favorise pas du tout le déploiement d’applications, et rend l’évolution de l’architecture très difficile. Tout changement dans la base de données nécessite une modification et un redéploiement de toutes les applications qui sont impactées par ce changement.
De plus, dans un monolithe, la couche serveur (le SGBD) est un standalone dont toutes les fonctionnalités sont exécutées dans un processus informatique unique. Sa scalabilité ne peut donc se faire que par réplication de tout le monolithe sur plusieurs serveurs. Il n’est pas possible de passer à l’échelle en partitionnant le processus et en le distribuant sur les nœuds d’un cluster conformément à l’approche Cluster Computing adaptée pour les problématiques du Big Data. Il est par conséquent très difficile de profiter de la logique du cluster computing avec une approche monolithique.
2- Découpler les données des applications : l’Architecture SOA et l’approche orientée [micro-]service
L’approche de développement monolithique a bien marché, spécialement à une époque où les entreprises étaient intégrées verticalement d’un point de vue organisationnel. Aujourd’hui, pour devenir plus compétitif, les entreprises ont compris qu’une délégation de pouvoir est nécessaire, et que cela passe nécessairement par un aplatissement de la hiérarchie, et la décentralisation du pouvoir de prise de décision. En clair, les entreprises sont quittées d’une organisation hiérarchique à une organisation modulaire. Pourquoi nous commençons par cette note ? Tout simplement parce qu’en règle générale, les approches de développement et/ou de déploiement logiciel adoptées par une entreprise sont souvent le reflet de sa structure organisationnelle. Ainsi, une entreprise à organisation centralisée aura souvent tendance à naturellement se tourner vers une approche informatique monolithique. Décentraliser une organisation exige automatiquement une autonomie des différentes équipes de la DSI dans leurs choix stratégiques, technologiques et techniques, chose qui doit se traduire dans les approches utilisées.
L’approche monolithique couple fortement la base de données aux applications, ce qui force l’entreprise a être dans une approche centralisée où la même équipe gère entièrement de A à Z le cycle de vie de toutes les applications. Ainsi, pour obtenir une organisation décentralisée (ou modulaire), il faut absolument découpler la base de données de ses applications. C’est dans cette démarche que s’inscrit l’approche orientée service, plus connue sous le nom d’architecture SOA.
Pour découpler les applications (ou réduire la dépendance forte qui existe entre elles) au sein de toute l’entreprise, l’approche consiste à réorganiser les composants applicatifs du SI en « services ». La caractéristique principale de ces services étant l’interopérabilité (la réutilisation potentielle par d’autres composants informatique).
2.1- Définition et avantages des services
A titre de rappel, un système est dit interopérable lorsqu’il peut communiquer avec d’autres composants existants ou futurs sans aucune restriction d’accès ou de mise en œuvre. L’interopérabilité garantit que le même composant pourra être utilisé par n’importe quel autre technologie présente ou future. L’interopérabilité transcende la compatibilité applicative et la diversité technologique. Le service est une application, à la différence qu’il est interopérable, il est une sorte de boîte noire qui subsiste par lui-même parce qu’il embarque toutes les fonctionnalités nécessaires à son fonctionnement. Il communique avec l’extérieur via des interfaces. C’est d’ailleurs pourquoi la seconde stratégie de cohésion des applications d’un système informatique est l’interfaçage. A la différence de la stratégie d’intégration, les applications ne dépendent pas d’un composant central et communiquent entre elles via des interfaces applicatives (ou web).
Le principe est le suivant : un fournisseur offre un service à un client qui le consomme dans une relation de confiance (contrat) établie entre les deux parties. Le client, qui peut être un logiciel, un programme ou un autre service, utilise (consomme) le résultat offert par le service sans se soucier de savoir comment ce dernier est obtenu. Par exemple : supposons que vous développiez une application logicielle de gestion de stocks dans laquelle vous avez besoin d’implémenter des fonctions de géo-localisation. Au lieu de développer vous-même ces fonctions, vous faites appel à Google et implémentez son service Google Earth dans votre logiciel via une API. Votre application est alors un client de Google, qui est le fournisseur du service Google Earth. Votre application ne sait pas comment Google Earth fournit les fonctionnalités du service. Elle ne fait que consommer les résultats de ces fonctionnalités à travers les API fournies.
Une API (Application Programming Interface ou interface de programmation applicative) est une interface offerte par un service, dans laquelle sont exposées des méthodes à appeler pour tirer profit des fonctionnalités du service. L’API est le contrat passé entre le fournisseur de service et le client. Elle définit ce que le client peut ou ne peut pas faire. L’API se présente sous forme d’une classe et chaque méthode expose une fonctionnalité précise du service. Le service communique avec l’extérieur ou est appelé de l’extérieur à travers l’API, qui définit les fonctionnalités que celui-ci expose. C’est en réalité à l’API qu’on fait référence lorsqu’on dit qu’un service communique à l’extérieur via une interface ; l’API est cette interface.
L’avantage des services est triple :
- chaque service a un périmètre fonctionnel très clair : chaque service est responsable d’un périmètre fonctionnel clair et ses fonctionnalités sont limitées à un domaine précis, ce qui minimise le risque de non-disponibilité que font peser le composant central dans un monolithe. Les fonctionnalités du service sont clairement définies dans son interface à travers la liste de ses méthodes.
- les services sont indépendants les uns des autres : les services sont comme des boîtes noires pour les autres services ; cela signifie que leur implémentation ne dépend pas d’un autre service ou d’une autre application. Un service n’encapsule pas les fonctionnalités d’un autre service, comme c’est le cas dans un système monolithique. Lorsqu’un service fait appel à un autre service, c’est le résultat de ce service qu’il reçoit, pas la façon dont ce résultat est obtenu. Ainsi, les services peuvent être développés, testés, déployés et maintenus indépendamment. Puisqu’un échange entre deux services implique uniquement un échange de résultat (et pas de fonctionnalité), l’indépendance qui existe entre les services peut également être d’ordre technologique (ils peuvent être développés avec des langages différents, implémentés dans des technologies différentes, communiquer avec différentes bases de données, sans que cela n’affecte les échanges avec l’extérieur).
- Chaque service a un cycle de vie qui lui est propre : grâce à ses caractéristiques inhérentes, l’un des avantages les plus importants des services réside sans aucun doute dans la gestion de leur cycle de vie. Étant donné que les services sont complètement indépendants, leur cycle de vie peut être confié à une équipe dédiée ou réparti sur un ensemble d’équipes dans l’entreprise, avec chaque équipe se concentrant uniquement sur un service spécifique ou une étape spécifique de leur cycle de vie. Là où dans une approche monolithique, toutes les applications sont gérées par des équipes souvent fortement dépendantes les unes des autres, dans l’approche par services, chaque équipe (ou département d’équipes) est responsable du cycle de vie entier du service, du développement, au tests, déploiement, maintenance et versioning. Ce qui est intéressant c’est que chacune de ces équipes travaille de façon indépendante sans que cela n’affecte les autres. Cela ne signifie pas que les équipes s’ignorent ou ne communiquent plus entre elles, mais que la communication entre elles se fait uniquement pour convenir ensemble de l’API (l’interface qui expose les méthodes/propriétés à travers lesquelles le service va communiquer avec l’extérieur) afin que la communication entre les services soit clairement définie. Cette indépendance intra-équipe concoure à rendre le cycle de vie de chaque service indépendant.
Ainsi, la démarche orientée services (SOA) est très efficace pour répondre aux besoins d’interopérabilité et de réutilisabilité de différentes applications. L’interopérabilité favorise la rapidité d’exécution et la flexibilité dans le développement applicatif. C’est d’ailleurs selon cette approche que de nombreuses technologies de l’écosystème Hadoop ont pu être développées aussi rapidement ; vVous pouvez combiner plusieurs outils pour la résolution d’un problème au lieu de chercher une application « one-size-fit-all ». Par exemple : ZooKeeper, Oozie, HBase, … pour le traitement massivement parallèle, l’écosystème Berkley Data Analytics Stack qui combine les applications comme Mesos, Spark, MLib pour le traitement distribué In-Memory. Lorsque vous combinez ces applications, vous obtenez un système distribué qui ressemble à un assemblage de puzzles Lego. Avec cette possibilité, le développeur n’a plus beaucoup de développement à faire ou de code à écrire (la charge de développement baisse), tout ce qu’il a à faire c’est simplement savoir combiner sous forme modulaire l’ensemble d’applications de manière à ce que cet ensemble réponde à son besoin.
2.2- Service ou microservice ?
A la différence d’une approche orientée service( ou architecture SOA) qui elle, est plus centrée sur la définition des composants applicatifs bornés et indépendants d’un SI, l’architecture en microservices est, au contraire, liée spécifiquement à la façon dont on développe les applications. Plus concrètement, l’approche en micro services est un style architectural dans lequel une application est développée comme une suite de mini-services (d’où l’expression « micro-service ») autonomes s’exécutant chacun dans son propre processus et communiquant en exposant leur fonctionnalité via une API ou un protocole de communication très léger tels que le HTTP.
Chaque micro-service implémente une et une seule fonctionnalité et a un cycle de vie (du développement jusqu’au déploiement) qui est complètement indépendant des autres micro-services de la même application. Tout comme les services, chaque micro-service a un cycle de vie qui est entièrement géré par une équipe. Là où le service est un composant qui couvre un périmètre précis, le micro-service est un composant du service. A notre sens, le niveau de granularité des micro-services est trop bas pour les cas d’usages que nous avons rencontrés jusqu’à présent pour les recommander en Big Data. La granularité du service est suffisante pour la majorité des systèmes à notre sens, et rares sont les applications qui sont suffisamment larges pour être découpées en micro-services. Martin Fowler a beaucoup travaillé sur ce concept. Sur sa chronique très détaillée sur les micro-services, vous trouverez expliqué plus en profondeur l’intérêt des micro-services. Nous lui empruntons son schéma suivant pour illustrer les micro-services.
2.3- SOA, services, microservice et API REST
Pour exposer ses fonctionnalités et communiquer avec l’extérieur, les services ou microservices utilisent une API. Dans la pratique, ce qui se fait spécifiquement, c’est l’usage d’une API REST pour l’exposition des données ou des résultats des traitements des services/microservices. Par exemple, vous remarquerez que dans la chronique précédente sur Elasticsearch, c’est une API REST qui est proposée à l’utilisateur pour interroger les données. Il en de même avec Kafka et son service Kafka Connect Pourquoi ? Qu’a le modèle REST de si particulier ? « API REST » est l’un des concepts qu’il est important d’appréhender pour comprendre l’intérêt de l’architecture SOA, spécialement en Big Data. Nous allons en donner les détails.
En réalité, lorsqu’on parle de REST, on ne fait pas particulièrement référence à un type d’API précis, mais à un ensemble de bonnes pratiques à respecter pour développer des services. Il a été mis au point au départ pour le développement des services web, mais peut aussi bien s’utiliser pour les services applicatifs. Le REST permet d’uniformiser le développement de services. Dans le modèle REST, la communication est client/serveur : des clients font la demande d’une ressource (un jeu de données par exemple) à un fournisseur qui leur en fournit l’accès. Les ressources sont identifiées de façon unique par une URI (Uniform Resource Identifier), avec une syntaxe similaire à une adresse web : protocole://host:port/Ressources/RessourceID ou simplement protocole://host/Ressources/RessourceID. Par ailleurs, il n’est pas rare de voir des architectures REST présentant les URI selon la syntaxe suivante : protocole://host/Ressources?method=nom_de_methode¶m=parametre_de_methode.
Le format d’échange utilisé pour transférer les ressources est le JSON (le XML est aussi souvent utilisé). L’API d’un service RESTful expose les fonctionnalités d’une application sous forme de ressources accessibles à l’aide de simples méthodes GET, PUT, POST, DELETE ou PATCH. Il est important de garder à l’esprit que la réponse renvoyée par le serveur REST n’est pas la ressource elle-même, mais sa représentation, qui s’appuie sur un format tel que le JSON. En revanche, l’API RESTful par laquelle vous accédez à la ressource la manipule réellement.
Par exemple, supposons que nous souhaitions réaliser un service REST pour gérer les livres d’une bibliothèque. Le service doit nous permettre d’ajouter, modifier, lire et supprimer ces livres, qui constituent les ressources à manipuler. Supposons que le serveur ait pour adresse http://bibliotheque/.
Les livres auront pour URI http://bibliotheque/livres/livre_id.
À l’aide d’un outil comme postman, on pourrait envoyer les requêtes suivantes :
- Lire le livre 4 : GET http://bibliotheque/livres/4 ;
- Modifier le livre 10 : POST http://bibliotheque/livres/10 ;
- Supprimer le livre 7 : DELETE http://bibliotheque/livres/7
Voilà ! Nous sommes arrivés au terme de cette chronique sur l’usage de l’architecture SOA et des [micro-]services pour le développement d’applications Big Data. Ce que vous devez retenir c’est que la meilleure façon de développer les applications Big Data aujourd’hui est de les développer comme des services qui communiquent avec d’autres services via une API REST autant que cela est possible. Les services augmentent la probabilité d’obtenir des systèmes les plus efficaces possibles pour l’extraction de connaissance des données. Ils minimisent le temps que l’on peut passer sur le cycle de vie d’une application de données. C’est d’ailleurs grâce à l’approche SOA que le développement d’applications en Big Data ressemble aujourd’hui plus à l’assemblage de puzzles Lego (la sélection des technologies dans l’écosystème Hadoop qui correspondent au besoin) qu’au codage pur et dur !
Si vous avez aimé cet article, n’hésitez pas à nous donner un coup de main dans sa diffusion en le partageant sur vos différents réseaux sociaux grâce aux boutons de partage qui s’affichent sur le site.
Lectures recommandées
Si vous souhaitez aller en profondeur dans la compréhension de l’architecture SOA, les [micro]-services, et la façon dont le style architectural SOA est utilisé pour développer les applications Big Data, je vous recommande de vous procurer l’ouvrage suivant.
« Maîtrisez l’utilisation des technologies Hadoop » : l’ouvrage contient plusieurs chapitres sur l’architecture SOA, et surtout sur son usage dans le développement d’applications en Big Data.
Microservice Architecture : voici un très bon livre qui traite exclusivement du développement des microservices. Après les ressources de Martin Fowler, je vous recommande vivement cet ouvrage si vous souhaitez maîtriser ce sujet.