Exécution d'un programme MapReduce dans un cluster Hadoop à nœud unique

Partage d'expérience sur la mise en œuvre d'un cluster Hadoop à un nœud et sur l'exécution d'un programme MapReduce en utilisant Eclipse

Gaël YIMEN YIMGA

Cet article est un récapitulatif de mon expérience la plus récente dans l'écosystème Hadoop. Il a été réalisé à la suite d'un travail d'étude et d'analyse qui m'a été confié dans le cadre d'un POC (Proof Of Concept). J'ai profité de la plateforme www.developpez.com pour partager ce travail sachant que le monde des BigData en général et l'écosystème Hadoop en particulier constituent plus ou moins un mystère actuellement pour certains acteurs de l'informatique.

Commentez

- Titre : Exécution d'un programme MapReduce dans un cluster Hadoop à nœud unique

- Auteur : Gaël YIMEN YIMGA

- Parution : 18 septembre 2014

- Mise à jour : 23 octobre 2014

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2014 Gaël YIMEN YIMGA. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Contexte

- III. Prérequis pour la réalisation de ce tutoriel

- III-A. Liste des outils et logiciels utilisés

- IV. Installation d'un cluster Hadoop à nœud unique

- IV-A. Téléchargement de la version stable 1.2.1 de Hadoop

- IV-B. Création d'un utilisateur pour Hadoop

- IV-C. Préparation de l'environnement

- IV-C-1. Mise à jour du fichier conf/hadoop-env.sh

- IV-C-2. Mise à jour du fichier conf/core-site.xml

- IV-C-3. Mise à jour du fichier conf/hdfs-site.xml

- IV-C-4. Mise à jour du fichier conf/mapred-site.xml

- IV-D. Quelques cas d'exécution

- IV-D-1. Formatage du système de fichier HDFS mis en place

- IV-D-2. Lancement des jobs Hadoop

- IV-D-3. Aperçu des interfaces d'administration du cluster Hadoop

- IV-D-4. Arrêt des jobs Hadoop

- V. Configuration du lien entre Hadoop et Eclipse

- V-A. Installation de Eclipse

- V-B. Téléchargement et installation du plugin Hadoop pour Eclipse

- V-C. Configuration du plugin Hadoop pour Eclipse

- V-D. Création d'un projet Hadoop sous Eclipse

- VI. Exécution d'un programme exemple: WordCount.jar

- VI-A. Bibliothèques à importer dans le projet

- VI-B. La classe WordCountMapper.java

- VI-C. La classe WordCountReducer.java

- VI-D. La classe WordCountDriver.java

- VI-E. Résultats de l'exécution du programme

- VII. Les potentielles erreurs et comment les résoudre

- VII-A. Arrêt inopiné du processus DataNode

- VII-B. Pas de permissions accordées pour accéder au cluster

- VII-C. L'erreur INPUT PATH does not exist

- VIII. Références

- IX. Remerciements

I - Introduction

À l'ère des Big Data, c'est la grande agitation dans les entreprises. Ces dernières n'ont jamais fait face à une quantité de données aussi importante. Plusieurs départements à savoir le marketing, la communication, les opérations, etc. s'intéressent à l'exploitation des données afin d'en extraire des business-values. En d'autres termes, il s'agit de l'information pertinente pour faire grandir le business de l'entreprise. Cette business-value est fonction du département et ne sera pas la même selon qu'on est dans le département x ou y.

Pour répondre à ce besoin d'exploitation de données massives, il s'avère que l'écosystème Hadoop serait la solution open source par excellence. Les raisons sont multiples : la communauté grandissante autour de cette technologie, l'implication des grandes firmes par la multiplication des distributions et sans oublier toute la propagande médiatique et je passe.

Je ne fais aucunement la publicité de la solution Hadoop, je relève juste des faits en partageant mon expérience, j'espère que vous comprenez ce que je veux dire . Cet article présente comment installer un cluster Hadoop à un nœud, l'intégration de Hadoop et Eclipse et les potentielles erreurs auxquelles peuvent être confrontés les débutants et enfin les techniques pour y faire face.

En règle générale, nous le verrons plus loin dans cet article, le framework Hadoop peut être déployé de trois façons en local mode, en mode pseudodistribué et en mode distribué complet. Nous avons choisi dans le cadre de cet article d'utiliser Hadoop sur un nœud pour les raisons suivantes qui sont plus ou moins pertinentes en fonction du besoin à couvrir :

- la mise en place d'un Proof Of Concept pour montrer que la solution que nous voulons développer est faisable. Dans la plupart des cas, pour montrer cela, on simule un environnement pour montrer la faisabilité. La simulation avec un nœud nous a suffi pour mettre en place notre POC ;

- les moyens financiers mis à notre disposition ne nous permettaient pas d'acquérir plusieurs machines afin de créer un réel cluster avec des nœuds distincts.

Lançons-nous dans cet univers qui sans doute nous réserve de belles surprises. Le voyage risque d'être très long, avez-vous pris votre tasse de café ?

II - Contexte

Cet article a été réalisé à la suite d'une étude et d'une analyse autour d'un sujet qui m'a été confié et qui était intitulé : je paraphrase, les bénéfices du Big Data et de la gestion centralisée des logs pour la détection de fraudes.

Cette étude a été menée dans une institution financière francilienne. Je m'abstiens de donner le nom pour des raisons de « non-publicité » et également de « sécurité ». L'étude que j'ai menée consistait :

- premièrement à étudier les solutions du marché en termes de gestion centralisée des logs (identification des logs, collecte des logs, standardisation des logs, analyse et indexation des logs et enfin corrélation des logs) pour répondre à un besoin business : l'optimisation de la détection de fraudes ;

- deuxièmement, proposer un modèle de mise en place de contrôles de sécurité en utilisant le modèle de conception et de programmation MapReduce.

Je ne fais pas un cours magistral sur la gestion centralisée des logs ou encore moins une mise en exergue de mes prouesses, loin de là. Bien que je n'hésiterai pas si l'occasion m'était offerte. Je n'irai pas plus loin. Pour ceux que cela intéresse, nous pouvons échanger et partager en off.

III - Prérequis pour la réalisation de ce tutoriel

