У цьому підручнику ви навчитеся використовувати Hadoop із прикладами MapReduce. Вхідними даними є SalesJan2009.csv. Він містить інформацію, пов’язану з продажами, таку як назва товару, ціна, спосіб оплати, місто, країна клієнта тощо. Мета - з’ясувати кількість товарів, що продаються в кожній країні.
У цьому підручнику ви дізнаєтесь-
- Перша програма Hadoop MapReduce
- Пояснення класу SalesMapper
- Пояснення класу SalesCountryReducer
- Пояснення класу SalesCountryDriver
Перша програма Hadoop MapReduce
Тепер у цьому посібнику MapReduce ми створимо нашу першу програму Java MapReduce:
Переконайтеся, що у вас встановлений Hadoop. Перш ніж розпочати фактичний процес, змініть користувача на «hduser» (ідентифікатор, який використовується під час конфігурації Hadoop, ви можете перейти на ідентифікатор користувача, який використовується під час налаштування програмування Hadoop).
su - hduser_
Крок 1)
Створіть новий каталог з назвою MapReduceTutorial як shwon у наведеному нижче прикладі MapReduce
sudo mkdir MapReduceTutorial
Дайте дозволи
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();}}}
Завантажте файли тут
Перевірте дозволи файлів усіх цих файлів
а якщо відсутні дозволи на читання, надайте те саме -
Крок 2)
Експортуйте шлях до класу, як показано в наведеному нижче прикладі Hadoop
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/*"
Крок 3)
Скомпілюйте файли Java (ці файли присутні в каталозі Final-MapReduceHandsOn ). Файли його класів будуть поміщені в каталог пакунків
javac -d . SalesMapper.java SalesCountryReducer.java SalesCountryDriver.java
Це попередження можна сміливо ігнорувати.
Ця компіляція створить каталог у поточному каталозі з іменем пакета, вказаним у вихідному файлі Java (тобто в нашому випадку SalesCountry ), і помістить у нього всі скомпільовані файли класів.
Крок 4)
Створіть новий файл Manifest.txt
sudo gedit Manifest.txt
додати до нього наступні рядки,
Main-Class: SalesCountry.SalesCountryDriver
SalesCountry.SalesCountryDriver - це ім'я основного класу. Зверніть увагу, що вам потрібно натиснути клавішу Enter в кінці цього рядка.
Крок 5)
Створіть файл Jar
jar cfm ProductSalePerCountry.jar Manifest.txt SalesCountry/*.class
Переконайтесь, що файл jar створено
Крок 6)
Почніть Hadoop
$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh
Крок 7)
Скопіюйте файл SalesJan2009.csv у ~ / inputMapReduce
Тепер скористайтеся командою нижче, щоб скопіювати ~ / inputMapReduce у HDFS.
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal ~/inputMapReduce /
Ми можемо спокійно проігнорувати це попередження.
Перевірте, чи файл скопійовано насправді чи ні.
$HADOOP_HOME/bin/hdfs dfs -ls /inputMapReduce
Крок 8)
Запустіть завдання MapReduce
$HADOOP_HOME/bin/hadoop jar ProductSalePerCountry.jar /inputMapReduce /mapreduce_output_sales
Це створить вихідний каталог із назвою mapreduce_output_sales на HDFS. Зміст цього каталогу буде файлом, що містить продажі товарів за країною.
Крок 9)
Результат можна побачити через командний інтерфейс як,
$HADOOP_HOME/bin/hdfs dfs -cat /mapreduce_output_sales/part-00000
Результати також можна побачити через веб-інтерфейс як
Відкрийте r у веб-браузері.
Тепер виберіть «Переглянути файлову систему» та перейдіть до / mapreduce_output_sales
Відкрийте частину-r-00000
Пояснення класу SalesMapper
У цьому розділі ми розберемося з реалізацією класу SalesMapper .
1. Ми починаємо із зазначення назви пакета для нашого класу. SalesCountry - це назва нашого пакету. Зверніть увагу, що результати компіляції, SalesMapper.class , потраплять у каталог, названий цим ім'ям пакету: SalesCountry .
Далі ми імпортуємо бібліотечні пакети.
Нижче моментальних показана реалізація SalesMapper class-
Приклад пояснення коду:
1. Визначення класу SalesMapper-
відкритий клас SalesMapper розширює MapReduceBase реалізує Mapper
Кожен клас mapper повинен бути розширений з класу MapReduceBase, і він повинен реалізовувати інтерфейс Mapper .
2. Визначення функції "карта" -
public void map(LongWritable key,Text value,OutputCollectoroutput,Reporter reporter) throws IOException
Основною частиною класу Mapper є метод 'map ()', який приймає чотири аргументи.
При кожному виклику методу 'map ()' передається пара ключ-значення ( 'ключ' і 'значення' в цьому коді).
Метод 'map ()' починається з розділення вхідного тексту, який отримується як аргумент. Він використовує маркер, щоб розділити ці рядки на слова.
String valueString = value.toString();String[] SingleCountryData = valueString.split(",");
Тут символ "," використовується як роздільник.
Після цього пара формується з використанням запису на 7-му індексі масиву 'SingleCountryData' та значення '1' .
output.collect (новий текст (SingleCountryData [7]), один);
Ми обираємо запис на 7-му індексі, оскільки нам потрібні дані про країну, і він знаходиться на 7-му індексі в масиві 'SingleCountryData' .
Зверніть увагу, що наші вхідні дані мають формат нижче (де країна знаходиться на 7- му індексі, а 0 - як початковий індекс) -
Дата транзакції, Продукт, Ціна, Тип_платежу, Ім'я, Місто, Штат, Країна , Створений акаунт, Останній_вхід, Широта, Довгота
Висновок mapper - це знову пара ключ-значення, яка виводиться методом 'collect ()' з 'OutputCollector' .
Пояснення класу SalesCountryReducer
У цьому розділі ми розберемося з реалізацією класу SalesCountryReducer .
1. Ми починаємо із зазначення назви пакета для нашого класу. SalesCountry - це назва вихідного пакета. Зверніть увагу, що результати компіляції, SalesCountryReducer.class , потраплять у каталог, названий цим ім'ям пакета: SalesCountry .
Далі ми імпортуємо бібліотечні пакети.
Нижче моментальних показана реалізація SalesCountryReducer class-
Пояснення коду:
1. Визначення класу SalesCountryReducer-
відкритий клас SalesCountryReducer розширює MapReduceBase реалізує Редуктор
Тут перші два типи даних, 'Text' та 'IntWritable' - це тип даних, що вводить ключ-значення для редуктора.
Висновок mapper має форму
Останні два типи даних, "Текст" та "Інтерв'юйтл" - це тип даних, що виводяться редуктором у формі пари ключ-значення.
Кожен клас редуктора повинен бути розширений з класу MapReduceBase, і він повинен реалізовувати інтерфейс редуктора .
2. Визначення функції «зменшення» -
public void reduce( Text t_key,Iteratorvalues,OutputCollector output,Reporter reporter) throws IOException {
Вхідні дані до методу зменшення () - це ключ зі списком декількох значень.
Наприклад, у нашому випадку це буде -
<Об'єднані Арабські Емірати, 1>, <Об'єднані Арабські Емірати, 1>, <Об'єднані Арабські Емірати, 1>, <Об'єднані Арабські Емірати, 1>, <Об'єднані Арабські Емірати, 1>, <ОАЕ, 1>.
Це надається редуктору як <Об'єднані Арабські Емірати, {1,1,1,1,1,1}>
Отже, для прийняття аргументів цієї форми використовуються перші два типи даних, а саме: Text та Iterator
Наступний аргумент має тип OutputCollector
Метод зменшення () починається з копіювання значення ключа та ініціалізації підрахунку частоти до 0.
Текстовий ключ = t_key; int частотаForCountry = 0;
Потім, використовуючи цикл ' while' , ми перебираємо список значень, пов'язаних з ключем, і обчислюємо кінцеву частоту, підсумовуючи всі значення.
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
У цьому розділі ми розберемося з реалізацією класу SalesCountryDriver
1. Ми починаємо із зазначення назви пакета для нашого класу. SalesCountry - це назва вихідного пакета. Зверніть увагу, що результати компіляції, SalesCountryDriver.class , потраплять у каталог, названий таким ім'ям пакету: SalesCountry .
Ось рядок із зазначенням назви пакета, за яким слідує код для імпорту бібліотечних пакетів.
2. Визначте клас драйвера, який створить нову роботу клієнта, об’єкт конфігурації та рекламує класи Mapper та Reducer.
Клас водіїв відповідає за налаштування нашої роботи MapReduce для роботи в Hadoop. У цьому класі ми вказуємо назву завдання, тип даних вводу / виводу та імена класів зіставлення та зменшення .
3. У наведеному нижче фрагменті коду ми встановлюємо вхідні та вихідні каталоги, які використовуються відповідно для споживання набору даних та виведення результатів.
arg [0] та arg [1] - це аргументи командного рядка, передані за допомогою команди, заданої в MapReduce hands-on, тобто
$ HADOOP_HOME / bin / hadoop jar ProductSalePerCountry.jar / inputMapReduce / mapreduce_output_sales
4. Спустіть нашу роботу
Нижче запуску коду виконання завдання MapReduce-
try {// Run the jobJobClient.runJob(job_conf);} catch (Exception e) {e.printStackTrace();}