1. Livres & vidéos
  2. Hadoop
  3. Premiers traitements avec MapReduce en Python
Extrait - Hadoop Maîtriser l’écosystème Big Data : HDFS, MapReduce, Hive, Spark…
Extraits du livre
Hadoop Maîtriser l’écosystème Big Data : HDFS, MapReduce, Hive, Spark… Revenir à la page d'achat du livre

Premiers traitements avec MapReduce en Python

Introduction

Après avoir étudié en détail l’architecture d’Hadoop et compris le rôle fondamental de MapReduce dans le chapitre Architecture de Hadoop, nous allons maintenant passer à la pratique. Ce nouveau chapitre marque une étape importante du parcours pédagogique, car il ne s’agit plus seulement de comprendre un modèle abstrait, mais d’apprendre à l’appliquer concrètement en écrivant et en exécutant des programmes distribués. L’outil choisi pour cette mise en œuvre est Python, un langage simple, largement utilisé dans le domaine des données, et parfaitement compatible avec l’écosystème Hadoop grâce au mécanisme de Hadoop Streaming.

MapReduce repose sur une idée simple mais puissante : décomposer un problème complexe en une série d’opérations élémentaires qui peuvent être exécutées en parallèle sur un grand nombre de machines. Le rôle du développeur consiste à définir deux fonctions, Map et Reduce, qui transforment et agrègent des données représentées sous forme de couples clé/valeur. Hadoop se charge ensuite du reste : distribuer les données, exécuter les tâches sur le cluster, gérer les éventuelles...

Comprendre le paradigme MapReduce

Le chapitre Architecture de Hadoop a posé les bases de l’écosystème Hadoop, une plateforme distribuée conçue pour traiter et stocker des volumes massifs de données de manière fiable et évolutive. Hadoop repose sur deux piliers essentiels : HDFS (Hadoop Distributed File System), qui découpe les fichiers en blocs de grande taille (128 ou 256 Mo) et les répartit sur un ensemble de serveurs appelés DataNodes, et MapReduce, son moteur de calcul distribué historique. 

Dans cette architecture, le NameNode joue un rôle central en gérant les métadonnées : il sait quels blocs composent chaque fichier, où ils sont stockés et quels droits y sont associés. Les DataNodes, quant à eux, stockent physiquement les blocs et communiquent en permanence leur état via des heartbeats pour assurer le suivi de la santé du cluster. Afin de garantir une tolérance aux pannes, chaque bloc est répliqué sur plusieurs DataNodes (trois copies par défaut). Ainsi, même en cas de défaillance matérielle, les données demeurent accessibles et Hadoop peut automatiquement recréer les blocs manquants.

Un autre composant clé est YARN (Yet Another Resource Negotiator), qui assure la planification et la gestion des ressources. YARN sépare le ResourceManager (allocation globale des ressources et planification des tâches) et les NodeManagers (supervision des ressources locales sur chaque nœud). Cette organisation rend Hadoop flexible, car différents moteurs de traitement - MapReduce, mais aussi Spark ou Tez - peuvent partager le même cluster.

Enfin, Hadoop suit le principe du « data locality » : au lieu de transférer d’énormes quantités de données sur le réseau vers une machine unique, il déplace le code de traitement au plus près des blocs de données. Ce concept est fondamental pour réduire la latence et améliorer le débit. Comprendre ces bases - HDFS, YARN, réplication des blocs et exécution proche des données - permet de saisir pourquoi le paradigme MapReduce est si efficace pour analyser des ensembles de données distribués à grande...

Écriture d’une première application MapReduce en Python

L’objectif de cette section est d’amener pas à pas le lecteur de la théorie vers la pratique. Nous allons montrer comment écrire un job MapReduce simple en Python, l’exécuter via Hadoop Streaming, comprendre précisément comment les mappers et reducers communiquent entre eux par les flux standards et visualiser le trajet des données entre HDFS et les tâches. La section suivante propose des squelettes prêts à l’emploi, des explications ligne par ligne et des exemples exécutables en local puis sur un cluster hadoop.

1. Hadoop Streaming : concepts, scripts et exécution

