Hadoop & Mapreduce-exempel: Skapa första program i Java

Innehållsförteckning:

Anonim

I den här handledningen lär du dig att använda Hadoop med MapReduce-exempel. Ingångsdata som används är SalesJan2009.csv. Den innehåller försäljningsrelaterad information som produktnamn, pris, betalningsläge, stad, kundland etc. Målet är att ta reda på antalet produkter som säljs i varje land.

I den här handledningen lär du dig-

  • Första Hadoop MapReduce-programmet
  • Förklaring av SalesMapper-klass
  • Förklaring av SalesCountryReducer-klass
  • Förklaring av SalesCountryDriver-klass

Första Hadoop MapReduce-programmet

Nu i denna MapReduce-handledning skapar vi vårt första Java MapReduce-program:

Data från SalesJan2009

Se till att du har Hadoop installerat. Innan du börjar med den faktiska processen, byt användare till 'hduser' (id som används under Hadoop-konfiguration, du kan växla till användar-ID som användes under din Hadoop-programmeringskonfiguration).

su - hduser_

Steg 1)

Skapa en ny katalog med namnet MapReduceTutorial som shwon i nedanstående MapReduce-exempel

sudo mkdir MapReduceTutorial

Ge behörigheter

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  {private final static IntWritable one = new IntWritable(1);public void map(LongWritable key, Text value, OutputCollector  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 {public void reduce(Text t_key, Iterator values, OutputCollector 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 valueIntWritable 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 jobJobConf job_conf = new JobConf(SalesCountryDriver.class);// Set a name of the Jobjob_conf.setJobName("SalePerCountry");// Specify data type of output key and valuejob_conf.setOutputKeyClass(Text.class);job_conf.setOutputValueClass(IntWritable.class);// Specify names of Mapper and Reducer Classjob_conf.setMapperClass(SalesCountry.SalesMapper.class);job_conf.setReducerClass(SalesCountry.SalesCountryReducer.class);// Specify formats of the data type of Input and outputjob_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 jobJobClient.runJob(job_conf);} catch (Exception e) {e.printStackTrace();}}}

Ladda ner filer här

Kontrollera filbehörigheterna för alla dessa filer

och om "läsbehörigheter" saknas, bevilja samma-

Steg 2)

Exportera klassvägen enligt nedanstående Hadoop-exempel

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

Steg 3)

Kompilera Java-filer (dessa filer finns i katalogen Final-MapReduceHandsOn ). Dess klassfiler läggs i paketkatalogen

javac -d . SalesMapper.java SalesCountryReducer.java SalesCountryDriver.java

Denna varning kan ignoreras säkert.

Denna sammanställning skapar en katalog i en aktuell katalog med namnet på paketnamnet som anges i java-källfilen (dvs. SalesCountry i vårt fall) och placerar alla kompilerade klassfiler i den.

Steg 4)

Skapa en ny fil Manifest.txt

sudo gedit Manifest.txt

lägg till följande rader till det,

Main-Class: SalesCountry.SalesCountryDriver

SalesCountry.SalesCountryDriver är namnet på huvudklassen. Observera att du måste trycka på Enter-tangenten i slutet av denna rad.

Steg 5)

Skapa en Jar-fil

