Exemples Hadoop et Mapreduce : créer le premier programme dans Java
Dans ce didacticiel, vous apprendrez à utiliser Hadoop avec des exemples MapReduce. Les données d'entrée utilisées sont VentesJan2009.csv. Il contient des informations relatives aux ventes telles que le nom du produit, le prix, le mode de paiement, la ville, le pays du client, etc. L'objectif est de Découvrez le nombre de produits vendus dans chaque pays.
Premier programme Hadoop MapReduce
Maintenant dans ce Tutoriel MapReduce, nous allons créer notre premier Java Programme MapReduce :
Assurez-vous que Hadoop est installé. Avant de commencer le processus proprement dit, remplacez l'utilisateur par « hduser » (identifiant utilisé lors de la configuration Hadoop, vous pouvez passer à l'ID utilisateur utilisé lors de votre configuration de programmation Hadoop).
su - hduser_
Étape 1)
Créez un nouveau répertoire avec le nom MapReduceTutorial comme le montre l'exemple MapReduce ci-dessous
sudo mkdir MapReduceTutorial
Donner des autorisations
sudo chmod -R 777 MapReduceTutorial
SalesMapper.java
package SalesCountry; import java.io.IOException; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapred.*; public class SalesMapper extends MapReduceBase implements Mapper <LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); public void map(LongWritable key, Text value, OutputCollector <Text, IntWritable> output, Reporter reporter) throws IOException { String valueString = value.toString(); String[] SingleCountryData = valueString.split(","); output.collect(new Text(SingleCountryData[7]), one); } }
SalesCountryReducer.java
package SalesCountry; import java.io.IOException; import java.util.*; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapred.*; public class SalesCountryReducer extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text t_key, Iterator<IntWritable> values, OutputCollector<Text,IntWritable> output, Reporter reporter) throws IOException { Text key = t_key; int frequencyForCountry = 0; while (values.hasNext()) { // replace type of value with the actual type of our value IntWritable value = (IntWritable) values.next(); frequencyForCountry += value.get(); } output.collect(key, new IntWritable(frequencyForCountry)); } }
SalesCountryDriver.java
package SalesCountry; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.*; import org.apache.hadoop.mapred.*; public class SalesCountryDriver { public static void main(String[] args) { JobClient my_client = new JobClient(); // Create a configuration object for the job JobConf job_conf = new JobConf(SalesCountryDriver.class); // Set a name of the Job job_conf.setJobName("SalePerCountry"); // Specify data type of output key and value job_conf.setOutputKeyClass(Text.class); job_conf.setOutputValueClass(IntWritable.class); // Specify names of Mapper and Reducer Class job_conf.setMapperClass(SalesCountry.SalesMapper.class); job_conf.setReducerClass(SalesCountry.SalesCountryReducer.class); // Specify formats of the data type of Input and output job_conf.setInputFormat(TextInputFormat.class); job_conf.setOutputFormat(TextOutputFormat.class); // Set input and output directories using command line arguments, //arg[0] = name of input directory on HDFS, and arg[1] = name of output directory to be created to store the output file. FileInputFormat.setInputPaths(job_conf, new Path(args[0])); FileOutputFormat.setOutputPath(job_conf, new Path(args[1])); my_client.setConf(job_conf); try { // Run the job JobClient.runJob(job_conf); } catch (Exception e) { e.printStackTrace(); } } }
Vérifiez les autorisations de fichiers de tous ces fichiers
et si les autorisations de « lecture » sont manquantes, accordez la même chose.
Étape 2)
Exportez le chemin de classe comme indiqué dans l'exemple Hadoop ci-dessous
export CLASSPATH="$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-core-2.2.0.jar:$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-common-2.2.0.jar:$HADOOP_HOME/share/hadoop/common/hadoop-common-2.2.0.jar:~/MapReduceTutorial/SalesCountry/*:$HADOOP_HOME/lib/*"
Étape 3)
Compiler Java fichiers (ces fichiers sont présents dans le répertoire Final-MapReduceHandsOn). Ses fichiers de classe seront placés dans le répertoire du package
javac -d . SalesMapper.java SalesCountryReducer.java SalesCountryDriver.java
Cet avertissement peut être ignoré en toute sécurité.
Cette compilation créera un répertoire dans un répertoire courant nommé avec le nom du package spécifié dans le fichier source Java (c'est-à-dire VentesPays dans notre cas) et placez-y tous les fichiers de classe compilés.
Étape 4)
Créer un nouveau fichier Manifeste.txt
sudo gedit Manifest.txt
ajoutez-y les lignes suivantes,
Main-Class: SalesCountry.SalesCountryDriver
SalesCountry.SalesCountryDriver est le nom de la classe principale. Veuillez noter que vous devez appuyer sur la touche Entrée à la fin de cette ligne.
Étape 5)
Créer un fichier Jar
jar cfm ProductSalePerCountry.jar Manifest.txt SalesCountry/*.class
Vérifiez que le fichier jar est créé
Étape 6)
Démarrer Hadoop
$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh
Étape 7)
Copiez le fichier VentesJan2009.csv développement ~/inputMapReduce
Maintenant, utilisez la commande ci-dessous pour copier ~/inputMapReduce vers HDFS.
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal ~/inputMapReduce /
Nous pouvons ignorer cet avertissement en toute sécurité.
Vérifiez si un fichier est réellement copié ou non.
$HADOOP_HOME/bin/hdfs dfs -ls /inputMapReduce
Étape 8)
Exécuter le travail MapReduce
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
Cela créera un répertoire de sortie nommé mapreduce_output_sales sur HDFS. Le contenu de ce répertoire sera un fichier contenant les ventes de produits par pays.
Étape 9)
Le résultat peut être vu via l'interface de commande comme suit :
$HADOOP_HOME/bin/hdfs dfs -cat /mapreduce_output_sales/part-00000
Les résultats peuvent également être consultés via une interface Web comme-
Ouvrez r dans un navigateur Web.
Sélectionnez maintenant 'Parcourir le système de fichiers' et naviguez jusqu'à /mapreduce_output_sales
Ouvert pièce-r-00000
Explication de la classe SalesMapper
Dans cette section, nous comprendrons la mise en œuvre de SalesMapper classe.
1. Nous commençons par spécifier un nom de package pour notre classe. VentesPays est le nom de notre package. Veuillez noter que la sortie de la compilation, SalesMapper.class ira dans un répertoire nommé par ce nom de package : VentesPays.
Ensuite, nous importons des packages de bibliothèque.
L'instantané ci-dessous montre une implémentation de SalesMapper classer-
Explication du code exemple :
1. Définition de la classe SalesMapper-
classe publique SalesMapper étend MapReduceBase implémente Mapper {
Chaque classe de mappeur doit être étendue à partir de MapRéduireBase classe et il doit implémenter Cartographe interface.
2. Définir la fonction « carte » -
public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException
La partie principale de la classe Mapper est un 'carte()' méthode qui accepte quatre arguments.
A chaque appel à 'carte()' méthode, un valeur clé paire ('clé' et le 'évaluer' dans ce code) est transmis.
'carte()' La méthode commence par diviser le texte d’entrée qui est reçu comme argument. Il utilise le tokenizer pour diviser ces lignes en mots.
String valueString = value.toString(); String[] SingleCountryData = valueString.split(",");
Ici, ',' est utilisé comme délimiteur.
Après cela, une paire est formée en utilisant un enregistrement au 7ème index du tableau 'Données d'un seul pays' et une valeur «1 '.
output.collect(new Text(SingleCountryData[7]), un);
Nous choisissons l'enregistrement au 7ème indice car nous avons besoin Pays données et il est situé au 7ème index du tableau 'Données d'un seul pays'.
Veuillez noter que nos données d'entrée sont dans le format ci-dessous (où Pays est à 7th index, avec 0 comme index de départ) -
Date_de la transaction, Produit, Prix, Type_de paiement, Nom, Ville, État,Pays,Compte_Créé,Dernière_Connexion,Latitude,Longitude
Une sortie du mappeur est à nouveau un valeur clé paire qui est sortie en utilisant 'collecter()' méthode de 'Collecteur de sortie'.
Explication de la classe SalesCountryReducer
Dans cette section, nous comprendrons la mise en œuvre de SalesCountryRéducteur classe.
1. Nous commençons par spécifier un nom de package pour notre classe. VentesPays est le nom de notre package. Veuillez noter que la sortie de la compilation, SalesCountryReducer.class ira dans un répertoire nommé par ce nom de package : VentesPays.
Ensuite, nous importons des packages de bibliothèque.
L'instantané ci-dessous montre une implémentation de SalesCountryRéducteur classer-
Explication du code :
1. Définition de la classe SalesCountryReducer-
classe publique SalesCountryReducer étend MapReduceBase implémente Réducteur {
Ici, les deux premiers types de données, 'Texte' et le 'IntInscriptible' sont le type de données de la valeur-clé d'entrée du réducteur.
La sortie du mappeur se présente sous la forme de , . Cette sortie du mappeur devient une entrée dans le réducteur. Donc, pour s'aligner sur son type de données, Texte et le IntÉcrit sont utilisés ici comme type de données.
Les deux derniers types de données, « Texte » et « IntWritable » sont des types de données de sortie générés par le réducteur sous la forme d'une paire clé-valeur.
Chaque classe de réduction doit être étendue de MapRéduireBase classe et il doit implémenter Moulure de Réduction interface.
2. Définir la fonction « réduire » -
public void reduce( Text t_key, Iterator<IntWritable> values, OutputCollector<Text,IntWritable> output, Reporter reporter) throws IOException {
Une contribution au réduire() La méthode est une clé avec une liste de plusieurs valeurs.
Par exemple, dans notre cas, ce sera-
, , , , , .
Ceci est donné au réducteur comme
Ainsi, pour accepter des arguments de cette forme, deux premiers types de données sont utilisés, à savoir. Texte et le Itérateur. Texte est un type de données de clé et Itérateur est un type de données pour la liste de valeurs pour cette clé.
L'argument suivant est du type Collecteur de sortie qui collecte la sortie de la phase réducteur.
réduire() La méthode commence par copier la valeur clé et initialiser le nombre de fréquences à 0.
Clé de texte = t_key ;
int fréquencePourPays = 0 ;
Ensuite, en utilisant 'alors que' boucle, nous parcourons la liste des valeurs associées à la clé et calculons la fréquence finale en résumant toutes les valeurs.
while (values.hasNext()) { // replace type of value with the actual type of our value IntWritable value = (IntWritable) values.next(); frequencyForCountry += value.get(); }
Maintenant, nous transmettons le résultat au collecteur de sortie sous la forme de clé et obtenu compte de fréquence.
Le code ci-dessous fait ceci-
output.collect(key, new IntWritable(frequencyForCountry));
Explication de la classe SalesCountryDriver
Dans cette section, nous comprendrons la mise en œuvre de VentesPaysDriver classe
1. Nous commençons par spécifier un nom de package pour notre classe. VentesPays est le nom de notre package. Veuillez noter que la sortie de la compilation, SalesCountryDriver.class ira dans le répertoire nommé par ce nom de package : VentesPays.
Voici une ligne spécifiant le nom du package suivi du code pour importer les packages de bibliothèque.
2. Définissez une classe de pilote qui créera un nouveau travail client, un objet de configuration et publiera les classes Mapper et Réducteur.
La classe du pilote est responsable de la configuration de notre tâche MapReduce pour qu'elle s'exécute dans Hadoop. Dans cette classe, on précise nom du travail, type de données d'entrée/sortie et noms des classes de mappeur et de réducteur.
3. Dans l'extrait de code ci-dessous, nous définissons les répertoires d'entrée et de sortie qui sont utilisés respectivement pour consommer l'ensemble de données d'entrée et produire la sortie.
argument[0] et le argument[1] sont les arguments de ligne de commande passés avec une commande donnée dans MapReduce, c'est-à-dire :
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
4. Déclenchez notre travail
Le code ci-dessous démarre l'exécution du travail MapReduce.
try { // Run the job JobClient.runJob(job_conf); } catch (Exception e) { e.printStackTrace(); }