Un ensemble de prérequis ont été nécessaires à la réalisation de ce tutoriel. Ils sont de plusieurs ordres :

- les connaissances théoriques nécessaires pour comprendre les notions abordées dans la suite de l'article telles qu'un cluster Hadoop, un NameNode, un DataNode, MapReduce, HDFS et autres. Car dans cet article, ces notions ne seront pas expliquées. Elles sont supposées être acquises. Le site internet http://hadoop.apache.org est suffisamment exhaustif sur ces notions et plus encore, un coup de chapeau à Mickael Baron qui a su donner un élan grâce à ces premiers articles. Les lire ici ;

- un ensemble de logiciels nécessaires pour la réalisation du tutoriel. Je vais énumérer tous les logiciels dans le paragraphe suivant ;

- une connaissance minimale en programmation, en Java, en Shell, en XML est également nécessaire pour comprendre les classes Java et le contenu des fichiers XML que nous allons écrire dans la suite.

III-A - Liste des outils et logiciels utilisés

Comme outils logiciels pour la réalisation de ce tutoriel, nous citerons :

- une machine virtuelle Linux RedHat. La distribution et la version utilisées sont données dans l'image suivante. Vous pouvez taper la commande suivante :

cat /etc/issue

Cependant, il faut noter que toute distribution Linux compatible GNU/Linux est supportée par la plateforme Hadoop ;

- le SSH est un protocole de communication sécurisé qui nous permet d'ouvrir un Shell sur une machine distante. Autrement dit, SSH permettra à son utilisateur de se connecter à distance sur une machine ou un serveur connaissant son adresse IP. Plus loin dans ce tutoriel, nous expliquerons comment le tester dans notre contexte.
L'utilitaire Putty est un client SSH. Il sera très important dans la mesure où il vous permettra de vous connecter à votre machine virtuelle depuis votre poste de travail. L'icône de Putty est donnée par l'image suivante :

- le service HTTPD doit être opérationnel sur la machine virtuelle. Il s'agit du service web qui puisse permettre de lancer une application web.

Pouvoir prendre la machine virtuelle à distance impose que le service SSHD soit opérationnel sur la machine virtuelle. Je peux reconnaitre que ce service fonctionne sur ma machine virtuelle en faisant la commande suivante :

ps -ef | grep -i sshd

Le résultat sur ma machine virtuelle est le suivant :

- la version de Hadoop que nous utilisons est la stable release 1.2.1. Dans la suite de l'article, nous expliquerons comment l'acquérir et comment l'installer pour en profiter pleinement. Il s'agit d'une simple archive.
Hadoop 1.2.1 est la version la plus stable de Hadoop qui implémente les concepts de base de Hadoop à savoir le NameNode, le SecondaryNameNode, le DataNode, le JobTracker, le TaskTracker. Il existe cependant une version de Hadoop qui introduit d'autres concepts comme YARN (MapReduce en version 2), les RessourceManager, le NodeManager, mais ces derniers ne font pas l'objet de cet article ;

- la version de Java à utiliser doit être au moins la JAVA 6, celle que j'ai utilisée pour la réalisation de ce tutoriel est donnée par la capture d'écran suivante :

Nous venons de lister les outils nécessaires à la réalisation de ce tutoriel. Lançons-nous dans la mise en œuvre proprement dite de notre cluster.

IV - Installation d'un cluster Hadoop à nœud unique