jar cfm ProductSalePerCountry.jar Manifest.txt SalesCountry/*.class

Kontrollera att jar-filen har skapats

Steg 6)

Starta Hadoop

$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh

Steg 7)

Kopiera filen SalesJan2009.csv till ~ / inputMapReduce

Använd nu kommandot nedan för att kopiera ~ / inputMapReduce till HDFS.

$HADOOP_HOME/bin/hdfs dfs -copyFromLocal ~/inputMapReduce /

Vi kan säkert ignorera denna varning.

Kontrollera om en fil faktiskt kopieras eller inte.

$HADOOP_HOME/bin/hdfs dfs -ls /inputMapReduce

Steg 8)

Kör MapReduce-jobb

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

Detta skapar en utdatakatalog med namnet mapreduce_output_sales på HDFS. Innehållet i denna katalog är en fil som innehåller produktförsäljning per land.

Steg 9)

Resultatet kan ses genom kommandogränssnittet som,

$HADOOP_HOME/bin/hdfs dfs -cat /mapreduce_output_sales/part-00000

Resultaten kan också ses via ett webbgränssnitt som-

Öppna r i en webbläsare.

Välj nu "Bläddra i filsystemet" och navigera till / mapreduce_output_sales

Öppna del-r-00000

Förklaring av SalesMapper-klass

I detta avsnitt kommer vi att förstå implementeringen av SalesMapper- klassen.

1. Vi börjar med att ange ett paketnamn för vår klass. SalesCountry är ett namn på vårt paket. Observera att produktionen av kompilering, SalesMapper.class kommer att gå till en katalog med namnet på detta paketnamn: SalesCountry .

Följt av detta importerar vi bibliotekspaket.

Nedanstående ögonblicksbild visar en implementering av SalesMapper klass-

Exempel på kodförklaring:

1. Definition av SalesMapper klass-

public class SalesMapper utökar MapReduceBase implementerar Mapper {

Varje mapparklass måste utökas från MapReduceBase- klassen och den måste implementera Mapper- gränssnittet.

2. Definiera 'kartfunktion'

public void map(LongWritable key,Text value,OutputCollector output,Reporter reporter) throws IOException

Huvuddelen av Mapper-klassen är en "map ()" -metod som accepterar fyra argument.

Vid varje anrop till "map ()" -metoden skickas ett nyckel-värdepar ( "tangent" och "värde" i den här koden).

metoden 'map ()' börjar med att dela in inmatad text som tas emot som ett argument. Den använder tokenizer för att dela upp dessa rader i ord.

String valueString = value.toString();String[] SingleCountryData = valueString.split(",");

Här används ',' som avgränsare.

Efter detta bildas ett par med en post vid 7: e index för array 'SingleCountryData' och ett värde '1' .

output.collect (ny text (SingleCountryData [7]), en);

Vi väljer post vid 7: e index eftersom vi behöver landdata och den ligger vid 7: e index i array 'SingleCountryData' .

Observera att våra ingångsdata är i nedanstående format (där Land är på 7: e index, med 0 som startindex) -

Transaktionsdatum, produkt, pris, betalningstyp, namn, stad, stat, land , konto_skapat, senaste_inloggning, latitud, longitud

En utdata från mapparen är återigen ett nyckel-värdepar som matas ut med metoden 'collect ()' i 'OutputCollector' .

Förklaring av SalesCountryReducer-klass

I det här avsnittet kommer vi att förstå implementeringen av SalesCountryReducer- klassen.

1. Vi börjar med att ange ett paketnamn för vår klass. SalesCountry är ett namn på vårt paket. Observera att produktionen av kompilering, SalesCountryReducer.class kommer att gå in i en katalog som namnges av detta paketnamn: SalesCountry .

Följt av detta importerar vi bibliotekspaket.

Nedanstående ögonblicksbild visar en implementering av SalesCountryReducer- klass-

Kodförklaring:

1. Definition av SalesCountryReducer-klass-

public class SalesCountryReducer utökar MapReduceBase implementerar Reducer {

Här är de två första datatyperna, 'Text' och 'IntWritable', datatyp för inmatningsnyckelvärde till reduceraren.

Utdata från mapparen är i form av , . Denna utdata från mapparen blir ingång till reduceringsenheten. Så för att anpassa sig till dess datatyp används Text och IntWritable som datatyp här.

De två sista datatyperna, 'Text' och 'IntWritable' är datatyp för utdata som genereras av reduceraren i form av nyckel-värdepar.

Varje reduceringsklass måste utvidgas från MapReduceBase- klass och den måste implementera Reducer- gränssnitt.

2. Definiera "reducera" funktion-

public void reduce( Text t_key,Iterator values,OutputCollector output,Reporter reporter) throws IOException {

En inmatning till reduceringsmetoden () är en nyckel med en lista med flera värden.

I vårt fall kommer det till exempel att

, , , , , .

Detta ges till reduceraren som

Så, för att acceptera argument av detta formulär används de första två datatyperna, nämligen Text och Iterator . Text är en datatyp av nyckel och Iterator är en datatyp för en lista över värden för den nyckeln.

Nästa argument är av typen OutputCollector som samlar utdata från reduceringsfas.

reducera () -metoden börjar med att kopiera nyckelvärde och initiera frekvensräkning till 0.

Textnyckel = t_key; int-frekvensForCountry = 0;

Sedan använder vi ' while' -slingan igenom listan över värden associerade med nyckeln och beräknar den slutliga frekvensen genom att summera alla värden.

 while (values.hasNext()) {// replace type of value with the actual type of our valueIntWritable value = (IntWritable) values.next();frequencyForCountry += value.get();}

Nu skjuter vi resultatet till utgångssamlaren i form av nyckel och erhållen frekvensräkning .

Nedanstående kod gör detta-

output.collect(key, new IntWritable(frequencyForCountry));

Förklaring av SalesCountryDriver-klass

I det här avsnittet kommer vi att förstå implementeringen av SalesCountryDriver- klassen

1. Vi börjar med att ange ett paketnamn för vår klass. SalesCountry är ett namn på vårt paket. Observera att produktionen av kompilering, SalesCountryDriver.class kommer att gå till katalogen med namnet på detta paketnamn: SalesCountry .

Här är en rad som anger paketnamn följt av kod för att importera bibliotekspaket.

2. Definiera en förarklass som skapar ett nytt klientjobb, konfigurationsobjekt och annonserar Mapper- och Reducer-klasser.

Förarklassen ansvarar för att vårt MapReduce-jobb körs i Hadoop. I den här klassen anger vi jobbnamn , datatyp för in- / utgång och namn på mapper- och reducerklasser .

3. I kodavsnittet nedan anger vi inmatnings- och utdatakataloger som används för att konsumera inmatningsdataset och producera utdata.

arg [0] och arg [1] är kommandoradsargumenten som skickas med ett kommando som ges i MapReduce hands-on, dvs.

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

4. Utlös vårt jobb

Nedanför kodstart körning av MapReduce jobb-

try {// Run the jobJobClient.runJob(job_conf);} catch (Exception e) {e.printStackTrace();}