Vous êtes sur la page 1sur 113

Hadoop / Big Data

Benjamin Renaut <renaut.benjamin@tokidev.fr>

MBDS 2016 - 2017


1 Introduction

Programme Planning Objectifs TP/valuations


Introduction
1-1

Benjamin Renaut
Tokidev SAS
- Bureau d'tude
- Dveloppement
- Consulting

http://www.tokidev.fr/
Avant de commencer
1-2

Posez des questions.


Si un point n'est pas clair, n'hsitez pas poser des questions tout moment.

Point de contact: ben@tokidev.fr


Vous pouvez m'envoyer toute question par e-mail concernant le cours, les TDs ou le
partiel.

Google est votre ami !


Si vous rencontrez un problme, prenez le rflexe d'effectuer une recherche dans
une majorit de cas, quelqu'un d'autre aura eu le mme problme que vous :-)

Cours en ligne: http://cours.tokidev.fr/bigdata/


Disponible cette adresse: la machine virtuelle utilise pour les TPs, les slides des
cours.
Objectifs
1-4

Dcouvrir la mthodologie map/reduce.

Apprendre installer et utiliser Hadoop.

Apprendre rdiger et excuter des programmes pour Hadoop.

Dcouvrir diverses solutions complmentaires lies Hadoop et aux


problmatiques Big Data en gnral (Pig, MongoDB, etc.).

Apprendre utiliser Apache Spark.

Apprentissage bas sur la pratique.


2 Le calcul distribu / Historique Hadoop
Le calcul distribu
2-1

Dsigne l'excution d'un traitement informatique sur une multitude de


machines diffrentes (un cluster de machines) de manire transparente.

Problmatiques:

Accs et partage des ressources pour toutes les machines.


Extensibilit: on doit pouvoir ajouter de nouvelles machines pour le calcul si
ncessaire.
Htrognit: les machines doivent pouvoir avoir diffrentes architectures,
l'implmentation diffrents langages.
Tolrance aux pannes: une machine en panne faisant partie du cluster ne doit
pas produire d'erreur pour le calcul dans son ensemble.
Transparence: le cluster dans son ensemble doit tre utilisable comme une
seule et mme machine traditionnelle.
Le calcul distribu
2-2

Ces problmatiques sont complexes et ont donn lieu des annes de


recherche et d'exprimentation.

On distingue historiquement deux approches/cas d'usage:

Effectuer des calculs intensifs localement (recherche scientifique,


rendu 3D, etc.) - on souhaite avoir un cluster de machines local pour
acclrer le traitement. Solution qui tait jusqu'ici coteuse et
complexe mettre en oeuvre.

Exploiter la dmocratisation de l'informatique moderne et la bonne


volont des utilisateurs du rseau pour crer un cluster distribu via
Internet moindre cot. Solution qui suppose qu'on trouve des
volontaires susceptibles de partager leur puissance de calcul.
Exemple: Blue Gene (1999)
2-3

Supercalculateur classique.

Connecte 131072 CPUs et 32 tera-octets de RAM, le


tout sous un contrle centralis pour assurer
l'excution de tches distribues.

L'architecture est ici spcifiquement construite pour


le calcul distribu grande chelle. Il s'agit d'un
cluster local (ne passant pas par Internet).

Premier supercalculateur tre commercialis et


produit (par IBM) en plusieurs exemplaires.

Utilis pour des simulations mdicales, l'tude de


signaux radio astronomiques, etc.
Exemple: GPUGRID.net (2007)
2-4

Projet de l'universit Pompeu Fabra (Espagne)


permettant des volontaires partout dans le monde
de mettre disposition le GPU de leur carte
graphique pour le calcul distribu (via NVIDIA
CUDA). Il s'agit d'un cluster distant: distribu
via Internet.

Le GPU est nettement plus performant que le CPU


pour certaines tches comme le traitement du signal
ou les calculs distribus sur les nombres flottants.

Utilis pour la simulation de protein folding


(maladies prion), la simulation molculaire, et
d'une manire gnrale des applications mdicales.
Exemple: clusters Beowulf (1998)
2-5

Architecture logique dfinissant un moyen de connecter


plusieurs ordinateurs personnels entre eux pour
l'excution de tches distribues sur un rseau local.
Une machine matre distribue les tches une srie de
machines esclaves.

Gnralement concrtis via plusieurs machines sous


GNU/Linux utilisant des interfaces standardises.
L'ensemble du cluster ainsi form apparat au niveau
du serveur matre comme une seule et mme machine.

Permet tout un chacun d'obtenir un systme de calcul


distribu hautes performances partir d'un matriel
peu onreux.

La NASA utilise ainsi un cluster Beowulf.


Exemple: SETI@Home/BOINC
2-6

A l'origine, un des premiers logiciels permettre


le calcul distribu via l'utilisation des ordinateurs
de volontaires tout autour du monde.

Objectif: dtecter d'ventuels signes de


civilisations extra-terrestres en analysant des
signaux radios reus par l'observatoire
Arecibo au Porto Rico.

Architecture et protocoles de communication


ensuite standardiss et mis disposition sous
la forme d'un framework, BOINC, donnant lieu
de nombreux autres projets (Einstein@Home,
Folding@Home, etc.).
Remarque: GPUGRID utilise dsormais lui
aussi le framework BOINC.
Conclusions
2-7
Pour l'excution de tches distribues distantes via la mise disposition de
machines tout autour du monde par des volontaires, la cration du framework
BOINC a apport une rponse efficace de nombreux projets universitaires et
scientifiques exploitant aujourd'hui la technologie.

Cependant, de nombreuses universits et entreprises ont des besoins d'excution


locale de tches paralllisables sur des donnes massives. Les solutions qui
taient disponibles jusqu'ici:
Des super calculateurs classiques comme Blue Gene: trs onreux, souvent trop
puissants par rapport aux besoins requis, rservs aux grands groupes industriels.
Des solutions dveloppes en interne: investissement initial trs consquent,
ncessite des comptences et une rigueur coteuses.
Architecture Beowulf: un dbut de rponse, mais complexe mettre en uvre pour
beaucoup d'entreprises ou petites universits, et ncessitant l aussi un
investissement initial assez consquent.
Le problme
2-8

Le problme qui se posait jusqu'ici pour ce cas d'usage:

Avoir un framework dj disponible, facile dployer, et qui permette


l'excution de tches paralllisables et le support et le suivi de ces
tches de manire rapide et simple mettre en uvre.

L'ide tant d'avoir un outil off the shelf qui puisse tre install et configur
rapidement au sein d'une entreprise/d'une universit et qui permettre des
dveloppeurs d'excuter des tches distribues avec un minimum de formation
requise.

L'outil en question devant tre facile dployer, simple supporter, et pouvant


permettre la cration de clusters de taille variables extensibles tout moment.
La solution: Apache Hadoop
2-9

Avantages:
Projet de la fondation Apache Open Source, composants compltement ouverts,
tout le monde peut participer.

Modle simple pour les dveloppeurs: il suffit de dvelopper des tches map-reduce,
depuis des interfaces simples accessibles via des librairies dans des langages
multiples (Java, Python,C/C++...).

Dployable trs facilement (paquets Linux pr-configurs), configuration trs simple


elle aussi.

S'occupe de toutes les problmatiques lies au calcul distribu, comme laccs et le


partage des donnes, la tolrance aux pannes, ou encore la rpartition des tches
aux machines membres du cluster: le programmeur a simplement s'occuper du
dveloppement logiciel pour l'excution de la tche.
Historique (1/2)
2-10

- 2002: Doug Cutting (directeur archive.org) et Mike Cafarella (tudiant) dveloppent


Nutch, un moteur de recherche Open Source exploitant le calcul distribu.
L'implmentation peut tourner seulement sur quelques machines et a de multiples
problmes, notamment en ce qui concerne l'accs et le partage de fichiers.

- 2003/2004: le dpartement de recherche de Google publie deux whitepapers, le


premier sur GFS (un systme de fichier distribu) et le second sur le paradigme
Map/Reduce pour le calcul distribu.

- 2004: Doug Cutting et Mike Cafarella dveloppent un framework (encore assez


primitif) inspir des papers de Google et portent leur projet Nutch sur ce framework.

- 2006: Doug Cutting (dsormais chez Yahoo) est en charge d'amliorer l'indexation
du moteur de recherche de Yahoo. Il exploite le framework ralis prcdemment...
Historique (2/2)
2-11

et cr une nouvelle version amliore du framework en tant que projet Open


Source de la fondation Apache, qu'il nomme Hadoop (le nom d'un lphant en
peluche de son fils).

A l'poque, Hadoop est encore largement en


dveloppement un cluster pouvait alors comporter au
maximum 5 20 machines, etc.

- 2008: le dveloppement est maintenant trs abouti, et


Hadoop est exploit par le moteur de recherche de Yahoo
Ainsi que par de nombreuses autres divisions de
l'entreprise.

- 2011: Hadoop est dsormais utilis par de nombreuses autres entreprises et des
universits, et le cluster Yahoo comporte 42000 machines et des centaines de peta-
octets d'espace de stockage.
Qui utilise Hadoop
2-12

et des centaines d'entreprises et universits travers le monde.


Une technologie en plein essort
2-13

De plus en plus de donnes produites par des systmes d'information de plus en


plus nombreux. Ces donnes doivent toutes tre analyses, corrles, etc. et
Hadoop offre une solution idale et facile implmenter au problme.

Pour le public, l'informatisation au sein des villes (smart cities) et des


administrations se dveloppe de plus en plus et va produire des quantits
massives de donnes.

le domaine de recherche/industriel autour de la gestion et de l'analyse de ces


donnes et de Hadoop et les technologies associes est communment dsign
sous l'expression Big Data.

Estimations IDC: croissance de 60% par an de l'industrie Big Data, pour un


march de 813 millions de dollars en 2016 uniquement pour la vente de logiciels
autour de Hadoop.
3 Le modle Map/Reduce
Prsentation
3-1

Pour excuter un problme large de manire distribu, il faut pouvoir dcouper le


problme en plusieurs problmes de taille rduite excuter sur chaque machine
du cluster (stratgie algorithmique dite du divide and conquer / diviser pour
rgner).

De multiples approches existent et ont exist pour cette division d'un problme en
plusieurs sous-tches.

MapReduce est un paradigme (un modle) visant gnraliser les approches


existantes pour produire une approche unique applicable tous les problmes.

MapReduce existait dj depuis longtemps, notamment dans les langages