Je me suis inspiré de la documentation officielle de Hadoop (http://hadoop.apache.org/docs/r1.2.1/). J'ai aussi usé de mon expérience et des retours d'expérience des uns et des autres. Il en ressort le condensé suivant.

IV-A - Téléchargement de la version stable 1.2.1 de Hadoop

Le téléchargement de la version stable 1.2.1 de Hadoop est aussi simple que la copie d'un fichier. Vous pouvez suivre le lien suivant http://mirrors.koehn.com/apache/hadoop/common/ qui représente l'un des serveurs miroirs sur lesquels vous pouvez acquérir la version 1.2.1 de Hadoop. Toutefois, vous avez le choix de sélectionner un autre serveur.

IV-B - Création d'un utilisateur pour Hadoop

Pour faire les choses proprement, je vous recommande de créer un groupe d'utilisateurs « hadoop » et un utilisateur « hadoop » qui appartiendra à ce groupe. Ce dernier doit avoir tous les droits sur le répertoire /home/hadoop.

Vous avez une panoplie d'articles pour la création d'un groupe d'utilisateurs sous Linux. Celui-ci n'est pas mal : Les utilisateurs et leurs droits.

Pour changer d'utilisateur, dans mon contexte, j'ai utilisé la commande suivante. La capture d'écran en fait une illustration claire.

Dans mon cas, lorsque je créais l'utilisateur « hadoop », je n'ai pas pu faire une capture d'écran pour illustrer. Néanmoins, j'ai tout fait dans la suite avec l'utilisateur « hadoop » car il n'est pas aussi lourd qu'un éléphant jaune.

IV-C - Préparation de l'environnement

Une fois l'archive de Hadoop obtenue, il faut la copier dans le répertoire /home/hadoop et la décompresser. Une illustration en est faite avec l'image suivante.

Tout d'abord, j'ai changé d'utilisateur pour passer à l'utilisateur « hadoop ». Ensuite, j'ai fait la commande ls pour m'assurer que mon archive est bien dans mon répertoire /home/hadoop. Enfin, j'ai fait la commande tar pour décompresser mon archive avec les options -v pour le mode verbeux, et -f pour dire que je vais préciser le fichier à décompresser.

IV-C-1 - Mise à jour du fichier conf/hadoop-env.sh

Une fois que l'archive a été décompressée, le répertoire « hadoop » contenant tous les programmes nécessaires au fonctionnement de Hadoop est accessible. Nous devons informer Hadoop sur l'emplacement de Java sur notre machine virtuelle. Pour cela, nous devons modifier le fichier conf/hadoop-env.sh qui se trouve dans le répertoire « hadoop » issu de la décompression.

Nous faisons les commandes suivantes sur le prompt tel qu'illustré sur la capture d'écran suivante.

Après avoir exécuté les trois commandes suivantes :

1. pwd

2. cd hadoop

3. ls

on accède au contenu du répertoire « hadoop ». On remarque bel et bien l'existence du répertoire conf.

Pour modifier le fichier conf/hadoop-env.sh, je vais utiliser l'éditeur nano, pour éviter les ennuis avec l'éditeur vi qui est réservé aux experts (, je n'en suis pas un). L'image suivante en illustre la situation :

Vous devez ajouter la ligne concernant la configuration de la variable JAVA_HOME en fonction de la configuration de votre installation de Java. Pour mon cas, ma configuration est en encadré rouge. Voir capture d'écran.

La configuration de base étant prête, pour vous assurer que Hadoop est désormais fonctionnel sur votre machine virtuelle, il faut faire la commande suivante :

bin/hadoop

Vous devez voir apparaître un écran similaire au suivant :

Eurêka, nous avons réussi.

Il faut noter que le démarrage d'un cluster Hadoop peut se faire de plusieurs façons :

- en mode local : c'est le mode basique, où il n'y a qu'un seul processus qui tourne pour Hadoop ;

- en mode pseudo distribué : ici, on simule un cluster réel en utilisant une seule machine. Dans ce contexte, plusieurs processus Java sont lancés sur la même machine (même machine virtuelle Java également) pour simuler les processus opérant dans le monde Hadoop à savoir un NameNode, un SecondaryNameNode, un DataNode, un JobTracker et un TaskTracker. Ce qu'il faut garder à l'esprit est que tous ces processus sont lancés sur la même machine, il faut donc prendre en compte les ressources de votre machine si vous souhaitez simuler ce modèle. C'est ce mode que j'ai utilisé dans la réalisation de cet article ;

- en mode entièrement distribué : c'est le mode réel de cluster où tous les nœuds sont indépendants les uns des autres. Chaque processus tourne sur une machine virtuelle Java différente.

L'objectif ici n'est pas de faire un cours magistral sur les concepts de Hadoop ou sur la distribution des charges (confer cours de physique électrostatique : 1re année. Just for fun). La littérature est assez exhaustive sur le sujet.

Pour exécuter les processus Hadoop (autrement dit, démarrer notre cluster Hadoop) en mode pseudodistribué, nous devons encore faire des configurations supplémentaires. En s'inspirant de la configuration faite dans le fichier conf/hadoop-env.sh précédent, on fait de même pour les fichiers suivants : conf/core-site.xml, conf/hdfs-site.xml, conf/mapred-site.xml.

IV-C-2 - Mise à jour du fichier conf/core-site.xml

1. <configuration>

2. <property>

3. <name>fs.default.name</name>

4. <value>hdfs://localhost:9000</value>

5. </property>

6. </configuration>

Dans mon cas, pour faire exécuter mon programme, puisque mon utilisateur hadoop n'avait pas tous les droits sur mon répertoire /home/hadoop/hadoop/input, j'ai dû laisser la balise <value> ci-dessus vide pour que mon programme WordCount.jar puisse s'exécuter. J'en parlerai plus en détail dans les chapitres suivants notamment dans le chapitre Exécution d'un programme exemple : WordCount et dans le chapitre Les potentielles erreurs et comment les résoudre.

IV-C-3 - Mise à jour du fichier conf/hdfs-site.xml

1. <configuration>

2. <property>

3. <name>dfs.replication</name>

4. <value>1</value>

5. </property>

6. </configuration>

IV-C-4 - Mise à jour du fichier conf/mapred-site.xml

1. <configuration>

2. <property>

3. <name>mapred.job.tracker</name>

4. <value>localhost:9001</value>

5. </property>

6. </configuration>

Pour avancer, il faut vous assurer que vous pouvez accéder à votre machine virtuelle en faisant

1. ssh localhost

sans avoir besoin de mot de passe.

Si le mot de passe est demandé, vous devez exécuter les commandes suivantes pour la création d'une clé ssh afin de passer l'étape du mot de passe.

Dans mon cas, je n'ai pas eu besoin de faire ces deux commandes, peut-être ce problème de clé ssh avait au préalable été réglé par l'administrateur système de l'entreprise dans laquelle je travaillais.

IV-D - Quelques cas d'exécution

IV-D-1 - Formatage du système de fichier HDFS mis en place

Avant d'utiliser notre cluster Hadoop pour la première fois, il est recommandé de formater le système de fichier HDFS avant de démarrer les processus NameNode, SecondaryNameNode et DataNode. Pour lancer le formatage de notre HDFS, il faut faire la commande suivante :

bin/hadoop namenode -format.

Vous devez avoir à l'issue de la commande une fenêtre ressemblant à la suivante :

IV-D-2 - Lancement des jobs Hadoop

Pour démarrer tous les processus Hadoop à la fois, il suffit de faire la commande suivante :

bin/start-all.sh

La fenêtre suivante illustre le démarrage de services Hadoop.

Il ne faut pas perdre de vue que vous pouvez démarrer chaque processus à son tour en utilisant une autre commande qui est la suivante pour chaque service:

/bin/hadoop-daemon.sh start xxx

où xxx représente namenode, secondarynamenode, datanode, jobtracker, tasktracker.

L'exécution des jobs Hadoop génère des fichiers de logs dans le répertoire /home/hadoop/hadoop/logs qui correspond au répertoire %HADOOP_HOME%/logs si la configuration est faite dans la variable d'environnement PATH.

IV-D-3 - Aperçu des interfaces d'administration du cluster Hadoop

L'écran d'administration du système de fichiers est donné par la figure suivante : cette interface est accessible via le lien suivant :

NameNode -

L'écran du gestionnaire de jobs MapReduce est donné par la figure suivante : cette interface est accessible par le lien suivant :

JobTracker -

IV-D-4 - Arrêt des jobs Hadoop

L'arrêt des jobs Hadoop est rendu possible par l'utilisation de la commande suivante :

bin/stop-all.sh

Le résultat est le suivant :

V - Configuration du lien entre Hadoop et Eclipse

Lorsqu'on a pris la folle habitude de développer en utilisant les IDE, il n'est pas toujours évident de se remettre à écrire des programmes en utilisant un simple éditeur de texte et compiler en ligne de commande.

Fondamentalement, l'écriture des programmes MapReduce devrait se faire « from scratch ». Cependant, les développeurs de la communauté ont pensé créer des plugins pour faciliter le développement des Jobs MapReduce en utilisant les IDE.

Nous allons voir dans ce chapitre comment intégrer le plugin Hadoop dans Eclipse et développer plus efficacement les jobs MapReduce.

V-A - Installation de Eclipse

Je ne reviens plus sur l'installation de Eclipse qui est supposée acquise. Peu importe la version de Eclipse que vous avez, cela devrait à priori fonctionner. Pour la réalisation de cet article, j'ai dû utiliser la version Europa, mais j'ai également testé la version Luna et tout fonctionne à merveille.

Allez sur le site de Eclipse, téléchargez la version qui vous intéresse, décompressez l'archive obtenue et le tour est joué.

Pas assez compliqué, l'installation de Eclipse.

V-B - Téléchargement et installation du plugin Hadoop pour Eclipse

Le plugin Hadoop pour Eclipse se présente comme une archive JAR. Plusieurs sites internet offrent un lien pour le téléchargement de ladite archive. J'ai pris le soin de vous en lister quelques-uns :

https://dl.dropboxusercontent.com/u/717667/hadoop/hadoop-eclipse-plugin-1.2.1.jar

http://crzyjcky.com/2013/09/03/hadoop-eclipse-plugin/hadoop-eclipse-plugin-1-2-1-jar/

http://ordinarygeek.me/2013/09/12/hadoop-build-and-install-hadoop-1-2-1-eclipse-plugin/

J'espère que vous avez bien remarqué qu'il s'agit du plugin pour la version 1.2.1 de Hadoop. Chaque distribution de Hadoop a à coup sûr une version de plugin correspondant ou du moins devrait.

Noter également qu'il est facile de s'en passer du plugin en utilisant Maven avec les dépendances Hadoop et MRUnit. Malheureusement, dans le cadre de ce tutoriel, je n'ai pas expérimenté cette approche. Elle pourrait bien aider les uns et les autres à aller un peu plus loin dans cette aventure.

Téléchargez ce plugin et copiez-le dans un dossier de votre poste de travail.

V-C - Configuration du plugin Hadoop pour Eclipse

La configuration du plugin Hadoop pour Eclipse n'est pas plus difficile qu'un simple COPIER-COLLER. Ouvrez le dossier « plugin » de votre installation de Eclipse et y déposez-y l'archive du plugin. La capture d'écran suivante en illustre cette explication :

Remarquez bien, l'archive du plugin qui a été sélectionnée dans le dossier

« Eclipse-Europa/eclipse/plugins ». Ceci est une illustration de la situation sur mon poste de travail. Après avoir copié l'archive, renommez-la comme présenté dans la capture d'écran.

Enfin, redémarrez Eclipse.

Une fois que Eclipse a redémarré, vous devez voir apparaître dans le coin supérieur droit de Eclipse l'icône de l'éléphant violet comme le montre l'image suivante, preuve que le plugin a été pris en compte.

Désormais vous pouvez utiliser la perspective Hadoop pour écrire vos programmes MapReduce.

Cependant, la configuration n'est pas terminée. Nous devons renseigner Eclipse sur les paramètres de notre cluster qui est déjà fonctionnel.

Faites « Windows -> Show view ->MapReduce Locations», la fenêtre suivante apparaît:

Cliquez sur le petit éléphant violet pour configurer un nouveau cluster. La fenêtre suivante apparaît :

Cette fenêtre vous permet de saisir les paramètres de votre cluster. Vous avez deux onglets « Général » et « Advanced parameters ». Les informations que vous voyez là sont les informations propres à mon cluster. Vous devez renseigner les vôtres.

Désormais votre cluster est reconnu par Eclipse. Voir image suivante :

Vous avez ainsi la possibilité d'effectuer les opérations de base dans votre système de fichiers HDFS, créer, lister, renommer des répertoires, copier des fichiers, etc.

Dans l'onglet Project Explorer, vous pouvez voir un dossier en rapport avec mon cluster :

Le clic droit sur le cluster permet de faire plusieurs opérations dont nous n'allons pas détailler ici. À vous de découvrir.

V-D - Création d'un projet Hadoop sous Eclipse

Pour créer un projet, il faut faire

File -> New -> Project

Ensuite, il faut sélectionner Map/Reduce Project et renseigner tous les paramètres, le nom du projet, etc.

Toutefois, vous pouvez créer un projet classique Java et ajouter à ce projet les classes Mapper, Reducer et MapReduce Driver. Ces classes représentent des spécificités de MapReduce et vous permettent également de créer des projets MapReduce.

Dans mon cas, c'est la deuxième option que j'ai utilisée pour la création de mon projet WordCount. Je l'ai trouvée plus maniable et plus proche du Java que je connais. Tout simplement parce que je ne suis pas un expert de Hadoop.

VI - Exécution d'un programme exemple: WordCount.jar

VI-A - Bibliothèques à importer dans le projet

Écrire un programme MapReduce en utilisant Eclipse se fait de la même façon qu'écrire un programme Java classique. On crée le projet, on crée éventuellement les packages qui contiendront les classes du projet et ensuite, on crée les classes telles que nous les avons décrites dans les paragraphes suivants.

Toutefois pour qu'un programme MapReduce puisse compiler proprement sous Eclipse, il faut attacher au projet un ensemble de bibliothèques et nous avons pris la peine de lister l'ensemble de ces bibliothèques pour éviter au lecteur de se perdre dans la recherche des bibliothèques. La figure suivante présente la liste des bibliothèques nécessaires.

Le dossier « lib » contient l'ensemble de ces fichiers jars. Ils ont été référencés dans le projet à partir de ce dossier. Il faut noter que le dossier est dans le projet que vous devrez créer.

VI-B - La classe WordCountMapper.java

1. package fr.yimson.bigdata.lactool;

3. import java.io.IOException;

4. import java.util.StringTokenizer;

6. import org.apache.hadoop.io.IntWritable;

7. import org.apache.hadoop.io.LongWritable;

8. import org.apache.hadoop.io.Text;

9. import org.apache.hadoop.mapred.MapReduceBase;

10. import org.apache.hadoop.mapred.Mapper;

11. import org.apache.hadoop.mapred.OutputCollector;

12. import org.apache.hadoop.mapred.Reporter;

14. public class WordCountMapper extends MapReduceBase implements

15. Mapper<LongWritable, Text, Text, IntWritable> {

17. private final IntWritable one = new IntWritable(1);

18. private Text word = new Text();

20. //La classe de Map

21. @Override

22. public void map(LongWritable key, Text value,

23. OutputCollector<Text, IntWritable> output, Reporter reporter)

24. throws IOException {

26. // TODO Auto-generated method stub

27. String line = value.toString();

28. StringTokenizer itr = new StringTokenizer(line.toLowerCase());

29. while (itr.hasMoreTokens()) {

30. word.set(itr.nextToken());

31. output.collect(word, one);

32. }

33. }

35. }

VI-C - La classe WordCountReducer.java

1. package fr.yimson.bigdata.lactool;

3. import java.io.IOException;

4. import java.util.Iterator;

6. import org.apache.hadoop.io.IntWritable;

7. import org.apache.hadoop.io.Text;

8. import org.apache.hadoop.mapred.MapReduceBase;

9. import org.apache.hadoop.mapred.OutputCollector;

10. import org.apache.hadoop.mapred.Reducer;

11. import org.apache.hadoop.mapred.Reporter;

13. public class WordCountReducer extends MapReduceBase implements

14. Reducer<Text, IntWritable, Text, IntWritable> {

16. //La methode de Reduce

17. @Override

18. public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output,

19. Reporter reporter) throws IOException {

21. int sum = 0;

22. while (values.hasNext()){

23. sum += values.next().get();

24. }

25. output.collect(key, new IntWritable(sum));

26. }

28. }

VI-D - La classe WordCountDriver.java

1. package fr.yimson.bigdata.lactool;

3. import org.apache.hadoop.conf.Configuration;

4. import org.apache.hadoop.fs.Path;

5. import org.apache.hadoop.io.IntWritable;

6. import org.apache.hadoop.io.Text;

7. import org.apache.hadoop.mapred.FileInputFormat;

8. import org.apache.hadoop.mapred.FileOutputFormat;

9. import org.apache.hadoop.mapred.JobClient;

10. import org.apache.hadoop.mapred.JobConf;

11. import org.apache.hadoop.mapred.TextInputFormat;

12. import org.apache.hadoop.mapred.TextOutputFormat;

14. public class WordCountDriver {

16. public static void main(String[] args) {

18. Configuration config = new Configuration();

19. // config.set("fs.default.name", "hdfs://latdevweb02:9000/");

20. // config.set("mapred.job.tracker", "latdevweb02:9001");

22. JobClient client = new JobClient();

23. JobConf conf = new JobConf(config);

25. // TODO: specify output types and set jar

26. conf.setOutputKeyClass(Text.class);

27. conf.setOutputValueClass(IntWritable.class);

28. conf.setJar("WordCount.jar");

30. // TODO: specify a mapper and a reducer and the combiner

31. conf.setMapperClass(fr.yimson.bigdata.lactool.WordCountMapper.class);

32. conf.setCombinerClass(fr.yimson.bigdata.lactool.WordCountReducer.class);

33. conf.setReducerClass(fr.yimson.bigdata.lactool.WordCountReducer.class);

35. // TODO: specify input and output DIRECTORIES (not files)

36. conf.setInputFormat(TextInputFormat.class);

37. conf.setOutputFormat(TextOutputFormat.class);

39. // TODO: specify input and output DIRECTORIES (not files)

40. FileInputFormat.setInputPaths(conf, new Path(

41. "/home/hadoop/hadoop/input"));

42. FileOutputFormat.setOutputPath(conf, new Path(

43. "/home/hadoop/hadoop/output"));

45. System.out.println("Entrée dans le programme MAIN !!!");

47. client.setConf(conf);

48. try {

49. JobClient.runJob(conf);

50. System.out.println("Sortie du programme MAIN!!!");

51. } catch (Exception e) {

52. e.printStackTrace();

53. }

55. }

57. }

VI-E - Résultats de l'exécution du programme

Le résultat que vous voyez ci-dessous ne s'est pas obtenu d'un seul coup. J'ai débogué ce programme au point de me demander si je savais encore développer en Java. Après moult essais, je me suis rendu compte qu'il ne s'agit nullement de compétence en développement Java, mais qu'il s'agit de compréhension de l'environnement Hadoop. Hadoop est un framework et son rôle primordial est de faciliter la tâche du développeur.

Objectivement, je n'exprime ici que le fond de ma pensée et le ressenti que j'ai eu après cette expérience. J'ai eu l'impression d'une sorte de deux poids deux mesures. Soit l'écosystème Hadoop n'est pas encore assez mature pour permettre une mise en œuvre aisée, soit je n'ai pas encore la maturité nécessaire pour comprendre cet environnement. Toutefois comme je le dis, chacun pourrait avoir son point de vue différent du mien. Ne nous égarons pas.

Voici la sortie du résultat de l'exécution de mon programme.

1. -bash-4.1$ bin/hadoop jar WordCount.jar

2. Entr?e dans le programme MAIN !!!

3. 14/09/15 15:00:41 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the sam.

4. 14/09/15 15:00:41 INFO util.NativeCodeLoader: Loaded the native-hadoop library

5. 14/09/15 15:00:41 WARN snappy.LoadSnappy: Snappy native library not loaded

6. 14/09/15 15:00:41 INFO mapred.FileInputFormat: Total input paths to process : 17

7. 14/09/15 15:00:42 INFO mapred.JobClient: Running job: job_201409101141_0008

8. 14/09/15 15:00:43 INFO mapred.JobClient:  map 0% reduce 0%

9. 14/09/15 15:00:50 INFO mapred.JobClient:  map 11% reduce 0%

10. 14/09/15 15:00:53 INFO mapred.JobClient:  map 17% reduce 0%

11. 14/09/15 15:00:54 INFO mapred.JobClient:  map 23% reduce 0%

12. 14/09/15 15:00:56 INFO mapred.JobClient:  map 35% reduce 0%

13. 14/09/15 15:00:59 INFO mapred.JobClient:  map 47% reduce 0%

14. 14/09/15 15:01:02 INFO mapred.JobClient:  map 58% reduce 0%

15. 14/09/15 15:01:04 INFO mapred.JobClient:  map 64% reduce 0%

16. 14/09/15 15:01:05 INFO mapred.JobClient:  map 70% reduce 19%

17. 14/09/15 15:01:07 INFO mapred.JobClient:  map 82% reduce 19%

18. 14/09/15 15:01:09 INFO mapred.JobClient:  map 88% reduce 19%

19. 14/09/15 15:01:10 INFO mapred.JobClient:  map 94% reduce 19%

20. 14/09/15 15:01:11 INFO mapred.JobClient:  map 100% reduce 19%

21. 14/09/15 15:01:14 INFO mapred.JobClient:  map 100% reduce 27%

22. 14/09/15 15:01:15 INFO mapred.JobClient:  map 100% reduce 100%

23. 14/09/15 15:01:16 INFO mapred.JobClient: Job complete: job_201409101141_0008

24. 14/09/15 15:01:16 INFO mapred.JobClient: Counters: 29

25. 14/09/15 15:01:16 INFO mapred.JobClient:   Job Counters

26. 14/09/15 15:01:16 INFO mapred.JobClient:     Launched reduce tasks=1

27. 14/09/15 15:01:16 INFO mapred.JobClient:     SLOTS_MILLIS_MAPS=47158

28. 14/09/15 15:01:16 INFO mapred.JobClient:     Total time spent by all reduces waiting after reserving slots (ms)=0

29. 14/09/15 15:01:16 INFO mapred.JobClient:     Total time spent by all maps waiting after reserving slots (ms)=0

30. 14/09/15 15:01:16 INFO mapred.JobClient:     Rack-local map tasks=17

31. 14/09/15 15:01:16 INFO mapred.JobClient:     Launched map tasks=17

32. 14/09/15 15:01:16 INFO mapred.JobClient:     SLOTS_MILLIS_REDUCES=25510

33. 14/09/15 15:01:16 INFO mapred.JobClient:   File Input Format Counters

34. 14/09/15 15:01:16 INFO mapred.JobClient:     Bytes Read=34293

35. 14/09/15 15:01:16 INFO mapred.JobClient:   File Output Format Counters

36. 14/09/15 15:01:16 INFO mapred.JobClient:     Bytes Written=16014

37. 14/09/15 15:01:16 INFO mapred.JobClient:   FileSystemCounters

38. 14/09/15 15:01:16 INFO mapred.JobClient:     FILE_BYTES_READ=65480

39. 14/09/15 15:01:16 INFO mapred.JobClient:     HDFS_BYTES_READ=1715

40. 14/09/15 15:01:16 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=1080096

41. 14/09/15 15:01:16 INFO mapred.JobClient:   Map-Reduce Framework

42. 14/09/15 15:01:16 INFO mapred.JobClient:     Map output materialized bytes=31283

43. 14/09/15 15:01:16 INFO mapred.JobClient:     Map input records=956

44. 14/09/15 15:01:16 INFO mapred.JobClient:     Reduce shuffle bytes=31283

45. 14/09/15 15:01:16 INFO mapred.JobClient:     Spilled Records=3154

46. 14/09/15 15:01:16 INFO mapred.JobClient:     Map output bytes=46384

47. 14/09/15 15:01:16 INFO mapred.JobClient:     Total committed heap usage (bytes)=2796748800

48. 14/09/15 15:01:16 INFO mapred.JobClient:     CPU time spent (ms)=7520

49. 14/09/15 15:01:16 INFO mapred.JobClient:     Map input bytes=34293

50. 14/09/15 15:01:16 INFO mapred.JobClient:     SPLIT_RAW_BYTES=1715

51. 14/09/15 15:01:16 INFO mapred.JobClient:     Combine input records=3435

52. 14/09/15 15:01:16 INFO mapred.JobClient:     Reduce input records=1577

53. 14/09/15 15:01:16 INFO mapred.JobClient:     Reduce input groups=820

54. 14/09/15 15:01:16 INFO mapred.JobClient:     Combine output records=1577

55. 14/09/15 15:01:16 INFO mapred.JobClient:     Physical memory (bytes) snapshot=3333201920

56. 14/09/15 15:01:16 INFO mapred.JobClient:     Reduce output records=820

57. 14/09/15 15:01:16 INFO mapred.JobClient:     Virtual memory (bytes) snapshot=11883048960

58. 14/09/15 15:01:16 INFO mapred.JobClient:     Map output records=3435

59. Sortie du programme MAIN !!!

60. -bash-4.1$ bin/hadoop jar WordCount.jar

VII - Les potentielles erreurs et comment les résoudre

VII-A - Arrêt inopiné du processus DataNode

Le débogage d'un programme MapReduce suit les mêmes règles que vous avez toujours appliquées pour le débogage d'autres programmes. Vous avez toujours la possibilité d'insérer des points d'arrêt dans le programme, d'utiliser les instructions d'impression à l'écran et même la bibliothèque log4j, etc.

Cependant, il y a des erreurs qui apparaissent et qui ne peuvent toujours pas être détectées avec ces méthodes classiques. Nous présentons dans ce paragraphe une erreur qui arrive très souvent lorsqu'on simule un cluster Hadoop en mode pseudodistribué. Il s'agit de l'arrêt inopiné du processus DataNode. Ceci signifie purement et simplement que votre système de fichier HDFS n'est plus accessible.

Pour reconnaitre cette erreur, le message suivant peut apparaître lors de l'exécution d'un programme MapReduce :

1. il y a plusieurs tentatives de connexions au système de fichier HDFS qui se matérialisent par des messages tels qu'illustrés par la capture d'écran suivante :

1. après plusieurs tentatives de connexions (par défaut 10), le message d'erreur

1. Exception in thread “main” java.lang.RuntimeException: java.net.ConnectException: Call to localhost/127.0.0.1:9000 failed on connection option: java.net.ConnectException: Connection refused

1. pour se rendre bien compte de cela, il faut se positionner dans le répertoire d'installation de Hadoop et faire la commande suivante :

jps

Cette commande liste l'ensemble des processus Hadoop qui sont fonctionnels au moment où la commande est lancée. Une illustration est donnée par la capture d'écran suivante :

Pour résoudre le problème, il faut faire les actions suivantes dans l'ordre défini ci-dessous :

1. il faut tout d'abord arrêter tous les processus Hadoop qui sont démarrés actuellement. Nous avons montré au chapitre 2 de ce tutoriel comment arrêter les processus Hadoop ;

2. dans le cluster, il faut identifier le datanode qui pose problème, puisque nous sommes en mode pseudodistribué, le datanode c'est notre machine virtuelle. Le cluster entier est simulé sur notre machine virtuelle et tous les processus Hadoop tournent dessus. Une fois le datanode identifié, il faut supprimer le dossier DATA dans lequel Hadoop stocke les fichiers issus de l'exécution des programmes. Dans notre cas, il s'agit du répertoire /home/hadoop/hadoop/tmp/dfs/data/ ;

3. il faut par la suite lancer la commande de formatage du cluster. Nous avons dans le chapitre 2 expliqué comment procéder ;

4. enfin, il faut redémarrer les processus Hadoop comme présenté dans le chapitre 2.

Toutes ces opérations concourent à réinitialiser proprement le cluster. Après cela, il faut refaire la commande JPS, pour vous assurer que tout est rentré dans l'ordre.

VII-B - Pas de permissions accordées pour accéder au cluster

Cette erreur arrive lorsque l'utilisateur avec lequel vous lancez le programme MapReduce n'a pas suffisamment de droits pour écrire dans les répertoires du cluster Hadoop. Je vais expliquer le cas auquel j'ai été confronté.

En effet, le poste de travail sur lequel, j'avais installé tout mon environnement de développement était une machine Windows 7. Tout y était installé notamment Eclipse, plugin Hadoop, etc. Ma machine virtuelle était une machine RedHat comme présenté au départ. Dans mes premiers essais, je lançais l'exécution de mon programme MapReduce directement à partir de Eclipse, et j'ai fait face pendant plusieurs jours à l'erreur suivante :

1. 2014-09-04 14:00:55,050 ERROR [org.apache.hadoop.security.UserGroupInformation] - PriviledgedActionException as:gyimenyi041514 cause:org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=gyimenyi041514, access=WRITE, inode="staging":hadoop:supergroup:rwxr-xr-x

2. org.apache.hadoop.security.AccessControlException: org.apache.hadoop.security.AccessControlException: Permission denied: user=gyimenyi041514, access=WRITE, inode="staging":hadoop:supergroup:rwxr-xr-x

3. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

4. at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

5. at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)

