Développement de programmes MapReduce

les principes de fonctionnement de MapReduce restent valables quel que soit le langage de programmation utilisé.

Un programme Hadoop se divise généralement en trois parties :

  • Le driver, qui s’exécute sur une machine client, est chargé de configurer le job puis de le soumettre pour exécution.
  • Le mapper est chargé de lire les données stockées sur disque et les traiter.
  • Le reducer est chargé de consolider les résultats issus du mapper puis de les écrire sur disque.

1 – Les entrées-sorties

Dans MapReduce, les données sont toujours lues ou écrites selon le format <key, value> (<clef, valeur>).

Les données lues par le mapper sont définies au niveau du driver. La définition des données comprend :

  • Leur localisation (fichier ou répertoire).
  • Le type des enregistrements, qui est défini par la classe InputFormat.
  • La détermination de la taille des InputSplits : un InputSplit définit le volume des données qui seront lues à chaque opération de lecture.

Hadoop prend en compte par défaut les types d’enregistrement suivants :

  • TextInputFormat :
    • value est une ligne entière terminée par \n
    • key est l’offset de la ligne depuis le début de fichier
  • KeyValueTextInputFormat:
    • Chaque ligne est supposée être au format <key><separator><value>\n.
    • Le separateurr par défaut est tab.
  • SequenceFileInputFormat :
    • Permet de lire un fichier binaire de paires <key, value>, comprenant éventuellement des métadonnées.
  • SequenceFileAsTextInputFormat :
    • • Format identique au précédent mais, en plus, convertit les clefs et les valeurs en strings (<key.toString(), value.toString()>).

Dans Hadoop:

  • Les clefs sont des objets qui implémentent l’interface ComparableWritable.
  • Les valeurs sont des objets qui implémentent l’interface Writable.

Par défaut, Hadoop propose les types de données suivants :

  • IntWritable (int en Java).
  • DoubleWritable (double en Java).
  • Text (string en Java).
  • etc.

2 – La phase map (exemple 1)

Nous allons utiliser le programme WordCount pour expliquer le fonctionnement d’un mapper ainsi que celui d’un reducer. Le programme WordCount est écrit en pseudo-code et est simplifié à l’extrême.

Il s’agit de concevoir un programme Hadoop comptant le nombre d’occurrences des différents mots composant un livre.

Voici le contenu du fichier (livre) en entrée :

Lorem ipsum dolor sit
nec et nec et ultrices
Pellentesque et Pellentesque et bibendum
Lorem ipsum dolor sit

Un enregistrement correspond à une ligne terminée par \n. Dans un véritable programme Hadoop, on utilisera le format TextInputFormat pour lire les enregistrements.

Ci-dessous le mapper du programme WordCount :

Explication :

Ligne 1 : le mapper lit en entrée un enregistrement sous la forme d’un couple <key, value> avec :

  • value du type String (c’est une ligne du fichier).
  • key du type LongWritable (c’est l’offset de la ligne depuis le début du fichier).

ligne 2 : pour chaque mot w de la ligne en cours…

Ligne 3 : on écrit dans un fichier en sortie le couple <w, 1>, 1 correspondant à une occurrence du mot contenu dans la variable w.

Le fichier en sortie de mapper sera donc le suivant :

Lorem,1
ipsum,1
dolor,1
sit,1
nec,1
et,1
nec,1
et,1
ultrices,1
Pellentesque,1
et,1
Pellentesque,1
et,1
bibendum,1
Lorem,1
ipsum,1
dolor,1
sit,1

3 – Entre la phase map et la phase reduce (exemple 1)

Avant d’être envoyé au reducer, le fichier est automatiquement trié par clef par Hadoop : c’est ce que l’on appelle la phase de “shuffle & sort”. Le fichier en entrée du reducer est le suivant :

Lorem,[1,1]
ipsum,[1,1]
dolor,[1,1]
sit,[1,1]
nec,[1,1]
et,[1,1,1,1]
ultrices,[1]
Pellentesque,[1,1]
bibendum,[1]

4. La phase reduce (exemple 1)

Ci-dessous le reducer du programme Hadoop permettant de consolider les résultats issus du mapper :

Explication :

Ligne 1 : le reducer prend en entrée un enregistrement sous la forme d’un couple <key, value> avec :

  • key du type Text (c’est un mot).
  • value étant une liste de valeurs du type intWritable.

Ligne 2 : le reducer remet à zéro le compteur wordCount lorsque l’on change de mot.

Ligne 3 et 4 : pour chaque valeur v dans la liste inValue2 on ajoute v à wordCount.

ligne 5 : quand on change de mot, on écrit dans un fichier en sortie le couple <inKey2, wordCount>, wordCount étant le nombre d’occurrences du mot contenu dans la variable inKey2.

Le fichier en sortie de reducer sera donc le suivant :

Lorem,2
ipsum,2
dolor,2
sit,2
nec,2
et,4
ultrices,1
Pellentesque,2
bibendum,1

Nous venons d’écrire notre premier programme Hadoop, permettant de compter le nombre d’occurrences des différents mots composant un livre !

  • Un job Hadoop comprend au minimum un mapper : il peut ne pas comprendre de phase reduce.
  • Durant la phase de shuffle & sort, tous les mappers sont susceptibles d’envoyer des données vers tous les reducers.

Laisser un commentaire