a. Présentation de Hadoop Streaming

Hadoop Streaming est un outil fourni avec Hadoop qui rend le paradigme MapReduce accessible sans nécessiter de développement en Java. Il fonctionne en utilisant la capacité qu’ont la plupart des langages de programmation à lire des données depuis l’entrée standard et à écrire des résultats vers la sortie standard, ce qui permet à des scripts externes d’être exécutés comme mappers et reducers sur un cluster distribué. Au lieu de compiler et empaqueter des classes Java, on prépare simplement des scripts en Python, Bash, Perl, Ruby ou tout autre langage capable de traiter un flux texte. Hadoop prend ensuite en charge la distribution des scripts à travers le cluster, l’envoi des portions de données appropriées aux mappers, puis la collecte des sorties intermédiaires, qui sont écrites sur le disque local des nœuds et transférées aux reducers lors de la phase de shuffle et de tri, pour effectuer l’agrégation finale, rendant ainsi la mise en œuvre de traitements distribués rapide et souple pour l’expérimentation ou l’enseignement.

Lorsqu’un job est lancé avec Hadoop Streaming, les fichiers stockés dans HDFS sont découpés en blocs et envoyés sous forme de flux de lignes à chaque mapper via stdin. Chaque script mapper lit ce flux, applique une logique métier et renvoie des paires clé tabulation valeur sur stdout. Hadoop lit ensuite ces paires, trie et regroupe toutes celles ayant la même...

Exécution sur plusieurs fichiers

1. Introduction : pourquoi traiter plusieurs fichiers en parallèle ?

Dans un environnement Big Data, les données ne se présentent presque jamais sous la forme d’un fichier unique, soigneusement formaté et prêt à être analysé. La réalité est beaucoup plus fragmentée : les systèmes applicatifs, les capteurs et les plateformes produisent continuellement des flux de données découpés en multiples fichiers. Ce découpage peut être intentionnel, pour faciliter la gestion et l’archivage, ou simplement inhérent au fonctionnement des systèmes qui génèrent les données.

Prenons l’exemple d’un serveur web d’entreprise : au lieu de conserver un unique fichier de logs qui grossirait de manière indéfinie, l’administrateur configure l’outil de journalisation pour qu’il crée un fichier par jour, voire par heure. Ainsi, l’analyse d’un mois complet de trafic web suppose d’examiner trente fichiers distincts. Dans un autre contexte, une flotte de capteurs IoT peut produire en continu des mesures envoyées par lots toutes les dix minutes, chacun étant stocké dans un fichier séparé. De même, une plateforme de commerce électronique découpe souvent ses transactions selon les régions géographiques ou les canaux de distribution, produisant ainsi une arborescence de répertoires et de fichiers qui reflète cette organisation.

Si l’on devait fusionner manuellement ces multiples fichiers pour les traiter en une seule passe, cela introduirait une étape supplémentaire coûteuse en temps, en espace disque et en complexité opérationnelle. Sur un volume de quelques mégaoctets, l’impact reste négligeable, mais dès lors que l’on parle de centaines de gigaoctets ou de téraoctets de données, la fusion préalable devient un goulot d’étranglement. Elle consomme des ressources disque et réseau sans apporter de valeur analytique, retardant le moment où les données peuvent réellement être exploitées.

C’est précisément ici que Hadoop et son écosystème montrent...

Optimisations possibles

L’efficacité d’un job MapReduce ne repose pas uniquement sur la logique des étapes Map et Reduce mais sur l’ensemble du pipeline distribué. Dans un environnement Big Data où les volumes de données atteignent plusieurs téraoctets et où un cluster peut contenir des centaines de nœuds, de petites inefficacités se traduisent par des heures supplémentaires de calcul ou une surcharge réseau. Les optimisations deviennent donc essentielles pour réduire le temps de traitement, minimiser la consommation des ressources et augmenter le parallélisme.