6. at java.lang.reflect.Constructor.newInstance(Unknown Source)

7. at org.apache.hadoop.ipc.RemoteException.instantiateException(RemoteException.java:95)

8. at org.apache.hadoop.ipc.RemoteException.unwrapRemoteException(RemoteException.java:57)

9. at org.apache.hadoop.hdfs.DFSClient.mkdirs(DFSClient.java:1459)

10. at org.apache.hadoop.hdfs.DistributedFileSystem.mkdirs(DistributedFileSystem.java:362)

11. at org.apache.hadoop.mapreduce.JobSubmissionFiles.getStagingDir(JobSubmissionFiles.java:126)

12. at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:942)

13. at org.apache.hadoop.mapred.JobClient$2.run(JobClient.java:936)

14. at java.security.AccessController.doPrivileged(Native Method)

15. at javax.security.auth.Subject.doAs(Unknown Source)

16. at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)

17. at org.apache.hadoop.mapred.JobClient.submitJobInternal(JobClient.java:936)

18. at org.apache.hadoop.mapred.JobClient.submitJob(JobClient.java:910)

19. at org.apache.hadoop.mapred.JobClient.runJob(JobClient.java:1353)

20. at fr.societegenerale.bigdata.lactool.WordCountDriver.main(WordCountDriver.java:51)

