Académique Documents
Professionnel Documents
Culture Documents
Benjamin Renaut
Tokidev SAS
- Bureau d'tude
- Dveloppement
- Consulting
http://www.tokidev.fr/
Avant de commencer
1-2
Problmatiques:
Supercalculateur classique.
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.
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++...).
- 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
- 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
De multiples approches existent et ont exist pour cette division d'un problme en
plusieurs sous-tches.
Mapper chacun de ces fragments pour obtenir des couples (clef; valeur).
Rduire (reduce) les groupes indexs par clef en une forme finale, avec une
valeur pour chacune des clefs distinctes.
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
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
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
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
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.
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
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
On fait galement en sorte que la clef soit toujours trie par ordre
alphabtique (clef B-A sera exprime sous la forme A-B).
("B-E";
("B-E"; "A
"A CC 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
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
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:
Il est distribu: les donnes sont rparties sur tout le cluster de machines.
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.
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
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:
FTP: une alternative haut niveau qui transfre les blocs manuellement via FTP.
Peu performant.
Comme pour HDFS, la gestion des tches de Hadoop se base sur deux serveurs
(des daemons):
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.).
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.
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.
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.
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.
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);
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
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.
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
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
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
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).
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.
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
Par exemple:
context.write("ciel",
context.write("ciel", "5
"5 occurences");
occurences");
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.
hadoop-common.jar
hadoop-mapreduce-client-core.jar
hadoop-mapreduce-client-common.jar
commons-cli.jar
hadoop
hadoop jar
jar [JAR
[JAR FILE]
FILE] [DRIVER
[DRIVER CLASS]
CLASS] [PARAMETERS]
[PARAMETERS]
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
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.
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
En sortie du script ou programme MAP, on doit crire sur stdout notre srie
de couples (clef;valeur) au format:
CLEF[TABULATION]VALEUR
## 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
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
## 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
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
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