Plusieurs leviers sont disponibles et chacun agit sur une partie précise du flux MapReduce. L’utilisation d’un combiner, par exemple, permet de réduire très tôt la quantité de données à transférer entre mappers et reducers en réalisant une pré-agrégation locale sur chaque nœud. La compression des données intermédiaires diminue la charge réseau et accélère la phase de shuffle et sort, en particulier lorsque les sorties des mappers sont volumineuses. Le choix judicieux du nombre de reducers influence directement l’équilibre entre parallélisme et surcharge : trop peu de reducers allongent la phase Reduce, tandis qu’un nombre excessif introduit un coût de coordination supplémentaire.

D’autres optimisations incluent le réglage des partitions pour garantir une distribution équilibrée des clés entre reducers, ce qui évite que certains nœuds deviennent des goulots d’étranglement. L’activation du compression codec approprié (comme Snappy ou LZO) peut accélérer l’écriture et la lecture HDFS. Le paramétrage de la taille des splits HDFS et l’ajustement du nombre de tâches Map permettent également d’améliorer l’utilisation des ressources. Enfin, l’organisation des données d’entrée elle-même joue un rôle important : regrouper de nombreux petits fichiers en formats adaptés comme SequenceFile ou Avro évite une explosion du nombre de splits et de mappers, ce qui réduit la surcharge de gestion des tâches....

Limites de MapReduce et évolutions

1. Introduction

MapReduce a marqué une étape majeure dans le traitement des données massives en offrant un modèle simple, robuste et tolérant aux pannes, capable d’exploiter pleinement le parallélisme d’un cluster Hadoop. Cependant, malgré sa fiabilité et sa valeur pédagogique, ce paradigme montre certaines limites lorsqu’il s’agit de traiter des workflows complexes, interactifs ou itératifs. Les opérations de lecture et d’écriture systématiques sur HDFS entre chaque étape, la lenteur des traitements nécessitant plusieurs passes sur les mêmes données et l’absence de capacités in-memory sont autant de contraintes qui ralentissent les performances et imposent des solutions complémentaires.

Cette section a pour objectif d’analyser ces limites en détail, d’illustrer concrètement les situations où MapReduce devient moins performant et de présenter les évolutions technologiques qui ont émergé pour répondre à ces contraintes. Elle permettra de comprendre pourquoi Spark et Flink ont été développés, quelles optimisations ils apportent, et dans quels contextes MapReduce reste un outil pertinent, notamment pour l’apprentissage du traitement distribué et des concepts fondamentaux du Big Data.

En explorant ces aspects, le lecteur pourra non seulement apprécier les forces et les limites de MapReduce, mais aussi faire des choix éclairés pour ses projets, en combinant le modèle classique avec des technologies plus adaptées aux besoins modernes de traitement de données massives.

2. Lourdeur des écritures et lectures intermédiaires

L’un des principaux points faibles de MapReduce réside dans le volume d’entrées/sorties sur disque généré entre chaque étape du traitement. Lorsqu’un job MapReduce est lancé, chaque mapper produit des fichiers intermédiaires contenant des paires clé/valeur qu’il écrit sur le disque local du nœud. Ces données sont ensuite transférées aux reducers durant la phase de shuffle pour effectuer l’agrégation finale. Seules les sorties finales...

Synthèse

Ce chapitre marque une étape clé dans l’apprentissage d’Hadoop, puisqu’il introduit de manière progressive et détaillée le paradigme MapReduce. Le lecteur découvre non seulement la logique du modèle, mais aussi ses applications concrètes, ses optimisations possibles et ses limites face aux évolutions de l’écosystème Big Data.

La première partie de ce chapitre présente les fondements du paradigme MapReduce. À travers un rappel des concepts déjà abordés dans les chapitres précédents, l’accent est mis sur le modèle clé/valeur et son application à des jeux de données réels. Des exemples illustratifs permettent de comprendre comment un problème simple, comme compter des occurrences (fruits, mots, codes d’erreurs), peut être reformulé dans ce modèle. La comparaison entre un traitement séquentiel classique et l’approche distribuée d’Hadoop met en évidence les gains en performance et en fiabilité.

La deuxième partie de ce chapitre plonge dans la programmation MapReduce en Python grâce à Hadoop Streaming. Les mécanismes d’entrée et de sortie via stdin et stdout sont expliqués pas à pas, permettant au lecteur de comprendre comment connecter...