21. Caused by: org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.security.AccessControlException: Permission denied: user=gyimenyi041514, access=WRITE, inode="mapred":hadoop:supergroup:rwxr-xr-x

22. at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:217)

23. at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:197)

24. at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:141)

25. at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkPermission(FSNamesystem.java:5758)

26. at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.checkAncestorAccess(FSNamesystem.java:5731)

27. at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirsInternal(FSNamesystem.java:2502)

28. at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirs(FSNamesystem.java:2469)

29. at org.apache.hadoop.hdfs.server.namenode.NameNode.mkdirs(NameNode.java:911)

30. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

31. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

32. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

33. at java.lang.reflect.Method.invoke(Method.java:601)

34. at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:587)

35. at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1432)

36. at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1428)

37. at java.security.AccessController.doPrivileged(Native Method)

38. at javax.security.auth.Subject.doAs(Subject.java:415)

39. at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190)

40. at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1426)

42. at org.apache.hadoop.ipc.Client.call(Client.java:1113)

43. at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:229)

44. at com.sun.proxy.$Proxy1.mkdirs(Unknown Source)

45. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

46. at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

47. at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

48. at java.lang.reflect.Method.invoke(Unknown Source)

49. at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:85)

50. at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:62)

51. at com.sun.proxy.$Proxy1.mkdirs(Unknown Source)