fonctionnels (Lisp, Scheme), mais la prsentation du paradigme sous une forme
rigoureuse, gnralisable tous les problmes et oriente calcul distribu est
attribuable un whitepaper issu du dpartement de recherche de Google publi en
2004 (MapReduce: Simplified Data Processing on Large Clusters).
Prsentation
3-2

MapReduce dfinit deux oprations distinctes effectuer sur les


donnes d'entre:
La premire, MAP, va transformer les donnes d'entre en une srie de couples
clef/valeur. Elle va regrouper les donnes en les associant des clefs, choisies de
telle sorte que les couples clef/valeur aient un sens par rapport au problme
rsoudre. Par ailleurs, cette opration doit tre paralllisable: on doit pouvoir
dcouper les donnes d'entre en plusieurs fragments, et faire excuter l'opration
MAP chaque machine du cluster sur un fragment distinct.

La seconde, REDUCE, va appliquer un traitement toutes les valeurs de chacune


des clefs distinctes produite par l'opration MAP. Au terme de l'opration REDUCE,
on aura un rsultat pour chacune des clefs distinctes.
Ici, on attribuera chacune des machines du cluster une des clefs uniques
produites par MAP, en lui donnant la liste des valeurs associes la clef. Chacune
des machines effectuera alors l'opration REDUCE pour cette clef.
Prsentation
3-3

On distingue donc 4 tapes distinctes dans un traitement MapReduce:


Dcouper (split) les donnes d'entre en plusieurs fragments.

Mapper chacun de ces fragments pour obtenir des couples (clef; valeur).

Grouper (shuffle) ces couples (clef; valeur) par clef.

Rduire (reduce) les groupes indexs par clef en une forme finale, avec une
valeur pour chacune des clefs distinctes.

En modlisant le problme rsoudre de la sorte, on le rend


paralllisable chacune de ces tches l'exception de la premire
seront effectues de manire distribue.
Prsentation
3-4

Pour rsoudre un problme via la mthodologie MapReduce avec


Hadoop, on devra donc:
Choisir une manire de dcouper les donnes d'entre de telle sorte que
l'opration MAP soit paralllisable.

Dfinir quelle CLEF utiliser pour notre problme.

crire le programme pour l'opration MAP.

Ecrire le programme pour l'opration REDUCE.

et Hadoop se chargera du reste (problmatiques calcul distribu,


groupement par clef distincte entre MAP et REDUCE, etc.).
Exemple concret (1/8)
3-5

Imaginons qu'on nous donne un texte crit en langue Franaise. On


souhaite dterminer pour un travail de recherche quels sont les mots les
plus utiliss au sein de ce texte (exemple Hadoop trs rpandu).

Ici, nos donnes d'entre sont constitues du contenu du texte.

Premire tape: dterminer une manire de dcouper (split) les donnes


d'entre pour que chacune des machines puisse travailler sur une partie
du texte.

Notre problme est ici trs simple on peut par exemple dcider de
dcouper les donnes d'entre ligne par ligne. Chacune des lignes du
texte sera un fragment de nos donnes d'entre.
Exemple concret (2/8)
3-6

Nos donnes d'entre (le texte):

Celui
Celui qui
qui croyait
croyait au
au ciel
ciel
Celui
Celui qui
qui n'y
n'y croyait
croyait pas
pas
[]
[] (Louis Aragon, La rose et le
Fou
Fou qui
qui fait
fait le
le dlicat
dlicat Rsda, 1943, fragment)
Fou
Fou qui
qui songe
songe ses
ses querelles
querelles

Pour simplifier les choses, on va avant le dcoupage supprimer toute


ponctuation et tous les caractres accentus. On va galement passer
l'intgralit du texte en minuscules.
Exemple concret (3/8)
3-7

Aprs dcoupage:

celui
celui qui
qui croyait
croyait au
au ciel
ciel
celui
celui qui
qui ny
ny croyait
croyait pas
pas
fou
fou qui
qui fait
fait le
le delicat
delicat
fou
fou qui
qui songe
songe aa ses
ses querelles
querelles

on obtient 4 fragments depuis nos donnes d'entre.


Exemple concret (4/8)
3-8

On doit dsormais dterminer la clef utiliser pour notre opration MAP,


et crire le code de l'opration MAP elle-mme.

Puisqu'on s'intresse aux occurrences des mots dans le texte, et qu'


terme on aura aprs l'opration REDUCE un rsultat pour chacune des
clefs distinctes, la clef qui s'impose logiquement dans notre cas est: le
mot-lui mme.

Quand notre opration MAP, elle sera elle aussi trs simple: on va
simplement parcourir le fragment qui nous est fourni et, pour chacun
des mots, gnrer le couple clef/valeur: (MOT; 1). La valeur indique ici
loccurrence pour cette clef- puisqu'on a crois le mot une fois, on
donne la valeur 1.
Exemple concret (5/8)
3-9

Le code de notre opration MAP sera donc (ici en pseudo code):


POUR
POUR MOT
MOT dans
dans LIGNE,
LIGNE, FAIRE:
FAIRE:
GENERER
GENERER COUPLE
COUPLE (MOT;
(MOT; 1)
1)

Pour chacun de nos fragments, les couples (clef; valeur) gnrs seront
donc:
celui
celui qui
qui croyait
croyait au
au ciel
ciel (celui;1)
(celui;1) (qui;1)
(qui;1) (croyait;1)
(croyait;1) (au;1)
(au;1) (ciel;1)
(ciel;1)
celui
celui qui
qui ny
ny croyait
croyait pas
pas (celui;1)
(celui;1) (qui;1)
(qui;1) (ny;1)
(ny;1) (croyait;1)
(croyait;1) (pas;1)
(pas;1)
fou
fou qui
qui fait
fait le
le delicat
delicat (fou;1)
(fou;1) (qui;1)
(qui;1) (fait;1)
(fait;1) (le;1)
(le;1) (delicat;1)
(delicat;1)
fou
fou qui
qui songe
songe aa ses
ses querelles
querelles (fou;1)
(fou;1) (qui;1)
(qui;1) (songe;1)
(songe;1) (a;1)
(a;1) (ses;1)
(ses;1)
(querelles;1)
(querelles;1)
Exemple concret (6/8)
3-10

Une fois notre opration MAP effectue (de manire distribue), Hadoop
groupera (shuffle) tous les couples par clef commune.

Cette opration est effectue automatiquement par Hadoop. Elle est, l aussi,
effectue de manire distribue en utilisant un algorithme de tri distribu, de
manire rcursive. Aprs son excution, on obtiendra les 15 groupes suivants:

(celui;1)
(celui;1) (celui;1)
(celui;1) (fou;1)
(fou;1) (fou;1)
(fou;1)
(qui;1)
(qui;1) (qui;1)
(qui;1) (qui;1)
(qui;1) (qui;1)
(qui;1) (fait;1)
(fait;1) (le;1)
(le;1)
(croyait;1)
(croyait;1) (croyait;1)
(croyait;1) (delicat;1)
(delicat;1) (songe;1)
(songe;1)
(au;1)
(au;1) (ny;1)
(ny;1) (a;1) (ses;1)
(a;1) (ses;1)
(ciel;1)
(ciel;1) (pas;1)
(pas;1) (querelles;1)
(querelles;1)
Exemple concret (7/8)
3-11

Il nous reste crer notre opration REDUCE, qui sera appele pour
chacun des groupes/clef distincte.

Dans notre cas, elle va simplement consister additionner toutes les


valeurs lies la clef spcifie:

TOTAL=0
TOTAL=0
POUR
POUR COUPLE
COUPLE dans
dans GROUPE,
GROUPE, FAIRE:
FAIRE:
TOTAL=TOTAL+1
TOTAL=TOTAL+1
RENVOYER
RENVOYER TOTAL
TOTAL
Exemple concret (8/8)
3-12

Une fois l'opration REDUCE effectue, on obtiendra donc une valeur


unique pour chaque clef distincte. En loccurrence, notre rsultat sera:
qui:
qui: 44
celui:
On constate que le mot le plus utilis dans
celui: 22
croyait: notre texte est qui, avec 4 occurrences,
croyait: 22
fou:
fou: 22 suivi de celui, croyait et fou, avec
au:
au: 11 2 occurrences chacun.
ciel:
ciel: 11
ny:
ny: 11
pas:
pas: 11
fait:
fait: 11
[]
[]
Exemple concret - conclusion
3-13

Notre exemple est videmment trivial, et son excution aurait t


instantane mme sur une machine unique, mais il est d'ores et dj
utile: on pourrait tout fait utiliser les mmes implmentations de MAP
et REDUCE sur l'intgralit des textes d'une bibliothque Franaise, et
obtenir ainsi un bon chantillon des mots les plus utiliss dans la
langue Franaise.

Lintrt du modle MapReduce est qu'il nous suffit de dvelopper les


deux oprations rellement importantes du traitement: MAP et REDUCE,
et de bnficier automatiquement de la possibilit d'effectuer le
traitement sur un nombre variable de machines de manire distribue.
Schma gnral
3-14
Exemple Statistiques web
3-15

Un autre exemple: on souhaite compter le nombre de visiteurs sur


chacune des pages d'un site Internet.
On dispose des fichiers de logs sous la forme suivante:
/index.html
/index.html [19/Oct/2013:18:45:03
[19/Oct/2013:18:45:03 +0200]
+0200]
/contact.html
/contact.html [19/Oct/2013:18:46:15
[19/Oct/2013:18:46:15 +0200]
+0200]
/news.php?id=5
/news.php?id=5 [24/Oct/2013:18:13:02
[24/Oct/2013:18:13:02 +0200]
+0200]
/news.php?id=4
/news.php?id=4 [24/Oct/2013:18:13:12
[24/Oct/2013:18:13:12 +0200]
+0200]
/news.php?id=18
/news.php?id=18 [24/Oct/2013:18:14:31
[24/Oct/2013:18:14:31 +0200]
+0200]
...etc...
...etc...

Ici, notre clef sera par exemple l'URL daccs la page, et nos
oprations MAP et REDUCE seront exactement les mmes que celles qui
viennent d'tre prsentes: on obtiendra ainsi le nombre de vue pour
chaque page distincte du site.
Exemple Graphe social
3-16

Un autre exemple: on administre un rseau social comportant des


millions d'utilisateurs.
Pour chaque utilisateur, on a dans notre base de donnes la liste des
utilisateurs qui sont ses amis sur le rseau (via une requte SQL).

On souhaite afficher quand un utilisateur va sur la page d'un autre


utilisateur une indication Vous avez N amis en commun.

On ne peut pas se permettre d'effectuer une srie de requtes SQL


