Primjer Hadoop MapReduce: Prvi Java Program sa Code
โก Pametni saลพetak
Hadoop MapReduce programi su napisani kao tri Java klase, mapper, reducer i driver, koji se kompajliraju, pakiraju u jar datoteku i ลกalju klasteru za brojanje prodaje po zemlji.
U ovom vodiฤu nauฤit ฤete koristiti Hadoop s MapReduce primjerima. Koriลกteni ulazni podaci su ProdajaSijeฤanj2009.csvSadrลพi podatke vezane uz prodaju kao ลกto su naziv proizvoda, cijena, naฤin plaฤanja, grad i drลพava klijenta. Cilj je saznati broj prodanih proizvoda u svakoj drลพavi.
Prvi Hadoop MapReduce program
Sada u ovome Vodiฤ za MapReduce, stvorit ฤemo svoj prvi Java Program MapReduce:
Snimka zaslona u nastavku prikazuje neobraฤene podatke o prodaji za sijeฤanj 2009., gdje svaki redak predstavlja jednu transakciju, a drลพava se nalazi u osmom stupcu odvojenom zarezom.
Provjerite imate li instaliran Hadoop. Prije nego ลกto zapoฤnete sa stvarnim postupkom, promijenite korisnika u 'hduser' (id koji se koristio prilikom konfiguriranja Hadoop-a - moลพete se prebaciti na korisniฤki ID koji se koristio tijekom vlastite konfiguracije Hadoop-a).
su - hduser_
Uputa se mijenja u hduser raฤun, kao ลกto je prikazano dolje.
Korak 1) Izradite direktorij projekta i izvorne datoteke
Izradite novi direktorij s nazivom MapReduceTutorial kao ลกto je prikazano u donjem primjeru MapReduce.
sudo mkdir MapReduceTutorial
Dajte dozvole
sudo chmod -R 777 MapReduceTutorial
Stvorite tri Java izvorne datoteke u nastavku unutar MapReduceTutoriala. Imajte na umu da sva tri koriste stariju org.apache.hadoop.mapred API, koji se joลก uvijek isporuฤuje s Hadoopom 3.x.
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(); } } }
Arhiva se proลกiruje u iste tri izvorne datoteke, kao ลกto je ovdje prikazano.
Provjerite dopuลกtenja za sve te datoteke
Ako nedostaju dozvole za 'ฤitanje', dodijelite ih:
Korak 2) Izvoz Hadoop classpath-a
Izvezite putanju klase kao ลกto je prikazano u donjem Hadoop primjeru.
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/*"
Izvezena putanja klase se vraฤa u promptu.
Korak 3) Sastavite Java slika
Sastavite Java datoteke (ove se datoteke nalaze u direktoriju Final-MapReduceHandsOn). Njihove datoteke klasa bit ฤe smjeลกtene u direktorij paketa.
javac -d . SalesMapper.java SalesCountryReducer.java SalesCountryDriver.java
Ovo upozorenje se moลพe sigurno zanemariti โ ono samo izvjeลกtava da je mapirani API zastario.
Ova kompilacija ฤe stvoriti direktorij u trenutnom direktoriju nazvan s nazivom paketa navedenim u Java izvornu datoteku (tj. SalesCountry u naลกem sluฤaju) i u nju staviti sve kompilirane datoteke klase.
Korak 4) Izradite datoteku manifesta
Stvorite novu datoteku Manifest.txt
sudo gedit Manifest.txt
Dodajte mu sljedeฤi redak:
Main-Class: SalesCountry.SalesCountryDriver
SalesCountry.SalesCountryDriver je naziv glavne klase. Imajte na umu da morate pritisnuti tipku Enter na kraju ovog retka.
Korak 5) Zapakirajte klase u staklenku
Stvorite Jar datoteku
jar cfm ProductSalePerCountry.jar Manifest.txt SalesCountry/*.class
Provjerite je li jar datoteka stvorena
Korak 6) Pokrenite Hadoop
Pokrenite Hadoop
$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh
Korak 7) Kopirajte ulaznu datoteku u HDFS
Kopirajte datoteku SalesJan2009.csv u ~/inputMapReduce
Sada upotrijebite naredbu u nastavku za kopiranje ~/inputMapReduce u HDFS.
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal ~/inputMapReduce /
Moลพemo slobodno zanemariti ovo upozorenje.
Provjerite je li datoteka stvarno kopirana ili ne.
$HADOOP_HOME/bin/hdfs dfs -ls /inputMapReduce
Korak 8) Pokrenite zadatak MapReduce
Pokrenite zadatak MapReduce
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
Ovo ฤe stvoriti izlazni direktorij pod nazivom mapreduce_output_sales on HDFS. Sadrลพaj ovog imenika bit ฤe datoteka koja ฤe sadrลพavati prodaju proizvoda po zemlji.
Korak 9) Proฤitajte rezultate
Rezultat se moลพe vidjeti kroz suฤelje naredbi kao,
$HADOOP_HOME/bin/hdfs dfs -cat /mapreduce_output_sales/part-00000
Rezultati se takoฤer mogu vidjeti putem web suฤelja kao-
Otvoren http://localhost:50070/ u web pregledniku. Na Hadoopu 3.x, web suฤelje NameNodea premjeลกteno je na port 9870, pa koristite http://localhost:9870/ tamo umjesto toga.
Sada odaberite 'Pregledaj datoteฤni sustav' i idite na /mapreduce_output_sales
Otvori dio-r-00000
Objaลกnjenje klase SalesMapper
S obzirom na to da se posao izvodi od poฤetka do kraja, sljedeฤa tri odjeljka opisuju ลกto svaka klasa zapravo radi.
U ovom odjeljku ฤemo razumjeti implementaciju klase SalesMapper.
1. Poฤinjemo odreฤivanjem naziva paketa za naลกu klasu. SalesCountry je naziv naลกeg paketa. Imajte na umu da ฤe izlaz kompilacije, SalesMapper.class, iฤi u direktorij nazvan ovim nazivom paketa: SalesCountry.
Nakon toga uvozimo knjiลพniฤne pakete.
Donja snimka prikazuje implementaciju klase SalesMapper-
Uzorak Code Objaลกnjenje:
1. Definicija klase SalesMapper-
public class SalesMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
Svaka klasa mappera mora biti proลกirena iz klase MapReduceBase i mora implementirati Mapper suฤelje.
2. Definiranje funkcije 'map'-
public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException
Glavni dio klase Mapper je metoda 'map()' koja prihvaฤa ฤetiri argumenta.
Pri svakom pozivu metode 'map()', prosljeฤuje se par kljuฤ-vrijednost ('kljuฤ' i 'vrijednost' u ovom kodu).
Metoda 'map()' zapoฤinje dijeljenjem ulaznog teksta koji se prima kao argument. Svaki redak dijeli na polja.
String valueString = value.toString(); String[] SingleCountryData = valueString.split(",");
Ovdje se ',' koristi kao razdjelnik.
Nakon toga, par se formira koriลกtenjem zapisa na 7. indeksu polja 'SingleCountryData' i vrijednosti '1'.
output.collect(new Text(SingleCountryData[7]), one);
Zapis na 7. indeksu odabiremo jer nam trebaju podaci o drลพavi, a on se nalazi na 7. indeksu u nizu 'SingleCountryData'.
Imajte na umu da su naลกi ulazni podaci u sljedeฤem formatu (gdje je Drลพava na 7. indeksu, s 0 kao poฤetnim indeksom) -
Transaction_date,Product,Price,Payment_Type,Name,City,State,Country,Account_Created,Last_Login,Latitude,Longitude
Izlaz mappera je opet par kljuฤ-vrijednost koji se emitira pomoฤu metode 'collect()' klase 'OutputCollector'.
Objaลกnjenje klase SalesCountryReducer
U ovom odjeljku ฤemo razumjeti implementaciju klase SalesCountryReducer.
1. Poฤinjemo odreฤivanjem naziva paketa za naลกu klasu. SalesCountry je naziv naลกeg paketa. Imajte na umu da ฤe izlaz kompilacije, SalesCountryReducer.class, iฤi u direktorij nazvan ovim nazivom paketa: SalesCountry.
Nakon toga uvozimo knjiลพniฤne pakete.
Donja snimka prikazuje implementaciju klase SalesCountryReducer.
Code Objaลกnjenje:
1. Definicija klase SalesCountryReducer-
public class SalesCountryReducer extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
Ovdje su prva dva tipa podataka, 'Text' i 'IntWritable', tip podataka ulaznog kljuฤa-vrijednosti za reducer.
Izlaz mappera je u obliku , Ovaj izlaz mappera postaje ulaz za reducer. Dakle, radi usklaฤivanja s njegovim tipom podataka, ovdje se kao tip podataka koriste Text i IntWritable.
Posljednja dva tipa podataka, 'Text' i 'IntWritable', su tipovi podataka izlaza koje generira reducer u obliku para kljuฤ-vrijednost.
Svaka klasa reducera mora biti proลกirena iz klase MapReduceBase i mora implementirati Reducer suฤelje.
2. Definiranje funkcije reduciranja-
public void reduce( Text t_key, Iterator<IntWritable> values, OutputCollector<Text,IntWritable> output, Reporter reporter) throws IOException {
Ulaz u metodu reduce() je kljuฤ s popisom viลกe vrijednosti.
Na primjer, u naลกem sluฤaju to ฤe biti-
, , , , , .
To se daje reduktoru kao
Dakle, za prihvaฤanje argumenata ovog oblika koriste se prva dva tipa podataka, i to tekst i iterator. Tekst je tip podataka kljuฤa i iteratora. je tip podataka za popis vrijednosti za taj kljuฤ.
Sljedeฤi argument je tipa OutputCollector koji prikuplja izlaz faze redukcije.
Metoda reduce() zapoฤinje kopiranjem vrijednosti kljuฤa i inicijalizacijom brojaฤa frekvencija na 0.
Text key = t_key;int frequencyForCountry = 0;
Zatim, koristeฤi petlju 'while', iteriramo kroz popis vrijednosti povezanih s kljuฤem i izraฤunavamo konaฤnu frekvenciju zbrajanjem svih vrijednosti.
while (values.hasNext()) { // replace type of value with the actual type of our value IntWritable value = (IntWritable) values.next(); frequencyForCountry += value.get(); }
Sada rezultat ลกaljemo na izlazni kolektor u obliku kljuฤa i dobivenog brojaฤa frekvencija.
Donji kod radi ovo-
output.collect(key, new IntWritable(frequencyForCountry));
Objaลกnjenje klase SalesCountryDriver
U ovom odjeljku ฤemo razumjeti implementaciju klase SalesCountryDriver.
1. Poฤinjemo odreฤivanjem naziva paketa za naลกu klasu. SalesCountry je naziv naลกeg paketa. Imajte na umu da ฤe izlaz kompilacije, SalesCountryDriver.class, iฤi u direktorij nazvan ovim nazivom paketa: SalesCountry.
Ovdje je redak koji navodi naziv paketa nakon kojeg slijedi kod za uvoz paketa knjiลพnice.
2. Definirajte klasu pokretaฤa koja ฤe kreirati novi posao klijenta, konfiguracijski objekt i oglaลกavati klase Mapper i Reducer.
Klasa upravljaฤkog programa odgovorna je za postavljanje naลกeg MapReduce posla za izvoฤenje HadoopU ovoj klasi odreฤujemo naziv posla, tip podataka ulaza/izlaza i nazive klasa mappera i reducera.
3. U donjem isjeฤku koda postavljamo ulazne i izlazne direktorije koji se koriste za potroลกnju ulaznog skupa podataka i proizvodnju izlaza.
arg[0] i arg[1] su argumenti naredbenog retka koji se prosljeฤuju s naredbom zadanom u praktiฤnom MapReduceu, tj.
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
4. Pokrenite naลก posao
Donji kod pokreฤe izvrลกavanje MapReduce posla -
try { // Run the job JobClient.runJob(job_conf); } catch (Exception e) { e.printStackTrace(); }





