52. at org.apache.hadoop.hdfs.DFSClient.mkdirs(DFSClient.java:1457)

53. ... 11 more

Après quelques jours de réflexion, je suis arrivé à la compréhension suivante de la situation que j'explique ici.

Après plusieurs recherches sur des forums, j'ai compris qu'à partir de mon poste de travail, je suis connecté en tant que « gyimenyi041514 », et cet utilisateur n'avait aucune permission pour exécuter des jobs Hadoop sur la machine virtuelle RedHat.

L'autre problème est que le job MapReduce que je lançais à partir de Eclipse essayait de créer un dossier dans le répertoire nommé « staging » en utilisant mon username Windows « gyimenyi041514 ». Voir dans le message d'erreur précédent. Cependant, le dossier « staging » appartient à l'utilisateur « hadoop ». Ainsi, les actions de l'utilisateur « gyimenyi041514 » ne pouvaient qu'échouer.

Dans mon cas, pour remédier à cette situation, désormais pour tester mon programme, j'exportais mon programme sous forme d'un fichier Jar, que je déposais dans le dossier d'installation de Hadoop et que je pouvais lancer cette fois en utilisant la commande suivante :

-bash-4.1$ bin/hadoop jar WordCount.jar

Désormais, je pouvais tout faire avec l'utilisateur « hadoop » qui possède tous les droits. Facile n'est-ce pas, mais pas évident à voir. Je vous assure.