chaque fois que la page est accde (trop lourd en traitement). On va
donc dvelopper des programmes MAP et REDUCE pour cette opration
et excuter le traitement toutes les nuits sur notre base de donnes, en
stockant le rsultat dans une nouvelle table.
Exemple Graphe social
3-17

Ici, nos donnes d'entre sous la forme Utilisateur => Amis:


AA =>
=> B,
B, C,
C, DD
BB =>
=> A,
A, C,
C, D,
D, EE
CC =>
=> A,
A, B,
B, D,
D, EE
DD =>
=> A,
A, B,
B, C,
C, EE
EE =>
=> B,
B, C,
C, DD

Puisqu'on est intress par l'information amis en commun entre deux


utilisateurs et qu'on aura terme une valeur par clef, on va choisir
pour clef la concatnation entre deux utilisateurs.
Par exemple, la clef A-B dsignera les amis en communs des
utilisateurs A et B.
On peut segmenter les donnes d'entre l aussi par ligne.
Exemple Graphe social
3-18

Notre opration MAP va se contenter de prendre la liste des amis fournie


en entre, et va gnrer toutes les clefs distinctes possibles partir de
cette liste. La valeur sera simplement la liste d'amis, telle quelle.

On fait galement en sorte que la clef soit toujours trie par ordre
alphabtique (clef B-A sera exprime sous la forme A-B).

Ce traitement peut paratre contre-intuitif, mais il va terme nous


permettre d'obtenir, pour chaque clef distincte, deux couples
(clef;valeur): les deux listes d'amis de chacun des utilisateurs qui
composent la clef.
Exemple Graphe social
3-19

Le pseudo code de notre opration MAP:


UTILISATEUR
UTILISATEUR == [PREMIERE
[PREMIERE PARTIE
PARTIE DE
DE LA
LA LIGNE]
LIGNE]
POUR
POUR AMI
AMI dans
dans [RESTE
[RESTE DE
DE LA
LA LIGNE],
LIGNE], FAIRE:
FAIRE:
SI
SI UTILISATEUR
UTILISATEUR << AMI:
AMI:
CLEF
CLEF == UTILISATEUR+"-"+AMI
UTILISATEUR+"-"+AMI
SINON:
SINON:
CLEF
CLEF == AMI+"-"+UTILISATEUR
AMI+"-"+UTILISATEUR
GENERER
GENERER COUPLE
COUPLE (CLEF;
(CLEF; [RESTE
[RESTE DE
DE LA
LA LIGNE])
LIGNE])

Par exemple, pour la premire ligne: AA =>


