Exemples Hadoop et Mapreduce : créer le premier programme en 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 programme Java MapReduce :

Premier programme Hadoop MapReduce

Données de ventesJan2009

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_

Premier programme Hadoop MapReduce

Étape 1)

Créez un nouveau répertoire avec le nom MapReduceTutorial comme le montre l'exemple MapReduce ci-dessous

sudo mkdir MapReduceTutorial

Premier programme Hadoop MapReduce

Donner des autorisations

sudo chmod -R 777 MapReduceTutorial

Premier programme Hadoop MapReduce

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();
        }
    }
}

Téléchargez les fichiers ici

Premier programme Hadoop MapReduce

Vérifiez les autorisations de fichiers de tous ces fichiers

Premier programme Hadoop MapReduce

et si les autorisations de « lecture » sont manquantes, accordez la même chose.

Premier programme Hadoop MapReduce

É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/*"

Premier programme Hadoop MapReduce

É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

Premier programme Hadoop MapReduce

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.

Premier programme Hadoop MapReduce

Étape 4)

Créer un nouveau fichier Manifeste.txt

sudo gedit Manifest.txt

ajouter un suiviwing des lignes vers lui,

Main-Class: SalesCountry.SalesCountryDriver

Premier programme Hadoop MapReduce

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

Premier programme Hadoop MapReduce

Vérifiez que le fichier jar est créé

Premier programme Hadoop MapReduce

É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 /

Premier programme Hadoop MapReduce

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

Premier programme Hadoop MapReduce

Étape 8)

Exécuter le travail MapReduce

$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales

Premier programme Hadoop MapReduce

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

Premier programme Hadoop MapReduce

Les résultats peuvent également être consultés via une interface Web comme-

Ouvrez r dans un navigateur Web.

Premier programme Hadoop MapReduce

Sélectionnez maintenant 'Parcourir le système de fichiers' et naviguez jusqu'à /mapreduce_output_sales

Premier programme Hadoop MapReduce

Ouvert pièce-r-00000

Premier programme Hadoop MapReduce

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 de la classe SalesMapper

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 'é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 de la classe SalesCountryReducer

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 '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 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, viz., Texte et 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 key 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.

Explication de la classe SalesCountryDriver

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.

Explication de la classe SalesCountryDriver

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 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

Explication de la classe SalesCountryDriver

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();
}