Données et bases de données
L'écosystème Hadoop : HDFS, YARN, MapReduce, Hive, HBase et Spark
Intermédiaire11 min de lectureMis à jour
Cette page a été traduite de l'anglais avec l'aide de l'IA, puis vérifiée par rapport à l'original. Lire la version anglaise
Hadoop a imposé l'idée qui a façonné une décennie de data engineering : déplacer le calcul vers les données et considérer la panne comme normale dès la conception. Ce guide explique les blocs HDFS et le NameNode, l'ordonnancement YARN, MapReduce et les raisons pour lesquelles Spark l'a supplanté, les rôles de Hive et HBase, le modèle DataFrame de Spark, et ce qui a encore du sens dans cette pile aujourd'hui.
Ce que vous allez apprendre
- Expliquer comment HDFS découpe, réplique et localise les blocs, et quel est le rôle du NameNode
- Décrire comment YARN alloue les conteneurs et comment les applications demandent des ressources
- Suivre un job MapReduce à travers les phases map, shuffle et reduce, et expliquer les avantages de Spark
- Choisir entre Hive, HBase et Spark selon le mode d'accès aux données
- Évaluer quelles parties de l'écosystème valent encore la peine d'être adoptées et ce qui a remplacé le reste
L'apport de Hadoop n'a pas été un logiciel mais une posture : partir du principe que les machines sont bon marché et qu'elles tomberont en panne, répartir les données entre elles, et envoyer le calcul là où les données se trouvent déjà. C'était l'inverse de l'hypothèse de la génération précédente, où l'on rapatriait les données vers une grosse machine coûteuse, et cela a rendu l'analyse de pétaoctets possible sur du matériel à la portée d'entreprises ordinaires.
Vingt ans plus tard, l'essentiel de l'implémentation d'origine a été dépassé, et pourtant son vocabulaire — blocs, shuffles, partitions, jobs, executors — reste celui du data engineering. Ce guide explique ce que fait réellement chaque composant, pourquoi Spark a supplanté MapReduce, et quelles briques méritent encore leur place dans une plateforme en 2026. Les choix d'architecture qui les entourent — data lakes, formats de table, streaming — font l'objet du guide sur l'architecture big data.
HDFS : un système de fichiers conçu pour la lecture séquentielle
Le Hadoop Distributed File System découpe chaque fichier en blocs de taille fixe, 128 Mo par défaut, et stocke chaque bloc sur plusieurs machines — trois par défaut, réparties sur au moins deux racks. Ce seul choix de conception explique l'essentiel de son comportement.
Deux types de processus font tourner le système :
- Le NameNode conserve en mémoire toute l'arborescence des répertoires et la correspondance entre blocs et DataNodes, et consigne chaque modification dans un journal d'édition (edit log). Il ne manipule jamais lui-même les données des fichiers : les clients lui demandent où se trouve un bloc, puis dialoguent directement avec les DataNodes.
- Les DataNodes stockent les blocs sous forme de fichiers ordinaires sur leurs disques locaux et se signalent par des heartbeats et des rapports de blocs. Quand un nœud cesse de se signaler, le NameNode constate que ses blocs sont sous-répliqués et demande à d'autres nœuds de les copier.
La mémoire du NameNode est la vraie limite du système : chaque fichier, répertoire et bloc exige un enregistrement en mémoire d'environ 150 octets. Un million de petits fichiers coûte donc bien plus cher qu'un seul gros fichier de même taille totale — c'est le problème des petits fichiers, que tout administrateur Hadoop a rencontré.
Trois propriétés découlent de cette conception et méritent d'être énoncées clairement. HDFS est write-once, append-only : impossible de modifier en place, les pipelines réécrivent donc des partitions entières. Il privilégie le débit plutôt que la latence, ce qui en fait une très mauvaise base de données et une excellente cible de scan. Enfin, il est rack-aware : il place les réplicas de sorte que la perte d'un rack entier ne fasse pas perdre de données, et que les lecteurs puissent privilégier une copie locale.
Hadoop 3 a apporté deux évolutions majeures. La haute disponibilité du NameNode fait tourner un NameNode actif et un NameNode de secours qui partagent les modifications via un quorum de JournalNodes, ZooKeeper se chargeant du basculement — auparavant, le NameNode était un véritable point de défaillance unique. Et l'erasure coding stocke des données de parité au lieu de réplicas complets, ce qui fait passer le surcoût de stockage de 200 % à environ 50 % pour les données froides, au prix de davantage de CPU et d'une reconstruction plus lente.
hdfs dfs -put sales-2026-09.parquet /data/raw/sales/dt=2026-09-07/
hdfs dfs -ls -h /data/raw/sales/dt=2026-09-07/
hdfs fsck /data/raw/sales -files -blocks -locations
hdfs dfsadmin -report
YARN : ordonnancer le cluster
Yet Another Resource Negotiator sépare la gestion des ressources du cluster de la logique applicative qui s'y exécute, et c'est ce qui a permis de faire tourner autre chose que MapReduce sur un cluster Hadoop.
- Le ResourceManager est l'ordonnanceur à l'échelle du cluster. Il connaît la capacité totale et distribue des conteneurs, chacun étant une réservation de mémoire et de CPU sur un nœud précis.
- Un NodeManager tourne sur chaque machine, lance les conteneurs et remonte leur état de santé et leur consommation.
- Chaque job soumis obtient d'abord son propre conteneur d'ApplicationMaster. Celui-ci négocie ensuite d'autres conteneurs pour le travail proprement dit, les surveille et relance ceux qui échouent. La gestion des pannes au niveau du job relève donc de l'application, pas de l'ordonnanceur.
En pratique, deux ordonnanceurs comptent. Le Capacity Scheduler divise le cluster en files d'attente hiérarchiques dotées de parts garanties et d'une élasticité optionnelle, ce qui convient aux organisations où chaque département dispose d'une capacité contractualisée. Le Fair Scheduler vise à donner à chaque application en cours une part égale dans la durée, ce qui convient aux charges ad hoc hétérogènes. Dans les deux cas, la leçon d'exploitation est toujours la même : un seul job mal dimensionné qui réclame des conteneurs énormes peut affamer tout le reste, d'où l'importance impérative des limites de file et des plafonds par utilisateur.
MapReduce, et pourquoi Spark l'a remplacé
MapReduce exprime un calcul sous la forme de deux fonctions séparées par un tri.
- Map s'exécute sur chaque split d'entrée — en général un bloc HDFS, planifié sur un nœud qui le détient — et émet des paires clé-valeur.
- Shuffle et tri achemine chaque paire vers le reducer responsable de sa clé, en triant par clé au passage. C'est la partie coûteuse : elle traverse le réseau et déborde sur disque.
- Reduce reçoit chaque clé avec toutes ses valeurs et émet le résultat.
Le comptage de mots en est l'illustration canonique : map émet (word, 1) pour chaque token, reduce additionne les valeurs par mot. Le modèle est d'une réelle élégance, et la même forme map-puis-reduce se retrouve dans du code applicatif ordinaire — l'API Streams de Java en est la version mono-machine.
Ses faiblesses sont structurelles, pas cosmétiques :
- Chaque étape est matérialisée sur disque. Un pipeline de cinq transformations écrit et relit l'intégralité du jeu de données cinq fois, avec réplication à chaque écriture.
- Les algorithmes itératifs sont pathologiques. Les algorithmes de machine learning et de graphes parcourent les mêmes données des dizaines de fois, en payant à chaque passe le coût complet des E/S.
- Seulement deux opérateurs. Jointures, filtres, agrégations et tris doivent être construits à la main à partir de map et reduce, si bien que les vrais jobs sont devenus de longues chaînes de classes Java.
- Batch uniquement. Ni requêtes interactives, ni streaming.
Apache Spark a résolu ces quatre problèmes avec un seul changement de modèle : garder le jeu de données en mémoire d'une étape à l'autre et décrire l'ensemble du calcul comme un graphe orienté acyclique (DAG) de transformations avant d'exécuter quoi que ce soit. Spark peut alors fusionner les transformations étroites en une seule passe, n'insérer un shuffle que là où les données doivent réellement être redistribuées, et réutiliser les données en cache d'une itération à l'autre. Les accélérations annoncées, de dix à cent fois par rapport à MapReduce, venaient surtout de la suppression des écritures intermédiaires, pas d'une arithmétique astucieuse.
Le modèle de programmation de Spark
L'abstraction d'origine de Spark était le RDD, pour resilient distributed dataset : une collection immuable et partitionnée, accompagnée du lignage enregistré des opérations qui l'ont produite. C'est grâce à ce lignage qu'il se rétablit : une partition perdue est recalculée à partir de ses parents plutôt que restaurée depuis un réplica. Les transformations (map, filter, join) sont paresseuses ; rien ne s'exécute tant qu'une action (count, collect, write) ne force pas l'évaluation.
Le code Spark moderne doit plutôt utiliser les DataFrames et les Datasets. Ils portent un schéma, ce qui permet à l'optimiseur Catalyst de réécrire la requête — en poussant les filtres jusqu'au scan, en élaguant les colonnes non lues, en choisissant les stratégies de jointure — et au moteur Tungsten de stocker les lignes dans une mémoire off-heap compacte et de générer du bytecode spécialisé. Conséquence pratique : un pipeline DataFrame bat généralement du code RDD écrit à la main, de la même façon que du SQL déclaratif bat une boucle écrite à la main.
val orders = spark.read.parquet("s3a://lake/curated/orders")
val customers = spark.read.parquet("s3a://lake/curated/customers")
val topRegions = orders
.filter($"placed_at" >= "2026-01-01" && $"status" === "SHIPPED")
.join(customers.select($"id", $"region"), $"customer_id" === $"id")
.groupBy($"region")
.agg(sum($"total").as("revenue"), countDistinct($"customer_id").as("buyers"))
.orderBy($"revenue".desc)
topRegions.explain(true) // read the physical plan before trusting the job
topRegions.write.mode("overwrite").parquet("s3a://lake/serving/revenue_by_region")
Spark SQL fait tourner le même moteur sur du texte SQL, si bien qu'analystes et ingénieurs partagent un seul chemin d'exécution. Structured Streaming réutilise l'API DataFrame pour des entrées non bornées, avec des fenêtres en event time et un état persisté par checkpoints. Spark 4 a poursuivi dans la même direction : la sémantique ANSI SQL est désormais activée par défaut, si bien que les dépassements silencieux et les troncatures implicites deviennent des erreurs ; Spark Connect découple le client du driver, ce qui permet à des clients légers de soumettre du travail à un cluster distant ; et un type natif VARIANT gère les données semi-structurées sans faire exploser le schéma.
Trois notions de performance expliquent l'essentiel du tuning Spark :
- Les partitions sont l'unité de parallélisme. Trop peu, et des cœurs restent inactifs ; trop, et le coût d'ordonnancement l'emporte. L'adaptive query execution les fusionne désormais automatiquement aux frontières de shuffle.
- Les shuffles sont l'opération coûteuse. Les transformations larges (
groupBy,join,distinct) en provoquent ; les transformations étroites, non. Une jointure broadcast évite complètement le shuffle quand l'un des deux côtés est assez petit pour tenir dans la mémoire de chaque executor. - Le skew — une clé qui concentre une part disproportionnée des lignes — laisse une seule tâche tourner longtemps après la fin des autres. L'adaptive execution peut découper les partitions déséquilibrées ; saler la clé est le remède manuel.
Hive et HBase
Apache Hive a mis du SQL au-dessus de fichiers. Une requête HiveQL est compilée en un job — historiquement MapReduce, puis Tez, et souvent Spark — sur des données stockées dans HDFS ou en stockage objet. Son apport durable n'est pas le moteur de requêtes mais le Metastore : une base relationnelle qui recense les tables existantes, leurs colonnes et leurs types, leurs partitions et l'emplacement de leurs fichiers. Ce catalogue a survécu à Hive lui-même ; Spark, Trino, Flink et Impala le lisent tous, et il reste un point d'interopérabilité courant, même dans des clusters sans la moindre trace de Hadoop.
Hive a les caractéristiques d'un moteur de scan : débit élevé, latence de l'ordre de la minute pour les gros jobs, pas d'index dignes de ce nom, et un support ACID ajouté après coup qu'il vaut mieux éviter au profit d'un format de table moderne. LLAP a ajouté des démons persistants et du cache pour rendre les requêtes interactives envisageables, mais la plupart des équipes branchent désormais Trino ou Spark SQL sur le même metastore.
Apache HBase est l'outil opposé : un store orienté colonnes larges inspiré de Bigtable, qui tourne au-dessus de HDFS et offre des lectures et écritures aléatoires en quelques millisecondes par clé de ligne. Les données sont organisées en familles de colonnes, découpées en régions par plage de clés de ligne et servies par des RegionServers ; les écritures passent par un write-ahead log et un store en mémoire qui est vidé vers des fichiers immuables, compactés en arrière-plan.
Bien utiliser HBase se résume entièrement à la conception de la clé de ligne. Les clés sont stockées triées, si bien qu'une clé monotone croissante (un horodatage, une séquence) envoie toutes les écritures vers une seule région — c'est le problème du hotspotting, que l'on traite en salant ou en hachant un préfixe. À l'inverse, une clé qui commence par la valeur sur laquelle portent vos scans rend les scans par plage efficaces. Il n'y a ni index secondaires, ni jointures, ni planificateur de requêtes : soit vous concevez la clé pour le mode d'accès, soit vous parcourez tout. Pour une comparaison avec l'approche document face au même compromis, consultez le guide MongoDB.
Autour gravitent les autres noms familiers : Sqoop pour le transfert en masse entre bases relationnelles et HDFS, largement remplacé par la capture de changements (CDC) vers un broker, comme décrit dans l'architecture de Kafka ; Oozie pour l'orchestration de workflows, remplacé par Airflow et des ordonnanceurs similaires ; Impala et Presto/Trino pour le SQL MPP interactif ; ZooKeeper pour la coordination, sous plusieurs des outils précédents ; et Apache Ozone, un stockage objet plus récent conçu pour lever les limites de HDFS en matière de petits fichiers et de passage à l'échelle.
Où en est l'écosystème en 2026
Le bilan honnête : les idées ont gagné, et l'essentiel de l'implémentation a été remplacé.
- HDFS est en mode maintenance dans la plupart des organisations. Le stockage objet dans le cloud offre une capacité pratiquement illimitée, sépare le stockage du calcul pour que chacun évolue indépendamment, et coûte moins cher. Spark et Trino le lisent directement via le connecteur S3A.
- MapReduce relève du legacy. Plus rien de nouveau ne doit être écrit avec ; les jobs existants sont migrés vers Spark.
- YARN subsiste on-premise, mais les nouveaux déploiements ordonnancent massivement Spark sur Kubernetes, ce qui unifie le modèle d'exploitation avec le reste de la plateforme — conteneurs, images et orchestration, comme expliqué dans les fondamentaux de Docker.
- Hive en tant que moteur a largement cédé la place à Trino, Spark SQL et aux entrepôts cloud ; le Metastore survit, même si les catalogues Iceberg REST le remplacent progressivement.
- HBase reste en place là où il a été déployé, tandis que Cassandra, ScyllaDB et les stores clé-valeur managés dans le cloud récupèrent les nouvelles charges.
- Spark se porte à merveille, et c'est la brique de l'écosystème qui vaut le plus la peine d'être apprise aujourd'hui.
Si vous héritez d'un cluster Hadoop, la voie pragmatique consiste généralement à : migrer le stockage vers du stockage objet avec un format de table ouvert, porter les jobs MapReduce sur Spark, conserver le metastore comme catalogue jusqu'à ce qu'un catalogue Iceberg le remplace, et faire passer l'ordonnancement de YARN à Kubernetes. Si vous partez de zéro, vous avez presque certainement besoin de Spark et d'un format de table, et presque certainement pas de HDFS.
Points clés à retenir
- HDFS stocke de gros blocs répliqués et immuables pour maximiser le débit séquentiel ; les métadonnées que le NameNode garde en mémoire expliquent pourquoi les petits fichiers font autant de dégâts.
- YARN sépare la gestion des ressources de la logique applicative grâce au ResourceManager, aux NodeManagers et à un ApplicationMaster par job qui demande des conteneurs.
- Le modèle map-shuffle-reduce de MapReduce est sain mais matérialise chaque étape sur disque, et c'est ce qui a rendu l'exécution en mémoire par DAG de Spark au moins dix fois plus rapide.
- Préférez les DataFrames Spark aux RDD pour que Catalyst et Tungsten puissent optimiser ; faites votre tuning en surveillant partitions, shuffles et skew.
- Hive est une couche SQL orientée scan dont le Metastore lui a survécu ; HBase est un store orienté colonnes larges à accès aléatoire où la conception de la clé de ligne détermine tout.
- En 2026, gardez Spark et l'idée de catalogue, migrez le stockage vers du stockage objet avec un format de table ouvert, et ordonnancez sur Kubernetes plutôt que sur YARN.
Sources et lectures complémentaires
Questions fréquentes
- Hadoop est-il mort ?
- MapReduce, en tant que modèle de programmation, l'est pratiquement, et rares sont les nouveaux projets qui déploient HDFS. Mais les idées de l'écosystème et plusieurs de ses composants lui survivent : le Hive Metastore catalogue toujours les tables pour des moteurs qui ne touchent jamais Hadoop, YARN ordonnance encore des clusters on-premise, et Spark, qui a grandi au sein de l'écosystème, n'a jamais été aussi utilisé. Voyez-le comme une infrastructure à comprendre et à reprendre, pas comme une base pour du neuf.
- Pourquoi la taille de bloc HDFS est-elle de 128 Mo ?
- Parce qu'un gros bloc amortit le coût des positionnements. Avec de petits blocs, un job passe l'essentiel de son temps à déplacer les têtes de lecture et à demander au NameNode où se trouvent les données ; avec de gros blocs, il lit en flux continu. Les gros blocs maîtrisent aussi la mémoire du NameNode, puisque chaque bloc exige un enregistrement en mémoire. La contrepartie : une multitude de petits fichiers gaspille à la fois des métadonnées de blocs et du temps d'ordonnancement.
- Quelle est la différence entre Hive et HBase ?
- Ils résolvent des problèmes opposés. Hive est une couche SQL au-dessus de fichiers en masse, destinée aux requêtes analytiques par parcours complet qui se mesurent en secondes ou en minutes, sans aucune notion de mise à jour ponctuelle. HBase est un store orienté colonnes larges pour des lectures et écritures aléatoires en quelques millisecondes par clé de ligne, sans planificateur de requêtes ni jointures. Utiliser l'un pour la charge de travail de l'autre ne mène qu'à la déception.
- Faut-il exécuter Spark sur YARN ou sur Kubernetes ?
- Kubernetes pour tout nouveau projet. Vous bénéficiez de la même isolation par conteneurs que vos autres charges de travail, d'un seul modèle d'exploitation pour toute la plateforme et d'un scaling élastique sur des instances cloud. YARN reste un choix raisonnable là où un cluster Hadoop on-premise existe déjà et où son Capacity Scheduler encode de vraies politiques multi-tenant qu'il faudrait sinon reconstruire.