=> B,
B, C,
C, DD
On obtiendra les couples (clef;valeur):
("A-B";
("A-B"; "B
"B CC D")
D") ("A-C";
("A-C"; "B
"B CC D")
D") ("A-D";
("A-D"; "B
"B CC D")
D")
Exemple Graphe social
3-20

Pour la seconde ligne: BB =>


=> A,
A, C,
C, D,
D, EE
On obtiendra ainsi:
("A-B";
("A-B"; "A
"A CC DD E")
E") ("B-C";
("B-C"; "A
"A CC DD E")
E") ("B-D";
("B-D"; "A
"A CC DD E")
E")

("B-E";
("B-E"; "A
"A CC DD E")
E")

Pour la troisime ligne: CC =>


=> A,
A, B,
B, D,
D, EE
On aura:
("A-C";
("A-C"; "A
"A BB DD E")
E") ("B-C";
("B-C"; "A
"A BB DD E")
E") ("C-D";
("C-D"; "A
"A BB DD E")
E")

("C-E";
("C-E"; "A
"A BB DD E")
E")
...et ainsi de suite pour nos 5 lignes d'entre.
Exemple Graphe social
3-21

Une fois l'opration MAP effectue, Hadoop va rcuprer les couples


(clef;valeur) de tous les fragments et les grouper par clef distincte. Le
rsultatsur la base de nos donnes d'entre:
Pour
Pour la
la clef
clef "A-B":
"A-B": valeurs
valeurs "A
"A CC DD E"
E" et
et "B
"B CC D"
D"
Pour
Pour la
la clef
clef "A-C":
"A-C": valeurs
valeurs "A
"A BB DD E"
E" et
et "B
"B CC D"
D"
Pour
Pour la
la clef
clef "A-D":
"A-D": valeurs
valeurs "A
"A BB CC E"
E" et
et "B
"B CC D"
D"
Pour
Pour la
la clef
clef "B-C":
"B-C": valeurs
valeurs "A
"A BB DD E"
E" et
et "A
"A CC DD E"
E"
Pour
Pour la
la clef
clef "B-D":
"B-D": valeurs
valeurs "A
"A BB CC E"
E" et
et "A
"A CC DD E"
E"
Pour
Pour la
la clef
clef "B-E":
"B-E": valeurs
valeurs "A
"A CC DD E"
E" et
et "B
"B CC D"
D"
Pour
Pour la
la clef
clef "C-D":
"C-D": valeurs
valeurs "A
"A BB CC E"
E" et
et "A
"A BB DD E"
E"
Pour
Pour la
la clef
clef "C-E":
"C-E": valeurs
valeurs "A
"A BB DD E"
E" et
et "B
"B CC D"
D"
Pour
Pour la
la clef
clef "D-E":
"D-E": valeurs
valeurs "A
"A BB CC E"
E" et
et "B
"B CC D"
D"
on obtient bien, pour chaque clef USER1-USER2, deux listes d'amis: les
amis de USER1 et ceux de USER2.
Exemple Graphe social
3-22

Il nous faut enfin crire notre programme REDUCE.


Il va recevoir en entre toutes les valeurs associes une clef. Son rle
va tre trs simple: dterminer quels sont les amis qui apparaissent
dans les listes (les valeurs) qui nous sont fournies. Pseudo-code:
LISTE_AMIS_COMMUNS=[]
LISTE_AMIS_COMMUNS=[] //
// Liste
Liste vide
vide au
au dpart.
dpart.
SI
SI LONGUEUR(VALEURS)!=2,
LONGUEUR(VALEURS)!=2, ALORS:
ALORS: //
// Ne
Ne devrait
devrait pas
pas se
se produire.
produire.
RENVOYER
RENVOYER ERREUR
ERREUR
SINON:
SINON:
POUR
POUR AMI
AMI DANS
DANS VALEURS[0],
VALEURS[0], FAIRE:
FAIRE:
SI
SI AMI
AMI EGALEMENT
EGALEMENT PRESENT
PRESENT DANS
DANS VALEURS[1],
VALEURS[1], ALORS:
ALORS:
//
// Prsent
Prsent dans
dans les
les deux
deux listes
listes d'amis,
d'amis, on
on l'ajoute.
l'ajoute.
LISTE_AMIS_COMMUNS+=AMI
LISTE_AMIS_COMMUNS+=AMI
RENVOYER
RENVOYER LISTE_AMIS_COMMUNS
LISTE_AMIS_COMMUNS
Exemple Graphe social
3-23

Aprs excution de l'opration REDUCE pour les valeurs de chaque clef unique,
on obtiendra donc, pour une clef A-B, les utilisateurs qui apparaissent dans
la liste des amis de A et dans la liste des amis de B. Autrement dit, on obtiendra
la liste des amis en commun des utilisateurs A et B. Le rsultat:

"A-B":
"A-B": "C,
"C, D"
D"
"A-C": "B, D" On sait ainsi que A et B ont pour amis communs
"A-C": "B, D"
"A-D": "B, C" les utilisateurs C et D, ou encore que B et C ont
"A-D": "B, C"
"B-C": "A, D, E" pour amis communs les utilisateurs A, D et E.
"B-C": "A, D, E"
"B-D":
"B-D": "A,
"A, C,
C, E"
E"
"B-E":
"B-E": "C,
"C, D"
D"
"C-D":
"C-D": "A,
"A, B,
B, E"
E"
"C-E":
"C-E": "B,
"B, D"
D"
"D-E":
"D-E": "B,
"B, C"
C"
Conclusion
3-24

En utilisant le modle MapReduce, on a ainsi pu crer deux programmes trs


simples (nos programmes MAP et REDUCE) de quelques lignes de code
seulement, qui permettent d'effectuer un traitement somme toute assez
complexe.

Mieux encore, notre traitement est paralllisable: mme avec des dizaines de
millions d'utilisateurs, du moment qu'on a assez de machines au sein du cluster
Hadoop, le traitement sera effectu rapidement. Pour aller plus vite, il nous
suffit de rajouter plus de machines.

Pour notre rseau social, il suffira d'effectuer ce traitement toutes les nuits
heure fixe, et de stocker les rsultats dans une table.
Ainsi, lorsqu'un utilisateur visitera la page d'un autre utilisateur, un seul
SELECT dans la base de donnes suffira pour obtenir la liste des amis en
commun avec un poids en traitement trs faible pour le serveur.
4 HDFS
Prsentation
4-1

Pour stocker les donnes en entre de nos tches Hadoop, ainsi que
les rsultats de nos traitements, on va utiliser HDFS:

Hadoop Distributed FileSystem

Il s'agit du systme de fichier standard de Hadoop - au mme sens que


les systmes de fichiers FAT32, NTFS ou encore Ext3FS, la diffrence
qu'il est videmment distribu.

Remarque: Hadoop peut et c'est le cas le plus frquent galement


communiquer directement avec une base de donnes (qu'elle soit
classique comme MySQL ou PostGreSQL ou plus exotique comme
MongoDB ou VoltDB). Ce mode d'intgration passe par le biais de ponts
d'interconnexion, qui seront abords plus loin dans le cours.
Prsentation
4-2

Les caractristiques de HDFS:

Il est distribu: les donnes sont rparties sur tout le cluster de machines.

Il est rpliqu: si une des machines du cluster tombe en panne, aucune


donne n'est perdue.

Il est conscient du positionnement des serveurs sur les racks. HDFS va


rpliquer les donnes sur des racks diffrents, pour tre certain qu'une
panne affectant un rack de serveurs entier (par exemple un incident
d'alimentation) ne provoque pas non plus de perte de donnes, mme
temporaire. Par ailleurs, HDFS peut aussi optimiser les transferts de
donnes pour limiter la distance parcourir pour la rplication (et
donc les temps de transfert).
Prsentation
4-3

Par ailleurs, le systme de gestion des tches de Hadoop, qui distribue les
fragments de donnes d'entre au cluster pour l'opration MAP ou encore les
couples (clef;valeur) pour l'opration REDUCE, est en communication constante
avec HDFS.

Il peut donc optimiser le positionnement des donnes traiter de telle sorte


qu'une machine puisse accder aux donnes relatives la tche qu'elle doit
effectuer localement, sans avoir besoin de les demander une autre machine.

Ainsi, si on a par exemple 6 fragments en entre et 2 machines sur le cluster,


Hadoop estimera que chacune des 2 machines traitera probablement 3
fragments chacune, et positionnera les fragments/distribuera les tches de telle
sortes que les machines y aient accs directement, sans avoir effectuer
daccs sur le rseau.
Architecture
4-4
HDFS repose sur deux serveurs (des daemons):

Le NameNode, qui stocke les informations relatives aux noms de fichiers.


C'est ce serveur qui, par exemple, va savoir que le fichier livre_5321 dans
le rpertoire data_input comporte 58 blocs de donnes, et qui sait o ils se
trouvent. Il y a un seul NameNode dans tout le cluster Hadoop.

Le DataNode, qui stocke les blocs de donnes eux-mmes. Il y a un DataNode


pour chaque machine au sein du cluster, et ils sont en communication
constante avec le NameNode pour recevoir de nouveaux blocs, indiquer quels
blocs sont contenus sur le DataNode, signaler des erreurs, etc...

Par dfaut, les donnes sont divises en blocs de 64KB (configurable).


Hadoop est inspir de GFS, un systme de fichier distribu conu par Google.
L'implmentation de HDFS a son origine dans un whitepaper issu du
dpartement de recherche de Google (The Google File System, 2003).
criture d'un fichier
4-5
Si on souhaite crire un fichier au sein de HDFS, on va utiliser la commande
principale de gestion de Hadoop: hadoop, avec l'option fs. Mettons qu'on
souhaite stocker le fichier page_livre.txt sur HDFS.

Le programme va diviser le fichier en blocs de 64KB (ou autre, selon la


configuration) supposons qu'on ait ici 2 blocs. Il va ensuite annoncer au
NameNode: Je souhaite stocker ce fichier au sein de HDFS, sous le nom
page_livre.txt.

Le NameNode va alors indiquer au programme qu'il doit stocker le bloc 1 sur le


DataNode numro 3, et le bloc 2 sur le DataNode numro 1.

Le client hadoop va alors contacter directement les DataNodes concerns et


leur demander de stocker les deux blocs en question.
Par ailleurs, les DataNodes s'occuperont en informant le NameNode de
rpliquer les donnes entre eux pour viter toute perte de donnes.
criture d'un fichier
4-6
Lecture d'un fichier
4-7

Si on souhaite lire un fichier au sein de HDFS, on utilise l aussi le client


Hadoop. Mettons qu'on souhaite lire le fichier page_livre.txt.

Le client va contacter le NameNode, et lui indiquer Je souhaite lire le fichier


page_livre.txt. Le NameNode lui rpondra par exemple Il est compos de
deux blocs. Le premier est disponible sur le DataNode 3 et 2, le second sur le
DataNode 1 et 3.

L aussi, le programme contactera les DataNodes directement et leur


demandera de lui transmettre les blocs concerns. En cas d'erreur/non rponse
d'un des DataNode, il passe au suivant dans la liste fournie par le NameNode.
Lecture d'un fichier
4-8
La commande hadoop fs
4-9

Comme indiqu plus haut, la commande permettant de stocker ou extraire des


fichiers de HDFS est l'utilitaire console hadoop, avec l'option fs.
Il rplique globalement les commandes systmes standard Linux, et est trs
simple utiliser:

hadoop fs -put livre.txt /data_input/livre.txt


Pour stocker le fichier livre.txt sur HDFS dans le rpertoire /data_input.
hadoop fs -get /data_input/livre.txt livre.txt
Pour obtenir le fichier /data_input/livre.txt de HDFS et le stocker dans le fichier
local livre.txt.
hadoop fs -mkdir /data_input
Pour crer le rpertoire /data_input
hadoop fs -rm /data_input/livre.txt
Pour supprimer le fichier /data_input/livre.txt

d'autres commandes usuelles: -ls, -cp, -rmr, -du, etc...


Remarques
4-10

La gestion du stockage est assure par les daemons Hadoop on a pas se


soucier d'o sont stockes les donnes.

Hadoop rplique lui-mme les donnes: les fichiers sont disponibles tout
moment sur plusieurs DataNodes, et si une machine tombe en panne, on a
toujours accs aux donnes grce la rplication.

Si les donnes proviennent d'une base de donnes (par exemple dans le cas
de l'exemple des amis en commun vu prcdemment), on sera oblig
avant d'excuter le traitement Hadoop d'extraire les donnes de la base via
des requtes SQL et de les stocker sur HDFS. De mme, pour rcuprer les
rsultats au sein d'une base de donnes, on devra extraire le ou les fichiers
des rsultats depuis HDFS, et les r-importer dans la base de donnes.
C'est dans ce cas que les bridges de connexion aux bases de donnes
voques plus haut prennent tout leur sens.
Inconvnients
4-11

Le NameNode est unique on ne peut pas en avoir plusieurs. En


consquence, si la machine hbergeant le NameNode tombe en panne, le
cluster est incapable d'accder aux fichiers le temps que le problme soit
corrig. Ce problme est partiellement mitig dans les versions rcentes
(beta) de Hadoop, avec un BackupNameNode qui peut tre bascul
manuellement en cas de problme. Une implmentation est en cours pour un
basculement automatique.

Le systme de fichier ne peut pas tre mont de manire classique. Pour y


accder, on est oblig de passer par l'utilitaire hadoop (ou par des APIs).
Remarque: ce n'est plus entirement vrai plusieurs projets FUSE existent
dsormais pour assurer des points de montage classiques.

Enfin, HDFS est optimis pour des lecture concurrentes: crire de manire
concurrente est nettement moins performant.
Alternatives
4-12

On a indiqu plus haut qu'on peut galement brancher Hadoop directement par
le biais de ponts sur une base de donnes pour en extraire des donnes
d'entre/y stocker des rsultats. Il existe galement des alternatives HDFS qui
conservent une logique de systmes de fichiers. Par exemple:

Amazon S3 filesystem: le systme de fichier Amazon utilis sur les solutions


de cloud de amazon.com. N'est pas conscient du positionnement par rapport
aux racks.

CloudStore: une alternative propose par Kosmix. Conscient des racks.

FTP: une alternative haut niveau qui transfre les blocs manuellement via FTP.
Peu performant.

HTTP/HTTPS en lecture seule.


5 L'architecture Hadoop
Prsentation
5-1

Comme pour HDFS, la gestion des tches de Hadoop se base sur deux serveurs
(des daemons):

Le JobTracker, qui va directement recevoir la tche excuter (un .jar Java),


ainsi que les donnes d'entres (nom des fichiers stocks sur HDFS) et le
rpertoire o stocker les donnes de sortie (toujours sur HDFS). Il y a un seul
JobTracker sur une seule machine du cluster Hadoop. Le JobTracker est en
communication avec le NameNode de HDFS et sait donc o sont les donnes.

Le TaskTracker, qui est en communication constante avec le JobTracker et va


recevoir les oprations simples effectuer (MAP/REDUCE) ainsi que les blocs
de donnes correspondants (stocks sur HDFS). Il y a un TaskTracker sur
chaque machine du cluster.
Prsentation
5-2

Comme le JobTracker est conscient de la position des donnes (grce au


NameNode), il peut facilement dterminer les meilleures machines
auxquelles attribuer les sous-tches (celles o les blocs de donnes
correspondants sont stocks).

Pour effectuer un traitement Hadoop, on va donc stocker nos donnes


d'entre sur HDFS, crer un rpertoire o Hadoop stockera les rsultats
sur HDFS, et compiler nos programmes MAP et REDUCE au sein d'un .jar
Java.

On soumettra alors le nom des fichiers d'entre, le nom du rpertoire des


rsultats, et le .jar lui-mme au JobTracker: il s'occupera du reste (et
notamment de transmettre les programmes MAP et REDUCE aux serveurs
TaskTracker des machines du cluster).
Prsentation
5-3
Le JobTracker
5-4

Le droulement de l'excution d'une tche Hadoop suit les tapes suivantes du


point de vue du JobTracker:

1. Le client (un outil Hadoop console) va soumettre le travail effectuer au


JobTracker: une archive java .jar implmentant les oprations Map et Reduce. Il
va galement soumettre le nom des fichiers d'entre, et l'endroit o stocker les
rsultats.

2. Le JobTracker communique avec le NameNode HDFS pour savoir o se


trouvent les blocs correspondant aux noms de fichiers donns par le client.

3. Le JobTracker, partir de ces informations, dtermine quels sont les nuds


TaskTracker les plus appropris, c'est dire ceux qui contiennent les donnes
sur lesquelles travailler sur la mme machine, ou le plus proche possible
(mme rack/rack proche).
Le JobTracker
5-5
4. Pour chaque morceau des donnes d'entre, le JobTracker envoie au
TaskTracker slectionn le travail effectuer (MAP/REDUCE, code Java) et les
blocs de donnes correspondant.

5. Le JobTracker communique avec les nuds TaskTracker en train d'excuter


les tches. Ils envoient rgulirement un heartbeat, un message signalant
qu'ils travaillent toujours sur la sous-tche reue. Si aucun heartbeat n'est reu
dans une priode donne, le JobTracker considre la tche comme ayant
choue et donne le mme travail effectuer un autre TaskTracker.

6. Si par hasard une tche choue (erreur java, donnes incorrectes, etc.), le
TaskTracker va signaler au JobTracker que la tche n'a pas p tre excut. Le
JobTracker va alors dcider de la conduite adopter: redonner la sous-tche
un autre TaskTracker, demander au mme TaskTracker de r-essayer, marquer
les donnes concernes comme invalides, etc. il pourra mme blacklister le
TaskTracker concern comme non-fiable dans certains cas.
Le JobTracker
5-6

7. Une fois que toutes les oprations envoyes aux TaskTracker (MAP +
REDUCE) ont t effectues et confirmes comme effectues par tous les
nuds, le JobTracker marque la tche comme effectue. Des informations
dtailles sont disponibles (statistiques, TaskTracker ayant pos problme,
etc.).

Par ailleurs, on peut galement obtenir tout moment de la part du JobTracker


des informations sur les tches en train d'tre effectues: tape actuelle (MAP,
SHUFFLE, REDUCE), pourcentage de compltion, etc.

La soumission du .jar, l'obtention de ces informations, et d'une manire


gnrale toutes les oprations lies Hadoop s'effectuent avec le mme
unique client console vu prcdemment: hadoop (avec d'autres options que
l'option fs vu prcdemment).
Le TaskTracker
5-7

Le TaskTracker dispose d'un nombre de slots d'excution. A chaque


slot correspond une tche excutable (configurable). Ainsi, une machine
ayant par exemple un processeur 8 curs pourrait avoir 16 slots
d'opration configurs.

Lorsqu'il reoit une nouvelle tche effectuer (MAP, REDUCE, SHUFFLE)


depuis le JobTracker, le TaskTracker va dmarrer une nouvelle instance de
Java avec le fichier .jar fourni par le JobTracker, en appelant l'opration
correspondante.

Une fois la tche dmarre, il enverra rgulirement au JobTracker ses


messages heartbeats. En dehors d'informer le JobTracker qu'il est
toujours fonctionnels, ces messages indiquent galement le nombre de
slots disponibles sur le TaskTracker concern.
Le TaskTracker
5-8

Lorsqu'une sous-tche est termine, le TaskTracker envoie un message


au JobTracker pour l'en informer, que la tche se soit bien droule ou
non (il indique videmment le rsultat au JobTracker).
Remarques
5-9

De manire similaire au NameNode de HDFS, il n'y a qu'un seul


JobTracker et s'il tombe en panne, le cluster tout entier ne peut plus
effectuer de tches. L aussi, des rsolutions aux problme sont prvues
dans la roadmap Hadoop, mais pas encore disponibles.

Gnralement, on place le JobTracker et le NameNode HDFS sur la mme


machine (une machine plus puissante que les autres), sans y placer de
TaskTracker/DataNode HDFS pour limiter la charge. Cette machine
particulire au sein du cluster (qui contient les deux gestionnaires, de
tches et de fichiers) est communment appele le nud matre (
Master Node). Les autres nuds (contenant TaskTracker + DataNode)
sont communment appels nuds esclaves (slave node).
Remarques
5-10

Mme si le JobTracker est situ sur une seule machine, le client qui
envoie la tche au JobTracker initialement peut tre excut sur
n'importe quelle machine du cluster comme les TaskTracker sont
prsents sur la machine, ils indiquent au client comment joindre le
JobTracker.

La mme remarque est valable pour l'accs au systme de fichiers: les


DataNodes indiquent au client comment accder au NameNode.

Enfin, tout changement de configuration Hadoop peut s'effectuer


facilement simplement en changeant la configuration sur la machine o
sont situs les serveurs NameNode et JobTracker: ils rpliquent les
changement de configuration sur tout le cluster automatiquement.
Architecture gnrale
5-11
6 Utilisation Hadoop
Interfaces utilisateur
6-1

Hadoop est essentiellement pilot par des outils consoles (CLI), mais
quelques interfaces utilisateurs sont mises disposition de l'utilisateur:

NameNode expose une interface web (via un serveur web intgr) qui
permet de parcourir les fichiers et rpertoires stocks sur HDFS.

DataNode expose une interface web similaire, appele par l'interface de


NameNode, qui permet de lire les blocs des fichiers stocks (ou les
fichiers stocks dans leur intgralit).

Enfin, JobTracker offre une interface web galement, qui permet de


consulter les tches en cours, d'avoir des statistiques sur l'excution des
tches, de voir l'tat des nodes TaskTracker et si oui ou non ils sont
parvenus excuter les tches qui leur ont t affect, etc.
Remarques
6-2
Par ailleurs, des interfaces utilisateur tierces ont t dveloppes pour
simplifier l'utilisation de Hadoop, par exemple le projet Hue (Open Source).
Remarques
6-3
Il est nanmoins vital de savoir de servir des commandes de base (qui
pourraient par exemple tre appeles depuis des scripts shell).
Programmation Hadoop
6-4
Comme indiqu prcdemment, Hadoop est dvelopp en Java. Les tches
MAP/REDUCE sont donc implmentables par le biais d'interfaces Java (il existe
cependant des wrappers trs simples permettant d'implmenter ses tches
dans n'importe quel langage). Un programme Hadoop se compile au sein d'un
.jar.

Pour dvelopper un programme Hadoop, on va crer trois classes distinctes:

Une classe dite Driver qui contient la fonction main du programme. Cette
classe se chargera d'informer Hadoop des types de donnes clef/valeur
utilises, des classes se chargeant des oprations MAP et REDUCE, et des
fichiers HDFS utiliser pour les entres/sorties.

Une classe MAP (qui effectuera l'opration MAP).

Une classe REDUCE (qui effectuera l'opration REDUCE).


Programmation Hadoop Classe Driver
6-5

La classe Driver contient le main de notre programme.

Au sein du main() en question, on va effectuer les oprations suivantes:

Crer un objet Configuration de Hadoop, qui est ncessaire pour permettre


Hadoop d'obtenir la configuration gnrale du cluster. L'objet en question
pourrait aussi nous permettre de rcuprer nous-mme des options de
configuration qui nous intressent.

Permettre Hadoop de rcuprer d'ventuels arguments gnriques


disponibles sur la ligne de commande (par exemple le nom du package de la
tche excuter si le .jar en contient plusieurs). On va galement rcuprer
les arguments supplmentaires pour s'en servir; on souhaite que l'utilisateur
puisse prciser le nom du fichier d'entre et le nom du rpertoire de sortie
HDFS pour nos tches Hadoop grce la ligne de commande.
Programmation Hadoop Classe Driver
6-6
Crer un nouvel objet Hadoop Job, qui dsigne une tche Hadoop.

Utiliser cet objet Job pour informer Hadoop du nom de nos classes Driver,
MAP et REDUCE.

Utiliser le mme objet pour informer Hadoop des types de donnes utiliss
dans notre programme pour les couples (clef;valeur) MAP et REDUCE.

Informer Hadoop des fichiers d'entre/sortie pour notre tche sur HDFS.

Enfin, utiliser l'objet Job cr prcdemment pour dclencher le lancement


de la tche via le cluster Hadoop.

On reprend ici l'exemple du compteur doccurrences de mots dcrit


prcdemment.
Programmation Hadoop Classe Driver
6-7

Le prototype de notre fonction main():


public
public static
static void
void main(String[]
main(String[] args)
args) throws
throws Exception
Exception
On se sert de args pour rcuprer les arguments de la ligne de commande.
Plusieurs fonctions Hadoop appeles au sein du main sont susceptibles de
dclencher des exceptions on l'indique donc lors de la dclaration.
Avant toute chose, on cr dans notre main un nouvel objet Configuration
Hadoop:
//
// Cr
Cr un
un objet
objet de
de configuration
configuration Hadoop.
Hadoop.
Configuration
Configuration conf=new
conf=new Configuration();
Configuration();

Le package importer est:


org.apache.hadoop.conf.Configuration
Programmation Hadoop Classe Driver
6-8

Ensuite, on passe Hadoop les arguments de la ligne de commande pour lui


permettre de rcuprer ceux qui sont susceptibles de lui tre adresss:
String[]
String[] ourArgs=new
ourArgs=new GenericOptionsParser(conf,
GenericOptionsParser(conf, args).getRemainingArgs();
args).getRemainingArgs();

On utilise pour ce faire un objet Hadoop GenericOptionsParser, dont le


package est:
org.apache.hadoop.util.GenericOptionsParser

La fonction getRemainingArgs() de notre objet nous permet par ailleurs de


rcuprer les arguments non exploits par Hadoop au sein d'un tableau
ourArgs ce qui nous permettra de les utiliser par la suite.

On peut ainsi rendre paramtrable facilement une tche Hadoop lors de


l'excution, par le biais des arguments de la ligne de commande.
Programmation Hadoop Classe Driver
6-9

On cr ensuite un nouvel objet Hadoop Job:


Job
Job job=Job.getInstance(conf,
job=Job.getInstance(conf, "Compteur
"Compteur de
de mots
mots v1.0");
v1.0");

Le package importer est le suivant:


org.apache.hadoop.mapreduce.Job

On passe au constructeur notre objet Configuration, ainsi qu'une description


textuelle courte du programme Hadoop.

Ensuite, il faut indiquer Hadoop par le biais de l'objet Job nouvellement


cr quelles sont les classes Driver, Map et Reduce de notre programme
Hadoop.
Dans notre cas, il s'agira respectivement des classes WCount, WCountMap et
WCountReduce du package org.mbds.hadoop.wordcount.
Programmation Hadoop Classe Driver
6-10

On utilise pour ce faire les fonctions suivantes:


job.setJarByClass(WCount.class);
job.setJarByClass(WCount.class);
job.setMapperClass(WCountMap.class);
job.setMapperClass(WCountMap.class);
job.setReducerClass(WCountReduce.class);
job.setReducerClass(WCountReduce.class);

Il faut ensuite indiquer Hadoop quels sont les types de donnes que l'ont
souhaite utiliser pour les couples (clef;valeur) de nos oprations map et
reduce. Dans le cas de notre compteur doccurrences de mots, on souhaite
utiliser des chanes de caractres pour les clefs (nos mots) et des entiers
pour nos occurrences.

Remarque: on ne doit pas utiliser les types classiques Int et String Java pour
dsigner nos types, mais des classes qui leur correspondent et qui sont
propres Hadoop. Dans notre cas, les classes IntWritable et Text.
Programmation Hadoop Classe Driver
6-11

job.setOutputKeyClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setOutputValueClass(IntWritable.class);

Les packages des types en question:


org.apache.hadoop.io.IntWritable et org.apache.hadoop.io.Text
Il en existe beaucoup d'autres dans org.apache.hadoop.io.*.

Ensuite, on doit indiquer o se situent nos donnes d'entre et de sortie


dans HDFS. On utilise pour ce faire les classes Hadoop FileInputFormat et
FileOutputFormat.
Ces classes sont implmentes suivant un design pattern Singleton il n'est
pas ncessaire de les instancier dans le cas qui nous intresse (dans des cas
plus complexe, on tendra parfois la classe en question dans une nouvelle
classe qui nous est propre).
Programmation Hadoop Classe Driver
6-12

On procde de la manire suivante:


FileInputFormat.addInputPath(job,
FileInputFormat.addInputPath(job, new
new Path(ourArgs[0]));
Path(ourArgs[0]));
FileOutputFormat.setOutputPath(job,
FileOutputFormat.setOutputPath(job, new
new Path(ourArgs[1]));
Path(ourArgs[1]));
Les packages utiliser:

org.apache.hadoop.mapreduce.lib.input.FileInputFormat
org.apache.hadoop.mapreduce.lib.input.FileOutputFormat
et
org.apache.hadoop.fs.Path

On utilise les arguments restants aprs ceux qu'a utilis Hadoop. Le code est
ici simplifi on devrait en thorie vrifier la taille du tableau ourArgs pour
viter d'ventuelles erreurs.
Programmation Hadoop Classe Driver
6-13

Enfin, il reste lancer l'excution de la tche par le biais du cluster Hadoop.


On procde ainsi:
if(job.waitForCompletion(true))
if(job.waitForCompletion(true))
System.exit(0);
System.exit(0);
System.exit(-1);
System.exit(-1);

La fonction waitForCompletion de l'objet job va excuter la tche et


attendre la fin de son excution. Elle prend un argument: un boolen
indiquant Hadoop si oui ou non il doit donner des indications sur la
progression de l'excution l'utilisateur sur la sortie standard (stdout).

Elle renvoie true en cas de succs; ici, on terminera l'excution du


programme en renvoyant 0 si tout s'est bien pass, et -1 en cas de problme
(codes de retour unix standards).
Programmation Hadoop Classe Driver
6-14

Le code complet de notre classe Driver:


package
package org.mbds.hadoop.wordcount;
org.mbds.hadoop.wordcount;

import
import org.apache.hadoop.fs.Path;
org.apache.hadoop.fs.Path;
import
import org.apache.hadoop.mapreduce.Job;
org.apache.hadoop.mapreduce.Job;
import
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import
import org.apache.hadoop.conf.Configuration;
org.apache.hadoop.conf.Configuration;
import
import org.apache.hadoop.util.GenericOptionsParser;
org.apache.hadoop.util.GenericOptionsParser;
import
import org.apache.hadoop.io.Text;
org.apache.hadoop.io.Text;
import
import org.apache.hadoop.io.IntWritable;
org.apache.hadoop.io.IntWritable;

//
// Notre
Notre classe
classe Driver
Driver (contient
(contient le
le main
main du
du programme
programme Hadoop).
Hadoop).
public
public class
class WCount
WCount
{{
Programmation Hadoop Classe Driver
6-15
//
// Le
Le main
main du
du programme.
programme.
public
public static
static void
void main(String[]
main(String[] args)
args) throws
throws Exception
Exception
{{
//
// Cr
Cr un
un object
object de
de configuration
configuration Hadoop.
Hadoop.
Configuration
Configuration conf=new
conf=new Configuration();
Configuration();

//
// Permet
Permet Hadoop
Hadoop de
de lire
lire ses
ses arguments
arguments gnriques,
gnriques,
//
// rcupre
rcupre les
les arguments
arguments restants
restants dans
dans ourArgs.
ourArgs.
String[]
String[] ourArgs=new
ourArgs=new GenericOptionsParser(conf,
GenericOptionsParser(conf,
args).getRemainingArgs();
args).getRemainingArgs();

//
// Obtient
Obtient un
un nouvel
nouvel objet
objet Job:
Job: une
une tche
tche Hadoop.
Hadoop. On
On
//
// fourni
fourni la
la configuration
configuration Hadoop
Hadoop ainsi
ainsi qu'une
qu'une description
description
//
// textuelle
textuelle de
de la
la tche.
tche.
Job
Job job=Job.getInstance(conf,
job=Job.getInstance(conf, "Compteur
"Compteur de
de mots
mots v1.0");
v1.0");
Programmation Hadoop Classe Driver
6-16
//
// Dfini
Dfini les
les classes
classes driver,
driver, map
map et
et reduce.
reduce.
job.setJarByClass(WCount.class);
job.setJarByClass(WCount.class);
job.setMapperClass(WCountMap.class);
job.setMapperClass(WCountMap.class);
job.setReducerClass(WCountReduce.class);
job.setReducerClass(WCountReduce.class);

//
// Dfini
Dfini types
types clefs/valeurs
clefs/valeurs de
de notre
notre programme
programme Hadoop.
Hadoop.
job.setOutputKeyClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setOutputValueClass(IntWritable.class);

//
// Dfini
Dfini les
les fichiers
fichiers d'entre
d'entre du
du programme
programme et
et le
le
//
// rpertoire
rpertoire des
des rsultats.
rsultats. On
On se
se sert
sert du
du premier
premier et
et du
du
//
// deuxime
deuxime argument
argument restants
restants pour
pour permettre
permettre
//
// l'utilisateur
l'utilisateur de
de les
les spcifier
spcifier lors
lors de
de l'excution.
l'excution.
FileInputFormat.addInputPath(job,
FileInputFormat.addInputPath(job, newnew Path(ourArgs[0]));
Path(ourArgs[0]));
FileOutputFormat.setOutputPath(job,
FileOutputFormat.setOutputPath(job, new new Path(ourArgs[1]));
Path(ourArgs[1]));
Programmation Hadoop Classe Driver
6-17
//
// On
On lance
lance la
la tche
tche Hadoop.
Hadoop. Si
Si elle
elle s'est
s'est effectue
effectue
//
// correctement,
correctement, on
on renvoie
renvoie 0.
0. Sinon,
Sinon, on
on renvoie
renvoie -1.
-1.
if(job.waitForCompletion(true))
if(job.waitForCompletion(true))
System.exit(0);
System.exit(0);
System.exit(-1);
System.exit(-1);
}}
}}
Programmation Hadoop Classe MAP
6-18
La classe MAP va tre en charge de l'opration MAP de notre programme.

Elle doit tendre la classe Hadoop org.apache.hadoop.mapreduce.Mapper.


Il s'agit d'une classe gnrique qui se paramtrise avec quatre types:

Un type keyin: le type de clef d'entre.


Un type valuein: le type de valeur d'entre.
Un type keyout: le type de clef de sortie.
Un type valueout: le type de valeur de sortie.

Le type keyin est notamment utile lorsqu'on utilise des fonctionnalits plus
avances, comme la possibilit d'effectuer plusieurs oprations MAP les unes
la suite des autres, auquel cas notre opration map recevra en entre des
couples (clef;valeur).
Dans notre cas, nous n'utiliserons pas cette possibilit; on utilisera donc le
type Java Object comme type keyin.
Programmation Hadoop Classe MAP
6-19

Dans notre exemple, notre classe Map sera dclare ainsi:


public
public class
class WCountMap
WCountMap extends
extends Mapper<Object,
Mapper<Object, Text,
Text, Text,
Text, IntWritable>
IntWritable>

On utilise ici comme types:

Text pour le type valuein, puisque notre valeur d'entre la fonction Map est
une chane de caractres (une ligne de texte).
Text pour le type keyout, puisque notre valeur de clef pour les couples
(clef;valeur) de la fonction Map est galement une chane de caractres (le
mot dont on compte les occurrences).
IntWritable pour le type valueout, puisque notre valeur pour les couples
(clef;valeur) de la fonction Map est un entier (le nombre d'occurences).

Ici aussi, on utilise les types Hadoop et non les types natifs Java (Int et String).
Programmation Hadoop Classe MAP
6-20

Au sein de la classe Mapper, c'est la fonction map qui va s'occuper d'effectuer


la tche MAP. C'est la seule qu'on doit absolument implmenter.
Elle prends trois arguments: la clef d'entre keyin (qu'on ignore dans notre
cas), la valeur d'entre valuein (la ligne de texte dont on souhaite compter les
mots), et un Context Java qui reprsente un handle Hadoop et nous permettra
de retourner les couples (clef;valeur) rsultant de notre opration Map.

Le prototype de notre fonction map:


protected
protected void
void map(Object
map(Object key,
key, Text
Text value,
value, Context
Context context)
context)
throws
throws IOException,
IOException, InterruptedException
InterruptedException

Comme pour la fonction main, la fonction map appellera des fonctions


susceptibles de dclencher des exceptions (notamment concernant
l'interruption de l'excution Hadoop ou des problmes daccs HDFS) on le
prcise donc dans sa dclaration.
Programmation Hadoop Classe MAP
6-21

Au sein de la mthode map, on va donc effectuer la tche MAP de notre


programme MAP/REDUCE.
Dans le cadre de notre exemple, la fonction devra parcourir la ligne de texte
fournie en entre, et renvoyer un couple (clef;valeur) pour chacun des mots. Ce
couple devra avoir pour clef le mot en question, et pour valeur l'entier 1.

Dans la fonction map, afin d'indiquer Hadoop qu'on souhaite renvoyer un


couple (clef;valeur), on utilise la fonction write de notre objet Context. Elle
peut tre appele autant de fois que ncessaire; une fois pour chacun des
couples (clef;valeur) qu'on souhaite renvoyer. Par exemple:
context.write("ciel",
context.write("ciel", 1);
1);

Il faut videmment que la clef et la valeur renvoyes ainsi correspondent aux


types keyout et valueout de notre classe Mapper.
Programmation Hadoop Classe MAP
6-22

Notre classe Map d'exemple en intgralit:


package
package org.mbds.hadoop.wordcount;
org.mbds.hadoop.wordcount;

import
import org.apache.hadoop.mapreduce.Job;
org.apache.hadoop.mapreduce.Job;
import
import org.apache.hadoop.io.Text;
org.apache.hadoop.io.Text;
import
import org.apache.hadoop.io.IntWritable;
org.apache.hadoop.io.IntWritable;
import
import java.util.StringTokenizer;
java.util.StringTokenizer;
import
import org.apache.hadoop.mapreduce.Mapper;
org.apache.hadoop.mapreduce.Mapper;
import
import java.io.IOException;
java.io.IOException;

//
// Notre
Notre classe
classe MAP.
MAP.
public
public class
class WCountMap
WCountMap extends
extends Mapper<Object,
Mapper<Object, Text,
Text, Text,
Text, IntWritable>
IntWritable>
{{
//
// IntWritable
IntWritable contant
contant de
de valeur
valeur 1.
1.
private
private static
static final
final IntWritable
IntWritable ONE=new
ONE=new IntWritable(1);
IntWritable(1);
Programmation Hadoop Classe MAP
6-23
//
// La
La fonction
fonction MAP
MAP elle-mme.
elle-mme.
protected
protected void
void map(Object
map(Object offset,
offset, Text
Text value,
value, Context
Context context)
context)
throws
throws IOException,
IOException, InterruptedException
InterruptedException
{{
//
// Un
Un StringTokenizer
StringTokenizer va
va nous
nous permettre
permettre de
de parcourir
parcourir chacun
chacun des
des
//
// mots
mots de
de la
la ligne
ligne qui
qui est
est passe
passe notre
notre opration
opration MAP.
MAP.
StringTokenizer
StringTokenizer tok=new
tok=new StringTokenizer(value.toString(),
StringTokenizer(value.toString(), "" ");
");

while(tok.hasMoreTokens())
while(tok.hasMoreTokens())
{{
Text
Text word=new
word=new Text(tok.nextToken());
Text(tok.nextToken());
//
// On
On renvoie
renvoie notre
notre couple
couple (clef;valeur):
(clef;valeur): le
le mot
mot courant
courant suivi
suivi
//
// de
de la
la valeur
valeur 11 (dfinie
(dfinie dans
dans la
la constante
constante ONE).
ONE).
context.write(word,
context.write(word, ONE);
ONE);
}}
}}
}}
Programmation Hadoop Classe REDUCE
6-24

La classe REDUCE va tre en charge de l'opration REDUCE de notre


programme.

Elle doit tendre la classe Hadoop org.apache.hadoop.mapreduce.Reducer.


Il s'agit l aussi d'une classe gnrique qui se paramtrise avec les mmes
quatre types que pour la classe Mapper: keyin, valuein,keyout et valueout.

On rappelle que l'opration REDUCE recevra en entre une clef unique,


associe toutes les valeurs pour la clef en question.

Dans le cas du compteur doccurrences de mots, on recevra en entre une


valeur unique pour la clef, par exemple ciel, suivi de toutes les valeurs qui
ont t rencontres la sortie de l'opration MAP pour la clef ciel (par
exemple cinq fois la valeur 1 si le mot ciel tait prsent cinq fois dans
notre texte d'exemple).
Programmation Hadoop Classe REDUCE
6-25

Dans notre exemple, la classe Reduce sera dfinie comme suit:


public
public class
class WCountReduce
WCountReduce extends
extends Reducer<Text,
Reducer<Text, IntWritable,
IntWritable, Text,
Text, Text>
Text>
On utilise pour chacun des types paramtrables:

Text pour keyin: il s'agit de notre clef unique d'entre le mot concern.
IntWritable pour valuein: le type de nos valeurs associes cette clef (le
nombre d'occurences, un entier).
Text pour keyout: le type de clef de sortie. Nous ne modifierons pas la clef, il
s'agira toujours du mot unique concern on utilise donc Text.
Text pour valueout: le type de valeur de sortie. On utilise ici Text on
renverra le nombre total doccurrences pour le mot concern sous la forme
d'une chane de caractres (on pourrait galement utiliser IntWritable ici).

L aussi, on utilise les types de donnes propres Hadoop.


Programmation Hadoop Classe REDUCE
6-26

Au sein de la classe Reducer, c'est la fonction reduce qui va effectuer


l'opration REDUCE. C'est la seule qu'on doive implmenter.

Elle prends trois arguments: la clef concerne, un Iterable java (une liste) de
toutes les valeurs qui lui sont associes et qui ont t renvoyes par
l'opration MAP, et enfin un objet Context java similaire celui de la fonction
map de la classe Mapper, et qui nous permettra de renvoyer notre valeur finale,
associe la clef.

Dans notre exemple, la dclaration de la fonction reduce:


public
public void
void reduce(Text
reduce(Text key,
key, Iterable<IntWritable>
Iterable<IntWritable> values,
values, Context
Context context)
context)
throws
throws IOException,
IOException, InterruptedException
InterruptedException

Comme pour map, la fonction fait appel des fonctions Hadoop susceptibles
de provoquer des exceptions on l'indique ici aussi.
Programmation Hadoop Classe REDUCE
6-27

Au sein de la fonction Reduce, on pourra renvoyer un couple (clef;valeur) en


rsultat exactement de la mme manire que pour la fonction map, par le biais
d'un appel la fonction write de notre objet Context.

Par exemple:
context.write("ciel",
context.write("ciel", "5
"5 occurences");
occurences");

Contrairement la fonction map, en revanche, on cherche ne produire qu'une


et une seule valeur de retour pour la clef concerne. On n'appellera donc la
fonction write qu'une seule fois.

Remarque: en thorie et dans des cas plus complexes, on pourrait l aussi


appeler la fonction plusieurs reprises, pour renvoyer plusieurs couples
(clef;valeur). En revanche, Hadoop n'appliquera aucun traitement dessus et les
considrera simplement comme plusieurs rsultats finals.
Programmation Hadoop Classe REDUCE
6-28

Notre classe Reduce d'exemple en intgralit:


package
package org.mbds.hadoop.wordcount;
org.mbds.hadoop.wordcount;

import
import org.apache.hadoop.io.Text;
org.apache.hadoop.io.Text;
import
import org.apache.hadoop.io.IntWritable;
org.apache.hadoop.io.IntWritable;
import
import org.apache.hadoop.mapreduce.Reducer;
org.apache.hadoop.mapreduce.Reducer;
import
import java.util.Iterator;
java.util.Iterator;
import
import java.io.IOException;
java.io.IOException;

//
// Notre
Notre classe
classe REDUCE
REDUCE -- paramtre
paramtre avec
avec un
un type
type Text
Text pour
pour la
la clef,
clef, un
un
//
// type de valeur IntWritable, et un type de retour (le retour final de
type de valeur IntWritable, et un type de retour (le retour final de
//
// la
la fonction
fonction Reduce)
Reduce) Text.
Text.
public
public class WCountReduce extends
class WCountReduce extends Reducer<Text,
Reducer<Text, IntWritable,
IntWritable, Text,
Text, Text>
Text>
{{
Programmation Hadoop Classe REDUCE
6-29
// La
La fonction
//classe
Notre ReduceREDUCE
fonction REDUCE elle-mme.
elle-mme.
d'exemple Les
Les arguments:
arguments: la
en intgralit: la clef
clef key,
key, un
un
//
// Iterable
Iterable de de toutes
toutes les
les valeurs
valeurs quiqui sont
sont associes
associes lala clef
clef en
en
//
// question,
package
package et
et le
le contexte
contexte Hadoop
org.mbds.hadoop.wordcount;
question,
org.mbds.hadoop.wordcount; Hadoop (un
(un handle
handle quiqui nous
nous permet
permet de
de
// renvoyer le rsultat Hadoop).
// renvoyer le rsultat Hadoop).
public
import
import void
void reduce(Text
reduce(Text key,
org.apache.hadoop.io.Text;
public
org.apache.hadoop.io.Text;key, Iterable<IntWritable>
Iterable<IntWritable> values,values,
import Context
Context context)
import org.apache.hadoop.io.IntWritable;
context)
org.apache.hadoop.io.IntWritable;
import throws
throws IOException,
IOException, InterruptedException
import org.apache.hadoop.mapreduce.Reducer;
org.apache.hadoop.mapreduce.Reducer; InterruptedException
{{ java.util.Iterator;
import
import java.util.Iterator;
import //
// Pour
Pour parcourir
parcourir toutes
import java.io.IOException;
java.io.IOException; toutes lesles valeurs
valeurs associes
associes la la clef
clef fournie.
fournie.
Iterator<IntWritable>
Iterator<IntWritable> i=values.iterator();
i=values.iterator();
int
int count=0;
count=0; // // Notre
Notre total
total pour
pour le
le mot
mot concern.
concern.
//
// Notre
Notre while(i.hasNext())
classe
classe REDUCE
while(i.hasNext()) //
// Pour
REDUCE -- paramtre
paramtre chaque
Pour avec un valeur...
un
chaque
avec type
type Text
Text pour
valeur... pour lala clef,
clef, un
un
// type de count+=i.next().get();
valeur IntWritable,
count+=i.next().get();
// type de valeur et un
IntWritable, et un type //
type...on
de
// ...on l'ajoute
retour (le
l'ajoute
de retour au total.
retour
(le au total.
retour final
final de
de
//
// la //
// On
On renvoie
la fonction
fonction Reduce)
renvoie
Reduce) le couple
couple (clef;valeur)
leText.
Text. (clef;valeur) constitu
constitu de de notre
notre clef
clef key
key
public //
// et
public class
class du
du total,
total, au
et WCountReduce
WCountReduce format
format Text.
au extends
extends Reducer<Text,
Reducer<Text, IntWritable,
Text. IntWritable, Text,
Text, Text>
Text>
{{ context.write(key,
context.write(key, new new Text(count+"
Text(count+" occurences."));
occurences."));
}}
}}
Remarques
6-30
Hadoop est une plate-forme rcente, en dveloppement constant: l'API Java
change rgulirement. Il faut toujours s'informer sur les dernires
modifications afin de rester jour des dernires modifications. Par ailleurs, la
distribution Hadoop comprend de nombreux exemples de programmes
Map/Reduce, mis jour afin d'utiliser l'API la plus rcente.

Mme si l'API change rgulirement, les anciennes manires de procder


restent gnralement disponibles pendant plusieurs mois aprs une mise
jour.

Enfin, il existe de nombreuses autres possibilits offertes par l'API: extraire


des paramtres de configurations globaux du cluster, implmenter sa propre
classe FileInputFormat pour des traitements plus complexes sur les donnes
d'entre, etc... d'une manire gnrale, se rfrer la documentation de l'API
Hadoop:
https://hadoop.apache.org/docs/
Compilation
6-31
Pour compiler un programme Hadoop, il suffit d'utiliser le compilateur javac
comme pour tout autre programme Java.

Il est cependant ncessaire d'inclure les librairies appropries. Elles sont


disponibles avec les distributions de Hadoop, sous la forme de fichiers .jar.
Les librairies principales utiliser:

hadoop-common.jar
hadoop-mapreduce-client-core.jar

hadoop-mapreduce-client-common.jar

commons-cli.jar

il en existe d'autres pour des cas d'utilisation plus complexes, inclure en


fonction des besoins.

Enfin, aprs compilation, on package le programme Hadoop l'intrieur d'un


fichier .jar pour son excution.
Excution
6-32
Pour excuter un programme Hadoop, on utilise l aussi le programme en
ligne de commande hadoop. La syntaxe est la suivante:

hadoop
hadoop jar
jar [JAR
[JAR FILE]
FILE] [DRIVER
[DRIVER CLASS]
CLASS] [PARAMETERS]
[PARAMETERS]

Par exemple pour notre compteur doccurrences de mots:

hadoop
hadoop jar
jar wcount_mbds.jar
wcount_mbds.jar org.mbds.hadoop.wordcount.WCount
org.mbds.hadoop.wordcount.WCount \\
input/poeme.txt
input/poeme.txt /results
/results

la commande demandera Hadoop d'excuter le programme Hadoop de la


classe Driver org.mbds.hadoop.wordcount du fichier wcount_mbds.jar, en
lui indiquant qu'il doit lire son texte dans le fichier input/poeme.txt sur
HDFS, et stocker les rsultats dans le rpertoire results sur HDFS.
Remarques
6-33

Hadoop stocke les rsultats dans une srie de fichiers part-r-XXXX, o


XXXX est un compteur incrmental. L'ide est ici de stocker de grandes
quantits de rsultats dans de nombreux fichiers diffrents, qui seront en
consquences distribus sur tout le cluster HDFS. Le nom du fichier est
paramtrable dans la configuration Hadoop.

On a un fichier part-r par opration REDUCE excute. Le r au sein du


nom signifie Reduce. On peut galement demander Hadoop d'effectuer
uniquement les oprations MAP (par exemple pour du debug), auquel cas on
aura une srie de fichiers part-m.

Un fichier _SUCCESS (vide) est galement cr dans le rpertoire des


rsultats en cas de succs. Cela permet de contrler que tout s'est bien
pass rapidement (avec un simple hadoop fs -ls sur HDFS).
Autres langages: streaming
6-34

Au del de Java, Hadoop permet galement l'excution d'un programme


Hadoop crit dans d'autres langages, par exemple en C, en Python ou encore
en bash (shell scripting).

Pour ce faire, un outil est distribu avec Hadoop: streaming. Il s'agit d'un .jar
qui est capable de prendre en argument des programmes ou scripts dfinissant
les tches MAP et REDUCE, ainsi que les fichiers d'entre et le rpertoire de
sortie HDFS, et d'excuter ainsi la tche spcifie sur le cluster.

Ce .jar est disponible dans le rpertoire d'installation Hadoop et porte le nom


hadoop-streaming-VERSION.jar, o VERSION est la version de Hadoop
concerne.

Il s'agit en ralit d'un programme Hadoop Java classique, mais qui appelle
les tches MAP et REDUCE par le biais du systme.
Streaming - MAP
6-35

Lorsqu'on dveloppe un programme MAP Hadoop dans un autre langage pour


son utilisation avec l'outil streaming, les donnes d'entre doivent tre lues sur
l'entre standard (stdin) et les donnes de sorties doivent tre envoyes sur la
sortie standard (stdout).

En entre du script ou programme MAP, on aura une srie de lignes: nos


donnes d'entre (par exemple dans le cas du compteur doccurrences de
mots, des lignes de notre texte).

En sortie du script ou programme MAP, on doit crire sur stdout notre srie
de couples (clef;valeur) au format:

CLEF[TABULATION]VALEUR

avec une ligne distincte pour chaque (clef;valeur).


Streaming - REDUCE
6-36

Lorsqu'on dveloppe un programme REDUCE Hadoop dans un autre langage


pour son utilisation avec l'outil streaming, les donnes d'entre et de sortie
doivent tre l aussi lues/crites sur stdin et stdout (respectivement).

En entre du script ou programme REDUCE, on aura une srie de lignes: des


couples (clef;valeur) au format:
CLEF[TABULATION]VALEUR
Les couples seront tris par clef distincte, et la clef rpte chaque fois. Par
ailleurs, on est susceptible d'avoir des clefs diffrentes au sein d'une seule et
mme excution du programme reduce!

En sortie du script ou programme REDUCE, on doit crire des couples


(clef;valeur), toujours au format CLEF[TABULATION]VALEUR.
Remarque: d'ordinaire, on crira videmment un seul couple (clef;valeur) par
clef distincte.
Exemple (Python)
6-37

Occurences de mots version Python opration MAP:


import
import sys
sys

## Pour
Pour chaque
chaque ligne
ligne d'entre.
d'entre.
for
for line
line in
in sys.stdin:
sys.stdin:
## Supprimer
Supprimer les
les espaces
espaces autour
autour de
de la
la ligne.
ligne.
line=line.strip()
line=line.strip()
## Pour
Pour chaque
chaque mot
mot de
de la
la ligne.
ligne.
words=line.split()
words=line.split()
for
for word
word in
in words:
words:
## Renvoyer
Renvoyer couple
couple clef;valeur:
clef;valeur: le
le mot
mot comme
comme clef,
clef, l'entier
l'entier "1"
"1" comme
comme
## valeur.
valeur.
## On
On renvoie
renvoie chaque
chaque couple
couple sur
sur une
une ligne,
ligne, avec
avec une
une tabulation
tabulation entre
entre
## la clef et la valeur.
la clef et la valeur.
print
print "%s\t%d"
"%s\t%d" %% (word,
(word, 1)
1)
Exemple (Python)
6-38

Occurences de mots version Python opration REDUCE:


import
import sys
sys

total=0;
total=0; ## Notre
Notre total
total pour
pour le
le mot
mot courant.
courant.
## Contient
Contient le
le dernier
dernier mot
mot rencontr.
rencontr.
lastword=None
lastword=None

## Pour
Pour chaque
chaque ligne
ligne d'entre.
d'entre.
for
for line
line in
in sys.stdin:
sys.stdin:
## Supprimer
Supprimer les
les espaces
espaces autour
autour de
de la
la ligne.
ligne.
line=line.strip()
line=line.strip()

## Rcuprer
Rcuprer la
la clef
clef et
et la
la valeur,
valeur, convertir
convertir la
la valeur
valeur en
en int.
int.
word, count=line.split('\t', 1)
word, count=line.split('\t', 1)
count=int(count)
count=int(count)
Exemple (Python)
6-39
## On
On change
change de
de mot
mot (test
(test ncessaire
ncessaire parce
parce qu'on
qu'on est
est susceptible
susceptible d'avoir
d'avoir
## en
en entre plusieurs clefs distinctes diffrentes pour une seule et
entre plusieurs clefs distinctes diffrentes pour une seule et
## mme
mme excution
excution du
du programme
programme Hadoop
Hadoop triera
triera les
les couples
couples par
par clef
clef
## distincte).
distincte).
if
if word!=lastword
word!=lastword and
and lastword!=None:
lastword!=None:
print
print "%s\t%d
"%s\t%d occurences"
occurences" %% (lastword,
(lastword, total)
total)
total=0;
total=0;
lastword=word
lastword=word

total=total+count
total=total+count ## Ajouter
Ajouter la
la valeur
valeur au
au total
total

## Ecrire
Ecrire le
le dernier
dernier couple
couple (clef;valeur).
(clef;valeur).
print
print "%s\t%d
"%s\t%d occurences"
occurences" %% (lastword,
(lastword, total)
total)
Exemple (Bash)
6-40

Occurences de mots version Bash opration MAP:

## Pour
Pour chaque
chaque ligne
ligne d'entre.
d'entre.
while
while read
read line;
line; do
do
## Supprimer
Supprimer les espaces
les espaces autour
autour de
de la
la ligne.
ligne.
line=$(echo
line=$(echo "$line"|sed
"$line"|sed 's/^\s*\(.\+\)\s*$/\1/')
's/^\s*\(.\+\)\s*$/\1/')
## Pour chaque mot de la ligne.
Pour chaque mot de la ligne.
for
for word
word in
in $line;
$line; do
do
## Renvoyer
Renvoyer couple
couple clef;valeur:
clef;valeur: le
le mot
mot comme
comme clef,
clef, l'entier
l'entier "1"
"1" comme
comme
## valeur.
valeur.
## On
On renvoie
renvoie chaque
chaque couple
couple sur
sur une
une ligne,
ligne, avec
avec une
une tabulation
tabulation entre
entre
## la
la clef
clef et
et la
la valeur.
valeur.
echo
echo -e
-e $word"\t"1
$word"\t"1
done
done
done
done
Exemple (Bash)
6-41

Occurences de mots version Bash opration REDUCE:

lastword=""
lastword=""
total=0
total=0

## Pour
Pour chaque
chaque ligne
ligne d'entre.
d'entre.
while
while read
read line;
line; do
do
## Supprimer
Supprimer les
les espaces
espaces autour
autour de
de la
la ligne.
ligne.
line=$(echo
line=$(echo "$line"|sed
"$line"|sed 's/^\s*\(.\+\)\s*$/\1/')
's/^\s*\(.\+\)\s*$/\1/')

## Recuperer
Recuperer mot
mot et
et occurrence
occurrence (IE,
(IE, clef
clef et
et valeur)
valeur)
word=$(echo
word=$(echo "$line"|awk
"$line"|awk -F
-F "\t"
"\t" '{print
'{print $1}');
$1}');
nb=$(echo
nb=$(echo "$line"|awk
"$line"|awk -F
-F "\t"
"\t" '{print
'{print $2}');
$2}');
Exemple (Bash)
6-42
## On
On change
change de
de mot
mot (test
(test ncessaire
ncessaire parce
parce qu'on
qu'on est
est susceptible
susceptible d'avoir
d'avoir
## en
en entre plusieurs clefs distinctes diffrentes pour une seule et
entre plusieurs clefs distinctes diffrentes pour une seule et
## mme
mme excution
excution du
du programme
programme Hadoop
Hadoop triera
triera les
les couples
couples par
par clef
clef
## distincte).
distincte).
if
if [[ "$word"
"$word" !=
!= "$lastword"
"$lastword" ]] &&
&& [[ "$lastword"
"$lastword" !=
!= ""
"" ];
]; then
then
echo
echo -e
-e $lastword"\t"$total"
$lastword"\t"$total" occurences."
occurences."
total=0;
total=0;
fi
fi
lastword="$word"
lastword="$word"

total=$[
total=$[ $total
$total ++ $nb
$nb ]] ## Ajouter
Ajouter la
la valeur
valeur au
au total.
total.
done
done

## Ecrire
Ecrire le
le dernier
dernier couple
couple (clef;valeur).
(clef;valeur).
echo
echo -e
-e $lastword"\t"$total"
$lastword"\t"$total" occurences."
occurences."
Excution
6-43

Streaming est un programme Hadoop standard, on l'excutera donc avec la


mme commande hadoop jar qu'un programme Hadoop Java habituel.
C'est dans ses options de ligne de commande qu'on va indiquer les scripts ou
programmes Hadoop map et reduce utiliser. Syntaxe:
hadoop
hadoop jar
jar hadoop-streaming-X.Y.Z.jar
hadoop-streaming-X.Y.Z.jar -input
-input [HDFS
[HDFS INPUT
INPUT FILES]
FILES] \\
-output
-output [HDFS
[HDFS OUTPUT
OUTPUT FILES]
FILES] \\
-mapper
-mapper [MAP
[MAP PROGRAM]
PROGRAM] \\
-reducer
-reducer [REDUCE
[REDUCE PROGRAM]
PROGRAM]

Par exemple:
hadoop
hadoop jar
jar hadoop-streaming-X.Y.Z.jar
hadoop-streaming-X.Y.Z.jar -input
-input /poeme.txt
/poeme.txt \\
-output
-output /results
/results -mapper
-mapper ./map.py
./map.py -reducer
-reducer ./reduce.py
./reduce.py

Aprs quoi la tche Hadoop s'excutera exactement comme une tche


standard.

Vous aimerez peut-être aussi