J'avais un enseignant qui disait, je le cite : « Mes chers enfants, qu'est-ce que l'informatique ? L'informatique c'est du bricolage … » et c'était très marrant. Je confirme cela aujourd'hui face à certaines situations. N'oublions pas notre objectif.

Je viens de présenter ici, les erreurs qui m'ont le plus tracassé. Il y en a eu d'autres, mais qui sont des erreurs classiques lorsqu'on exécute un programme Java en ligne de commande. Je fais allusion aux erreurs en rapport avec le fichier MANIFEST, en rapport avec la configuration du CLASSPATH, etc.

VII-C - L'erreur INPUT PATH does not exist

Une autre erreur susceptible d'arriver aux débutants dans l'écosystème Hadoop est l'erreur INPUT PATH DOES NOT EXIST. Nous présentons ci-dessous son contexte et comment y faire face. Comme toujours depuis le début de ce tutoriel, il s'agit de mon expérience, j'explique ce que j'ai fait pour y faire face. Je rappelle que je ne suis pas un expert, je m'intéresse et je me documente sur cet univers.

1. -bash-4.1$ bin/hadoop jar WordCount.jar

2. Entr?e dans le programme MAIN !!!

3. 14/09/11 12:06:10 WARN mapred.JobClient: Use GenericOptionsParser for parsing the arguments. Applications should implement Tool for the same.

