In deze tutorial leer je Hadoop gebruiken met MapReduce-voorbeelden. De gebruikte invoergegevens zijn SalesJan2009.csv. Het bevat verkoopgerelateerde informatie zoals productnaam, prijs, betalingsmodus, stad, land van klant enz. Het doel is om het aantal verkochte producten in elk land te achterhalen.
In deze tutorial leer je-
- Eerste Hadoop MapReduce-programma
- Uitleg van SalesMapper Class
- Verklaring van SalesCountryReducer Class
- Uitleg van SalesCountryDriver Class
Eerste Hadoop MapReduce-programma
Nu zullen we in deze MapReduce-zelfstudie ons eerste Java MapReduce-programma maken:
Zorg ervoor dat Hadoop is geïnstalleerd. Voordat u met het eigenlijke proces begint, wijzigt u de gebruiker in 'hduser' (id gebruikt tijdens de Hadoop-configuratie, u kunt overschakelen naar de gebruikers-id die werd gebruikt tijdens uw Hadoop-programmeerconfiguratie).
su - hduser_
Stap 1)
Maak een nieuwe map met de naam MapReduceTutorial zoals weergegeven in het onderstaande MapReduce-voorbeeld
sudo mkdir MapReduceTutorial
Geef toestemming
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();}}}
Download bestanden hier
Controleer de bestandsrechten van al deze bestanden
en als 'lees'-machtigingen ontbreken, verleen dan dezelfde-
Stap 2)
Export classpath zoals getoond in het onderstaande Hadoop-voorbeeld
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/*"
Stap 3)
Compileer Java-bestanden (deze bestanden zijn aanwezig in de directory Final-MapReduceHandsOn ). De klassebestanden worden in de pakketmap geplaatst
javac -d . SalesMapper.java SalesCountryReducer.java SalesCountryDriver.java
Deze waarschuwing kan veilig worden genegeerd.
Deze compilatie zal een map aanmaken in een huidige map met de naam van de pakketnaam gespecificeerd in het Java-bronbestand (dwz SalesCountry in ons geval) en alle gecompileerde klassebestanden daarin plaatsen.
Stap 4)
Maak een nieuw bestand Manifest.txt
sudo gedit Manifest.txt
voeg de volgende regels eraan toe,
Main-Class: SalesCountry.SalesCountryDriver
SalesCountry.SalesCountryDriver is de naam van de hoofdklasse. Houd er rekening mee dat u aan het einde van deze regel op de Enter-toets moet drukken.
Stap 5)
Maak een Jar-bestand
jar cfm ProductSalePerCountry.jar Manifest.txt SalesCountry/*.class
Controleer of het jar-bestand is gemaakt
Stap 6)
Start Hadoop
$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh
Stap 7)
Kopieer het bestand SalesJan2009.csv naar ~ / inputMapReduce
Gebruik nu de onderstaande opdracht om ~ / inputMapReduce naar HDFS te kopiëren.
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal ~/inputMapReduce /
We kunnen deze waarschuwing gerust negeren.
Controleer of een bestand daadwerkelijk is gekopieerd of niet.
$HADOOP_HOME/bin/hdfs dfs -ls /inputMapReduce
Stap 8)
Voer de MapReduce-taak uit
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
Hiermee wordt een uitvoermap gemaakt met de naam mapreduce_output_sales op HDFS. De inhoud van deze directory is een bestand met de productverkopen per land.
Stap 9)
Het resultaat is te zien via de opdrachtinterface als,
$HADOOP_HOME/bin/hdfs dfs -cat /mapreduce_output_sales/part-00000
Resultaten kunnen ook worden bekeken via een webinterface als-
Open r in een webbrowser.
Selecteer nu 'Browse the filesystem' en navigeer naar / mapreduce_output_sales
Open deel-r-00000
Uitleg van SalesMapper Class
In deze sectie zullen we de implementatie van de SalesMapper- klasse begrijpen .
1. We beginnen met het specificeren van een pakketnaam voor onze klas. SalesCountry is een naam van ons pakket. Houd er rekening mee dat de uitvoer van compilatie, SalesMapper.class , naar een map gaat met de naam van deze pakketnaam: SalesCountry .
Daarna importeren we bibliotheekpakketten.
Onderstaande snapshot toont een implementatie van SalesMapper class-
Voorbeeldcode Uitleg:
1. SalesMapper Class Definition-
openbare klasse SalesMapper breidt MapReduceBase uit en implementeert Mapper
Elke mapper-klasse moet worden uitgebreid vanuit de MapReduceBase- klasse en moet de Mapper- interface implementeren .
2. 'kaart'-functie definiëren
public void map(LongWritable key,Text value,OutputCollectoroutput,Reporter reporter) throws IOException
Het grootste deel van de Mapper-klasse is een 'map ()' - methode die vier argumenten accepteert.
Bij elke aanroep van de methode 'map ()' wordt een sleutel / waarde- paar ( 'sleutel' en 'waarde' in deze code) doorgegeven.
De methode 'map ()' begint met het splitsen van invoertekst die als argument wordt ontvangen. Het gebruikt de tokenizer om deze regels in woorden te splitsen.
String valueString = value.toString();String[] SingleCountryData = valueString.split(",");
Hier wordt ',' gebruikt als scheidingsteken.
Hierna wordt een paar gevormd met behulp van een record op de 7e index van array 'SingleCountryData' en een waarde '1' .
output.collect (nieuwe tekst (SingleCountryData [7]), een);
We kiezen voor record op de 7de index want we moeten Country data en het is gelegen op de 7e-index reeks 'SingleCountryData' .
Houd er rekening mee dat onze invoergegevens de onderstaande indeling hebben (waarbij Land op de 7e index staat, met 0 als startindex) -
Transaction_date, Product, Price, Payment_Type, Name, City, State, Country , Account_created, Last_Login, Latitude, Longitude
Een uitvoer van mapper is weer een sleutel / waarde- paar dat wordt uitgevoerd met de 'collect ()' methode van 'OutputCollector' .
Verklaring van SalesCountryReducer Class
In deze sectie zullen we de implementatie van de SalesCountryReducer- klasse begrijpen .
1. We beginnen met het specificeren van een naam van het pakket voor onze klas. SalesCountry is een naam van ons pakket. Houd er rekening mee dat de uitvoer van de compilatie, SalesCountryReducer.class , naar een map gaat met de naam van deze pakketnaam: SalesCountry .
Daarna importeren we bibliotheekpakketten.
Onderstaande snapshot toont een implementatie van SalesCountryReducer class-
Code Verklaring:
1. SalesCountryReducer Class Definition-
openbare klasse SalesCountryReducer breidt MapReduceBase uit implementeert Reducer
Hier zijn de eerste twee gegevenstypen, 'Tekst' en 'IntWritable' , het gegevenstype van de invoersleutelwaarde naar het reductiemiddel.
De uitvoer van mapper is in de vorm van
De laatste twee gegevenstypen, 'Tekst' en 'IntWritable', zijn gegevenstype uitvoer gegenereerd door reducer in de vorm van een sleutel-waardepaar.
Elke reducer-klasse moet worden uitgebreid vanuit de MapReduceBase- klasse en moet de Reducer- interface implementeren .
2. De functie 'verminderen' definiëren
public void reduce( Text t_key,Iteratorvalues,OutputCollector output,Reporter reporter) throws IOException {
Een invoer voor de methode reduce () is een sleutel met een lijst met meerdere waarden.
In ons geval zal het bijvoorbeeld
Dit wordt aan reducer gegeven als
Dus om argumenten van deze vorm te accepteren, worden de eerste twee gegevenstypen gebruikt, namelijk Tekst en Iterator
Het volgende argument is van het type OutputCollector
reduce () methode begint met het kopiëren van de sleutelwaarde en het initialiseren van de frequentietelling naar 0.
Tekstsleutel = t_key; int frequencyForCountry = 0;
Vervolgens doorlopen we met de ' while'- lus de lijst met waarden die aan de sleutel zijn gekoppeld en berekenen we de uiteindelijke frequentie door alle waarden op te tellen.
while (values.hasNext()) {// replace type of value with the actual type of our valueIntWritable value = (IntWritable) values.next();frequencyForCountry += value.get();}
Nu pushen we het resultaat naar de uitvoercollector in de vorm van een sleutel en verkregen frequentietelling .
Onderstaande code doet dit-
output.collect(key, new IntWritable(frequencyForCountry));
Uitleg van SalesCountryDriver Class
In deze sectie zullen we de implementatie van de SalesCountryDriver- klasse begrijpen
1. We beginnen met het specificeren van een pakketnaam voor onze klas. SalesCountry is een naam van ons pakket. Houd er rekening mee dat de uitvoer van de compilatie, SalesCountryDriver.class , naar de map met de naam van het pakket gaat: SalesCountry .
Hier is een regel die de pakketnaam specificeert, gevolgd door code om bibliotheekpakketten te importeren.
2. Definieer een chauffeursklasse die een nieuwe clienttaak en configuratieobject zal maken en Mapper- en Reducer-klassen zal adverteren.
De chauffeursklasse is verantwoordelijk voor het instellen van onze MapReduce-taak om in Hadoop te worden uitgevoerd. In deze klasse specificeren we de taaknaam, het gegevenstype van invoer / uitvoer en namen van mapper- en reducer-klassen .
3. In het onderstaande codefragment stellen we invoer- en uitvoermappen in die worden gebruikt om respectievelijk de invoergegevensset te verbruiken en uitvoer te produceren.
arg [0] en arg [1] zijn de opdrachtregelargumenten die worden doorgegeven met een commando gegeven in MapReduce hands-on, dat wil zeggen,
$ HADOOP_HOME / bin / hadoop jar ProductSalePerCountry.jar / inputMapReduce / mapreduce_output_sales
4. Activeer ons werk
Onderstaande code start uitvoering van MapReduce-taak-
try {// Run the jobJobClient.runJob(job_conf);} catch (Exception e) {e.printStackTrace();}