4. 14/09/11 12:06:10 INFO util.NativeCodeLoader: Loaded the native-hadoop library

5. 14/09/11 12:06:10 WARN snappy.LoadSnappy: Snappy native library not loaded

6. 14/09/11 12:06:10 INFO mapred.JobClient: Cleaning up the staging area hdfs://latdevweb02:9000/user/hadoop/.staging/job_201409101141_0005

7. 14/09/11 12:06:10 ERROR security.UserGroupInformation: PriviledgedActionException as:hadoop cause:org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://latdevweb02:9000/home/hadoop/hadoop/input

8. org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://latdevweb02:9000/home/hadoop/hadoop/input

9. at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:197)

En effet, lorsqu'un programme MapReduce s'exécute, il lit des fichiers qui se trouvent dans un répertoire précis qui a été soit mentionné dans la configuration du fichier core/hdfs-site.xml, soit dans le programme proprement dit.

Ce qu'il faut noter est que lorsque ladite configuration est faite dans le programme directement, c'est celle-là qui est prioritaire. Pour résoudre le problème, et pouvoir exécuter le programme, j'ai dû supprimer la configuration que j'avais faite dans la balise <value> pour la propriété «fs.default.name » dans le fichier core/hdfs-site.xml.

Les leçons que je retiens de cette erreur sont que lorsque vous exécutez un programme Hadoop, vous devez vous assurer que les fondamentaux suivants sont garantis :

1. premièrement, le dossier OUTPUT (où les résultats doivent être stockés) ne doit pas exister, car il sera créé par le programme. Sauf si, vous l'avez défini explicitement dans le fichier conf/hdfs-site.xml ;

2. deuxièmement, si vous avez défini le dossier INPUT en utilisant l'instruction suivante dans votre programme :

FileInputFormat.setInputPaths(conf, new Path("/home/hadoop/hadoop/input"));

vous devez laisser vide la balise <value> de la propriété «fs.default.name » dans le fichier core/hdfs-site.xml.

VIII - Références

Pour réaliser cet article, je me suis inspiré de plusieurs articles et blogs en ligne. Je ne suis pas un expert de l'écosystème Hadoop. Toutefois, je m'intéresse et me documente sur le sujet. Cet article est le résultat d'une capitalisation des retours d'expérience çà et là. Je vais énumérer quelques liens, cependant, il faudra bien garder à l'esprit que la liste n'est pas exhaustive.

https://developer.yahoo.com/hadoop/tutorial/module7.html

http://www.michael-noll.com/tutorials/

https://mbaron.developpez.com/tutoriels/nosql/hadoop/installation-configuration-cluster-singlenode-avec-cloudera-cdh5/

http://hadoop.apache.org/docs/r1.2.1/single_node_setup.html

http://ordinarygeek.me/2013/09/12/hadoop-build-and-install-hadoop-1-2-1-eclipse-plugin/

http://crzyjcky.com/2013/09/03/hadoop-eclipse-plugin/hadoop-eclipse-plugin-1-2-1-jar/

http://solaimurugan.blogspot.fr/2014/04/configuring-eclipse-for-apache-hadoop.html

http://glebche.appspot.com/static/hadoop-ecosystem/mapreduce-job-java.html

http://stackoverflow.com/questions/17507670/basic-permissions-error-in-mr2

http://www.codeweblog.com/hadoop-study-notes-five-use-of-eclipse-plug-in/

http://www.hadoopinrealworld.com/fixing-org-apache-hadoop-security-accesscontrolexception-permission-denied/

http://pcbje.com/2012/08/submitting-hadoop-mapreduce-jobs-to-a-remote-jobtracker/

http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-multi-node-cluster/#java-io-ioexception-incompatible-namespaceids

http://stackoverflow.com/questions/20315862/hadoop-jar-jobtracker-is-in-safe-mode

IX - Remerciements

Je remercie particulièrement ces blogueurs et ces passionnés de la technologie Hadoop. Je remercie Mickael Baron pour ses conseils d'expert et pour sa relecture technique, sans oublier ClaudeLELOUP pour sa relecture orthographique. Leurs apports respectifs m'ont permis de produire cet article. Les brillants lecteurs de la communauté www.developpez.com et bien entendu tous ceux qui de près ou de loin m'ont aidé dans la production de ce travail.