SlideShare a Scribd company logo
Map-Reduce API
Типы API
• org.apache.hadoop.mapreduce
– Новое API, будем использовать в примерах
• org.apache.hadoop.mapred
– Старое API, лучше не использовать
Класс Job
Содержит описание MapReduce задачи:
– input/output пути
– Формат input/output данных
– Указания классов для mapper, reducer, combiner
и partitioner
– Типы значений пар key/value
– Количество редьюсеров
Класс Mapper
• void setup(Mapper.Context context)
– Вызывается один раз при запуске таска
• void map(K key, V value, Mapper.Context context)
– Вызывается для каждой пары key/value из input split
• void cleanup(Mapper.Context context)
– Вызывается один раз при завершении таска
Класс Reducer/Combiner
• void setup(Reducer.Context context)
– Вызывается один раз при запуске таска
• void reduce(K key, Iterable<V> values,
Reducer.Context context)
– Вызывается для каждого key
• void cleanup(Reducer.Context context)
– Вызывается один раз при завершении таска
Класс Partitioner
int getPartition(K key, V value, int numPartitions)
– Возвращает номер reducer для ключа K
“Hello World”: Word Count
Map(String docid, String text):
for each word w in text:
Emit(w, 1);
Reduce(String term, Iterator<Int> values):
int sum = 0;
for each v in values:
sum += v;
Emit(term, sum);
WordCount: Configure Job
• Создание объекта Job:
• Определение jar для задачи:
Job job = Job.getInstance(getConf(), “WordCount");
job.setJarByClass(getClass());
WordCount: Configure Job
Определение input:
– в качестве пути может быть файл, директория,
шаблон пути (/path/to/dir/test_*)
– TextInputFormat читает входные данные как
текстовый файл (key – LongWritable, value – Text)
TextInputFormat.addInputPath(job, new Path(args[0]));
job.setInputFormatClass(TextInputFormat.class);
WordCount: Configure Job
Определение output:
Если типы для map и reduce отличаются, то:
TextOutputFormat.setOutputPath(job, new Path(args[1]));
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
WordCount: Configure Job
• Определение класса для Mapper и Reducer:
• Определение класса для Combiner:
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
job.setCombinerClass(WordCountReducer.class);
WordCount: запуск задачи
Запускает задачу и ждет ее окончания:
– true в случае успеха, false в случае ошибки
job.waitForCompletion(true);
public class WordCountJob extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
Job job = Job.getInstance(getConf(), "WordCount");
job.setJarByClass(getClass());
TextInputFormat.addInputPath(job, new Path(args[0]));
job.setInputFormatClass(TextInputFormat.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
job.setCombinerClass(WordCountReducer.class);
TextOutputFormat.setOutputPath(job, new Path(args[1]));
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
return job.waitForCompletion(true) ? 0 : 1;
}
}
public class WordCountJob extends Configured implements Tool{
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(
new WordCountJob(), args);
System.exit(exitCode);
}
}
WordCount: Mapper
• Наследник класса:
• Должен быть реализован метод map():
• Типы key / value (из org.apache.hadoop.io):
– IntWritable
– Text
– ImmutableBytesWritable
public class Mapper <KEYIN, VALUEIN, KEYOUT, VALUEOUT>
void map(KEYIN key, VALUEIN value, Context context){}
public class WordCountMapper
extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private final Text word = new Text();
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
StringTokenizer tokenizer =
= new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
context.write(word, one);
}
}
}
WordCount: Reducer
• Наследник класса:
• Должен быть реализован метод reduce():
• Типы входных данных в Reducer должны
совпадать с типами выходных данных Mapper
public class Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
void reduce(KEYIN key, Iterable<VALUEIN> values,
Context context){}
public class WordCountReducer
extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key,
Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
context.write(key, new IntWritable(sum));
}
}
Reducer в качестве Combiner
• Меньше данных отправляется на Reducer
• Типы key/value в output у Reducer и Mapper равны
• Фреймворк MapReduce не гарантирует вызов
Combiner
– Нужно только с точки зрения оптимизации
– Логика приложения не должна зависеть от вызова
вызов Combiner
Типы данных в Hadoop
• Writable
– Определяет протокол де-сериализации. Каждый тип в Hadoop
должен быть Writable
• WritableComprable
– Определяет порядок сортировки. Все ключи должны быть
WritableComprable (но не значения!)
• Text, IntWritable, LongWritable и т.д.
– Конкретные реализации для конкретных типов
• SequenceFiles
– Бинарно-закодированная последовательность пар key/value
Комплексные типы данных в Hadoop
Простой способ:
– Закодировать в Text
– Для раскодирования нужен специальный
метод парсинга
– Просто, работает, но…
Комплексные типы данных в Hadoop
Сложный (правильный) способ:
– Определить реализацию своего типа
Writable(Comprable)
– Необходимо реализовать методы readFields,
write, (compareTo)
– Более производительное решение, но сложнее
в реализации
Класс InputSplit
• Split – это набор логически организованных записей
– Строки в файле
– Строки в выборке из БД
• Каждый экземпляр Mapper обрабатывает один split
– Функция map(k, v) вызывается для каждой записи из split
• Cплиты реализуются расширением класса InputSplit:
– FileSplit
– TableSplit
Класс InputFormat
• Создает input splits
• Определяет, как читать каждый split
public abstract class InputFormat<K, V> {
public abstract List<InputSplit> getSplits(JobContext context)
throws IOException, InterruptedException;
public abstract RecordReader<K,V> createRecordReader(InputSplit split,
TaskAttemptContext context )
throws IOException, InterruptedException;
}
• Готовые классы-реализации InputFormat:
– TextInputFormat
• LongWritable / Text
– NLineInputFormat
• NLineInputFormat.setNumLinesPerSplit(job, 100);
– DBInputFormat
– TableInputFormat (HBASE)
• ImmutableBytesWritable / Result
– SequenceFileInputFormat
• Выбор нужного формата:
job.setInputFormatClass(*InputFormat.class);
Класс OutputFormat
• Определяет формат выходных данных
• Реализация интерфейса класса OutputFormat
– Проверяет output для задачи
– Создает реализацию RecordWriter
– Создает реализацию OutputCommitter
• Готовые классы-реализации OutputFormat:
– TextOutputFormat
– DBOutputFormat
– TableOutputFormat (HBASE)
– SequenceFileOutputFormat
– NullOutputFormat
• Выбор нужного формата:
job.setOutputFormatClass(*OutputFormat.class);
job.setOutputKeyClass(*Key.class);
job.setOutputValueClass(*Value.class);
Shuffle и Sort в Hadoop
• На стороне Map
– Выходные данные сохраняются в памяти в циклическом буфере
– Когда размер буфера достигает предела, данные “скидываются” (spilled) на диск
– Все “сброшенные” части объединяются (merge) в один файл, разбитый на части
• Внутри каждой части данные отсортированы
• Combiner запускается во время процедуры объединения
• На стороне Reduce
– Выходные данные от мапперов копируются на машину, где будет запущен редьюсер
– Процесс сортировки (sort) представляет собой многопроходный процесс объединения
(merge) данных от мапперов
• Это происходит в памяти и затем пишется на диск
– Итоговый результат объединения отправляется непосредственно на редьюсер
Shuffle и Sort в Hadoop
Circ Buff
(in RAM)
spill
spill
spill
Merged spills
Combiner
Mapper
Shuffle и Sort в Hadoop
Intermediate files
Other mappers
Other reducers
Reducer
sort
Merged spills
$ hadoop jar <jar> [mainClass] args...
Generic Option Описание
-conf <conf_file.xml> Добавляет свойства конфигурации из указанного
файла в объект Configuration
-Dproperty=value Устанавливает значение свойства конфигурации в
объекте Configuration
-files <file,file,file> Предоставляет возможность использовать указанные
файлы в задаче MapReduce через DistributedCache
-libjars <f.jar, f2.jar> Добавляет указанные jars к переменной CLASSPATH у
тасков задачи и копирует их через DistributedCache
$ hadoop jar file.jar org.my.main.class –files dict.txt –D send.stat=true
Отладка задач в Hadoop
• Логирование
– System.out.println
– Доступ к логам через веб-интерфейс
– Лучше использовать отдельный класс-логер (log4j)
– Аккуратней с количество данных в логах
• Использование счетчиков:
context.getCounter(“GROUP”, “NAME”).increment(1);
Hadoop Streaming
Hadoop Streaming
• Используется стандартный механизм ввода/вывода
в Unix для взаимодействия программы и Hadoop
• Разработка MR задачи почти на любом языке
программирования
• Обычно используется:
• Для обработки текста
• При отсутствии опыта программирования на Java
• Для быстрого написания прототипа
Streaming в MapReduce
• На вход функции map() данные подаются через
стандартный ввод
• В map() обрабатываются они построчно
• Функция map() пишет пары key/value, разделяемые
через символ табуляции, в стандартный вывод
• На вход функции reduce() данные подаются через
стандартный ввод, отсортированный по ключам
• Функция reduce() пишет пары key/value в
стандартный вывод
WordCount на Python
Map: countMap.py
#!/usr/bin/python
import sys
for line in sys.stdin:
for token in line.strip().split(" "):
if token: print token + 't1'
Reduce: countReduce.py
#!/usr/bin/python
import sys
(lastKey, sum)=(None, 0)
for line in sys.stdin:
(key, value) = line.strip().split("t")
if lastKey and lastKey != key:
print lastKey + 't' + str(sum)
(lastKey, sum) = (key, int(value))
else:
(lastKey, sum) = (key, sum + int(value))
if lastKey:
print lastKey + 't' + str(sum)
Запуск и отладка
Тест в консоли перед запуском
$ cat test.txt | countMap.py | sort | countReduce.py
Запуск и отладка
Запуск задачи через Streaming Framework:
hadoop jar $HADOOP_HOME/hadoop/hadoop-streaming.jar 
-D mapred.job.name=“WordCount Job via Streaming" 
-files countMap.py, countReduce.py 
-input text.txt 
-output /tmp/wordCount/ 
-mapper countMap.py 
-combiner countReduce.py 
-reducer countReduce.py
Python vs. Java
#!/usr/bin/python
import sys
for line in sys.stdin:
for token in line.strip().split(""):
if token: print token + 't1'
#!/usr/bin/python
import sys
(lastKey, sum)=(None, 0)
for line in sys.stdin:
(key, value) = line.strip().split("t")
if lastKey and lastKey != key:
print lastKey + 't' + str(sum)
(lastKey, sum) = (key, int(value))
else:
(lastKey, sum) = (key, sum + int(value))
if lastKey:
print lastKey + 't' + str(sum)
public class WordCountJob extends Configured implements Tool{
static public class WordCountMapper
extends Mapper<LongWritable, Text, Text, IntWritable>{
private final static IntWritableone = new IntWritable(1);
private final Text word = new Text();
@Override
protected void map(LongWritablekey, Text value, Context context)
throws IOException, InterruptedException{
StringTokenizer tokenizer = new StringTokenizer(value.toString());
while (tokenizer.hasMoreTokens()){
text.set(tokenizer.nextToken());
context.write(text, one);
}
}
static public class WordCountReducer
extends Reducer<Text, IntWritable,Text, IntWritable>{
@Override
protected void reduce(Text key, Iterable<IntWritable>values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritablevalue : values) {
sum += value.get();
}
context.write(key, new IntWritable(sum));
}
}
@Override
public int run(String[] args) throws Exception {
Job job = Job.getInstance(getConf(), "WordCount");
job.setJarByClass(getClass());
TextInputFormat.addInputPath(job, new Path(args[0]));
job.setInputFormatClass(TextInputFormat.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
job.setCombinerClass(WordCountReducer.class);
TextOutputFormat.setOutputPath(job, new Path(args[1]));
job.setOutputFormatClass(TextOutputFormat.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
return job.waitForCompletion(true)? 0 : 1;
}
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(
new WordCountJob(), args);
System.exit(exitCode);
}
}

More Related Content

What's hot

Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARN
Technopark
 
Spark: нетипичные примеры использования
Spark:  нетипичные примеры использованияSpark:  нетипичные примеры использования
Spark: нетипичные примеры использования
faithlessfriend
 
Лекция 10. Apache Mahout
Лекция 10. Apache MahoutЛекция 10. Apache Mahout
Лекция 10. Apache Mahout
Technopark
 
Разработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PIРазработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PI
Ilya Chesnokov
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Timur Safin
 
Лекция 2. Основы Hadoop
Лекция 2. Основы HadoopЛекция 2. Основы Hadoop
Лекция 2. Основы Hadoop
Technopark
 
Big Data и Ruby
Big Data и RubyBig Data и Ruby
Big Data и Ruby
Александр Ежов
 
Apache Spark — Егор Пахомов
Apache Spark — Егор ПахомовApache Spark — Егор Пахомов
Apache Spark — Егор Пахомов
Yandex
 
Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)
Technopark
 
Hacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данныхHacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данных
Anastasia Lubennikova
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico
 
Расширения для PostgreSQL
Расширения для PostgreSQLРасширения для PostgreSQL
Расширения для PostgreSQL
Anastasia Lubennikova
 
MyRocks: табличный движок для MySQL на основе RocksDB
MyRocks: табличный движок для MySQL на основе RocksDBMyRocks: табличный движок для MySQL на основе RocksDB
MyRocks: табличный движок для MySQL на основе RocksDB
Sergey Petrunya
 
Hadoop presentation
Hadoop presentationHadoop presentation
Hadoop presentation
Vlad Orlov
 
Пакет purrr
Пакет purrrПакет purrr
Hacking PostgreSQL. Разделяемая память и блокировки.
Hacking PostgreSQL. Разделяемая память и блокировки.Hacking PostgreSQL. Разделяемая память и блокировки.
Hacking PostgreSQL. Разделяемая память и блокировки.
Anastasia Lubennikova
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кода
Anastasia Lubennikova
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?
Ivan Tsyganov
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Ivan Muratov
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Ontico
 

What's hot (20)

Лекция 13. YARN
Лекция 13. YARNЛекция 13. YARN
Лекция 13. YARN
 
Spark: нетипичные примеры использования
Spark:  нетипичные примеры использованияSpark:  нетипичные примеры использования
Spark: нетипичные примеры использования
 
Лекция 10. Apache Mahout
Лекция 10. Apache MahoutЛекция 10. Apache Mahout
Лекция 10. Apache Mahout
 
Разработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PIРазработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PI
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
Лекция 2. Основы Hadoop
Лекция 2. Основы HadoopЛекция 2. Основы Hadoop
Лекция 2. Основы Hadoop
 
Big Data и Ruby
Big Data и RubyBig Data и Ruby
Big Data и Ruby
 
Apache Spark — Егор Пахомов
Apache Spark — Егор ПахомовApache Spark — Егор Пахомов
Apache Spark — Егор Пахомов
 
Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)Лекция 6. MapReduce в Hadoop (графы)
Лекция 6. MapReduce в Hadoop (графы)
 
Hacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данныхHacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данных
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
 
Расширения для PostgreSQL
Расширения для PostgreSQLРасширения для PostgreSQL
Расширения для PostgreSQL
 
MyRocks: табличный движок для MySQL на основе RocksDB
MyRocks: табличный движок для MySQL на основе RocksDBMyRocks: табличный движок для MySQL на основе RocksDB
MyRocks: табличный движок для MySQL на основе RocksDB
 
Hadoop presentation
Hadoop presentationHadoop presentation
Hadoop presentation
 
Пакет purrr
Пакет purrrПакет purrr
Пакет purrr
 
Hacking PostgreSQL. Разделяемая память и блокировки.
Hacking PostgreSQL. Разделяемая память и блокировки.Hacking PostgreSQL. Разделяемая память и блокировки.
Hacking PostgreSQL. Разделяемая память и блокировки.
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кода
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
 

Similar to 06 - Hadoop. Java API и Hadoop Streaming

Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)
Technopark
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
Vasil Remeniuk
 
Not the Rails Way
Not the Rails WayNot the Rails Way
Not the Rails Way
Igor Alexandrov
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf Conference
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
Арсений Жижелев
 
PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
Дмитрий Золотов
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark Job
Provectus
 
Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычностьStepan Tanasiychuk
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
SmartTools
 
Паттерны проектирования источников данных
Паттерны проектирования источников данныхПаттерны проектирования источников данных
Паттерны проектирования источников данных
Alex Polorotov
 
паттерны проектирования источников данных
паттерны проектирования источников данныхпаттерны проектирования источников данных
паттерны проектирования источников данныхVitaliy Trenkenshu
 
Hadoop implementation in Wikimart
Hadoop implementation in WikimartHadoop implementation in Wikimart
Hadoop implementation in WikimartRoman Zykov
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
corehard_by
 
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
pgdayrussia
 
Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)
Alex Ott
 
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Fedor Lavrentyev
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
Alexander Podkhalyuzin
 
Gradle
GradleGradle
Gradle
Ilya Lapitan
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
Alexander Makarov
 

Similar to 06 - Hadoop. Java API и Hadoop Streaming (20)

Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)Лекция 4. MapReduce в Hadoop (введение)
Лекция 4. MapReduce в Hadoop (введение)
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Not the Rails Way
Not the Rails WayNot the Rails Way
Not the Rails Way
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
 
Расширение библиотеки Slick
Расширение библиотеки SlickРасширение библиотеки Slick
Расширение библиотеки Slick
 
PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
 
Expert Fridays Spark Job
Expert Fridays Spark JobExpert Fridays Spark Job
Expert Fridays Spark Job
 
Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычность
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
Паттерны проектирования источников данных
Паттерны проектирования источников данныхПаттерны проектирования источников данных
Паттерны проектирования источников данных
 
паттерны проектирования источников данных
паттерны проектирования источников данныхпаттерны проектирования источников данных
паттерны проектирования источников данных
 
Hadoop implementation in Wikimart
Hadoop implementation in WikimartHadoop implementation in Wikimart
Hadoop implementation in Wikimart
 
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
C++ CoreHard Autumn 2018. Метаклассы: воплощаем мечты в реальность - Сергей С...
 
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2...
 
Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)Clojure: Lisp for the modern world (русская версия)
Clojure: Lisp for the modern world (русская версия)
 
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
 
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
WebCamp2016:Front-End.Максим Климишин.Теоретические и практические концепции ...
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Gradle
GradleGradle
Gradle
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 

More from Roman Brovko

Individual task Networking
Individual task NetworkingIndividual task Networking
Individual task Networking
Roman Brovko
 
Networking essentials lect3
Networking essentials lect3Networking essentials lect3
Networking essentials lect3
Roman Brovko
 
Gl embedded starterkit_ethernet
Gl embedded starterkit_ethernetGl embedded starterkit_ethernet
Gl embedded starterkit_ethernet
Roman Brovko
 
Networking essentials lect2
Networking essentials lect2Networking essentials lect2
Networking essentials lect2
Roman Brovko
 
Networking essentials lect1
Networking essentials lect1Networking essentials lect1
Networking essentials lect1
Roman Brovko
 
Bare metal training_07_spi_flash
Bare metal training_07_spi_flashBare metal training_07_spi_flash
Bare metal training_07_spi_flash
Roman Brovko
 
Bare metal training_06_I2C
Bare metal training_06_I2CBare metal training_06_I2C
Bare metal training_06_I2C
Roman Brovko
 
Glesk worshop
Glesk worshopGlesk worshop
Glesk worshop
Roman Brovko
 
Bare metal training_05_uart
Bare metal training_05_uartBare metal training_05_uart
Bare metal training_05_uart
Roman Brovko
 
Bare metal training_04_adc_temp_sensor
Bare metal training_04_adc_temp_sensorBare metal training_04_adc_temp_sensor
Bare metal training_04_adc_temp_sensor
Roman Brovko
 
Bare metal training_03_timers_pwm
Bare metal training_03_timers_pwmBare metal training_03_timers_pwm
Bare metal training_03_timers_pwm
Roman Brovko
 
Bare metal training_02_le_ds_and_buttons
Bare metal training_02_le_ds_and_buttonsBare metal training_02_le_ds_and_buttons
Bare metal training_02_le_ds_and_buttons
Roman Brovko
 
Bare metal training_01_hello_world
Bare metal training_01_hello_worldBare metal training_01_hello_world
Bare metal training_01_hello_world
Roman Brovko
 
Bare metal training_00_prerequisites
Bare metal training_00_prerequisitesBare metal training_00_prerequisites
Bare metal training_00_prerequisites
Roman Brovko
 
C language lect_23_advanced
C language lect_23_advancedC language lect_23_advanced
C language lect_23_advanced
Roman Brovko
 
C language lect_22_advanced
C language lect_22_advancedC language lect_22_advanced
C language lect_22_advanced
Roman Brovko
 
C language lect_21_advanced
C language lect_21_advancedC language lect_21_advanced
C language lect_21_advanced
Roman Brovko
 
подготовка рабочего окружения
подготовка рабочего окруженияподготовка рабочего окружения
подготовка рабочего окружения
Roman Brovko
 
C language lect_20_advanced
C language lect_20_advancedC language lect_20_advanced
C language lect_20_advanced
Roman Brovko
 
C language lect_19_basics
C language lect_19_basicsC language lect_19_basics
C language lect_19_basics
Roman Brovko
 

More from Roman Brovko (20)

Individual task Networking
Individual task NetworkingIndividual task Networking
Individual task Networking
 
Networking essentials lect3
Networking essentials lect3Networking essentials lect3
Networking essentials lect3
 
Gl embedded starterkit_ethernet
Gl embedded starterkit_ethernetGl embedded starterkit_ethernet
Gl embedded starterkit_ethernet
 
Networking essentials lect2
Networking essentials lect2Networking essentials lect2
Networking essentials lect2
 
Networking essentials lect1
Networking essentials lect1Networking essentials lect1
Networking essentials lect1
 
Bare metal training_07_spi_flash
Bare metal training_07_spi_flashBare metal training_07_spi_flash
Bare metal training_07_spi_flash
 
Bare metal training_06_I2C
Bare metal training_06_I2CBare metal training_06_I2C
Bare metal training_06_I2C
 
Glesk worshop
Glesk worshopGlesk worshop
Glesk worshop
 
Bare metal training_05_uart
Bare metal training_05_uartBare metal training_05_uart
Bare metal training_05_uart
 
Bare metal training_04_adc_temp_sensor
Bare metal training_04_adc_temp_sensorBare metal training_04_adc_temp_sensor
Bare metal training_04_adc_temp_sensor
 
Bare metal training_03_timers_pwm
Bare metal training_03_timers_pwmBare metal training_03_timers_pwm
Bare metal training_03_timers_pwm
 
Bare metal training_02_le_ds_and_buttons
Bare metal training_02_le_ds_and_buttonsBare metal training_02_le_ds_and_buttons
Bare metal training_02_le_ds_and_buttons
 
Bare metal training_01_hello_world
Bare metal training_01_hello_worldBare metal training_01_hello_world
Bare metal training_01_hello_world
 
Bare metal training_00_prerequisites
Bare metal training_00_prerequisitesBare metal training_00_prerequisites
Bare metal training_00_prerequisites
 
C language lect_23_advanced
C language lect_23_advancedC language lect_23_advanced
C language lect_23_advanced
 
C language lect_22_advanced
C language lect_22_advancedC language lect_22_advanced
C language lect_22_advanced
 
C language lect_21_advanced
C language lect_21_advancedC language lect_21_advanced
C language lect_21_advanced
 
подготовка рабочего окружения
подготовка рабочего окруженияподготовка рабочего окружения
подготовка рабочего окружения
 
C language lect_20_advanced
C language lect_20_advancedC language lect_20_advanced
C language lect_20_advanced
 
C language lect_19_basics
C language lect_19_basicsC language lect_19_basics
C language lect_19_basics
 

06 - Hadoop. Java API и Hadoop Streaming

  • 2. Типы API • org.apache.hadoop.mapreduce – Новое API, будем использовать в примерах • org.apache.hadoop.mapred – Старое API, лучше не использовать
  • 3. Класс Job Содержит описание MapReduce задачи: – input/output пути – Формат input/output данных – Указания классов для mapper, reducer, combiner и partitioner – Типы значений пар key/value – Количество редьюсеров
  • 4. Класс Mapper • void setup(Mapper.Context context) – Вызывается один раз при запуске таска • void map(K key, V value, Mapper.Context context) – Вызывается для каждой пары key/value из input split • void cleanup(Mapper.Context context) – Вызывается один раз при завершении таска
  • 5. Класс Reducer/Combiner • void setup(Reducer.Context context) – Вызывается один раз при запуске таска • void reduce(K key, Iterable<V> values, Reducer.Context context) – Вызывается для каждого key • void cleanup(Reducer.Context context) – Вызывается один раз при завершении таска
  • 6. Класс Partitioner int getPartition(K key, V value, int numPartitions) – Возвращает номер reducer для ключа K
  • 7. “Hello World”: Word Count Map(String docid, String text): for each word w in text: Emit(w, 1); Reduce(String term, Iterator<Int> values): int sum = 0; for each v in values: sum += v; Emit(term, sum);
  • 8. WordCount: Configure Job • Создание объекта Job: • Определение jar для задачи: Job job = Job.getInstance(getConf(), “WordCount"); job.setJarByClass(getClass());
  • 9. WordCount: Configure Job Определение input: – в качестве пути может быть файл, директория, шаблон пути (/path/to/dir/test_*) – TextInputFormat читает входные данные как текстовый файл (key – LongWritable, value – Text) TextInputFormat.addInputPath(job, new Path(args[0])); job.setInputFormatClass(TextInputFormat.class);
  • 10. WordCount: Configure Job Определение output: Если типы для map и reduce отличаются, то: TextOutputFormat.setOutputPath(job, new Path(args[1])); job.setOutputFormatClass(TextOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(LongWritable.class);
  • 11. WordCount: Configure Job • Определение класса для Mapper и Reducer: • Определение класса для Combiner: job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setCombinerClass(WordCountReducer.class);
  • 12. WordCount: запуск задачи Запускает задачу и ждет ее окончания: – true в случае успеха, false в случае ошибки job.waitForCompletion(true);
  • 13. public class WordCountJob extends Configured implements Tool { @Override public int run(String[] args) throws Exception { Job job = Job.getInstance(getConf(), "WordCount"); job.setJarByClass(getClass()); TextInputFormat.addInputPath(job, new Path(args[0])); job.setInputFormatClass(TextInputFormat.class); job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setCombinerClass(WordCountReducer.class); TextOutputFormat.setOutputPath(job, new Path(args[1])); job.setOutputFormatClass(TextOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); return job.waitForCompletion(true) ? 0 : 1; } }
  • 14. public class WordCountJob extends Configured implements Tool{ public static void main(String[] args) throws Exception { int exitCode = ToolRunner.run( new WordCountJob(), args); System.exit(exitCode); } }
  • 15. WordCount: Mapper • Наследник класса: • Должен быть реализован метод map(): • Типы key / value (из org.apache.hadoop.io): – IntWritable – Text – ImmutableBytesWritable public class Mapper <KEYIN, VALUEIN, KEYOUT, VALUEOUT> void map(KEYIN key, VALUEIN value, Context context){}
  • 16. public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private final Text word = new Text(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { StringTokenizer tokenizer = = new StringTokenizer(value.toString()); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); context.write(word, one); } } }
  • 17. WordCount: Reducer • Наследник класса: • Должен быть реализован метод reduce(): • Типы входных данных в Reducer должны совпадать с типами выходных данных Mapper public class Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT> void reduce(KEYIN key, Iterable<VALUEIN> values, Context context){}
  • 18. public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable value : values) { sum += value.get(); } context.write(key, new IntWritable(sum)); } }
  • 19. Reducer в качестве Combiner • Меньше данных отправляется на Reducer • Типы key/value в output у Reducer и Mapper равны • Фреймворк MapReduce не гарантирует вызов Combiner – Нужно только с точки зрения оптимизации – Логика приложения не должна зависеть от вызова вызов Combiner
  • 20. Типы данных в Hadoop • Writable – Определяет протокол де-сериализации. Каждый тип в Hadoop должен быть Writable • WritableComprable – Определяет порядок сортировки. Все ключи должны быть WritableComprable (но не значения!) • Text, IntWritable, LongWritable и т.д. – Конкретные реализации для конкретных типов • SequenceFiles – Бинарно-закодированная последовательность пар key/value
  • 21. Комплексные типы данных в Hadoop Простой способ: – Закодировать в Text – Для раскодирования нужен специальный метод парсинга – Просто, работает, но…
  • 22. Комплексные типы данных в Hadoop Сложный (правильный) способ: – Определить реализацию своего типа Writable(Comprable) – Необходимо реализовать методы readFields, write, (compareTo) – Более производительное решение, но сложнее в реализации
  • 23. Класс InputSplit • Split – это набор логически организованных записей – Строки в файле – Строки в выборке из БД • Каждый экземпляр Mapper обрабатывает один split – Функция map(k, v) вызывается для каждой записи из split • Cплиты реализуются расширением класса InputSplit: – FileSplit – TableSplit
  • 24. Класс InputFormat • Создает input splits • Определяет, как читать каждый split public abstract class InputFormat<K, V> { public abstract List<InputSplit> getSplits(JobContext context) throws IOException, InterruptedException; public abstract RecordReader<K,V> createRecordReader(InputSplit split, TaskAttemptContext context ) throws IOException, InterruptedException; }
  • 25. • Готовые классы-реализации InputFormat: – TextInputFormat • LongWritable / Text – NLineInputFormat • NLineInputFormat.setNumLinesPerSplit(job, 100); – DBInputFormat – TableInputFormat (HBASE) • ImmutableBytesWritable / Result – SequenceFileInputFormat • Выбор нужного формата: job.setInputFormatClass(*InputFormat.class);
  • 26. Класс OutputFormat • Определяет формат выходных данных • Реализация интерфейса класса OutputFormat – Проверяет output для задачи – Создает реализацию RecordWriter – Создает реализацию OutputCommitter
  • 27. • Готовые классы-реализации OutputFormat: – TextOutputFormat – DBOutputFormat – TableOutputFormat (HBASE) – SequenceFileOutputFormat – NullOutputFormat • Выбор нужного формата: job.setOutputFormatClass(*OutputFormat.class); job.setOutputKeyClass(*Key.class); job.setOutputValueClass(*Value.class);
  • 28. Shuffle и Sort в Hadoop • На стороне Map – Выходные данные сохраняются в памяти в циклическом буфере – Когда размер буфера достигает предела, данные “скидываются” (spilled) на диск – Все “сброшенные” части объединяются (merge) в один файл, разбитый на части • Внутри каждой части данные отсортированы • Combiner запускается во время процедуры объединения • На стороне Reduce – Выходные данные от мапперов копируются на машину, где будет запущен редьюсер – Процесс сортировки (sort) представляет собой многопроходный процесс объединения (merge) данных от мапперов • Это происходит в памяти и затем пишется на диск – Итоговый результат объединения отправляется непосредственно на редьюсер
  • 29. Shuffle и Sort в Hadoop Circ Buff (in RAM) spill spill spill Merged spills Combiner Mapper
  • 30. Shuffle и Sort в Hadoop Intermediate files Other mappers Other reducers Reducer sort Merged spills
  • 31. $ hadoop jar <jar> [mainClass] args... Generic Option Описание -conf <conf_file.xml> Добавляет свойства конфигурации из указанного файла в объект Configuration -Dproperty=value Устанавливает значение свойства конфигурации в объекте Configuration -files <file,file,file> Предоставляет возможность использовать указанные файлы в задаче MapReduce через DistributedCache -libjars <f.jar, f2.jar> Добавляет указанные jars к переменной CLASSPATH у тасков задачи и копирует их через DistributedCache $ hadoop jar file.jar org.my.main.class –files dict.txt –D send.stat=true
  • 32. Отладка задач в Hadoop • Логирование – System.out.println – Доступ к логам через веб-интерфейс – Лучше использовать отдельный класс-логер (log4j) – Аккуратней с количество данных в логах • Использование счетчиков: context.getCounter(“GROUP”, “NAME”).increment(1);
  • 34. Hadoop Streaming • Используется стандартный механизм ввода/вывода в Unix для взаимодействия программы и Hadoop • Разработка MR задачи почти на любом языке программирования • Обычно используется: • Для обработки текста • При отсутствии опыта программирования на Java • Для быстрого написания прототипа
  • 35. Streaming в MapReduce • На вход функции map() данные подаются через стандартный ввод • В map() обрабатываются они построчно • Функция map() пишет пары key/value, разделяемые через символ табуляции, в стандартный вывод • На вход функции reduce() данные подаются через стандартный ввод, отсортированный по ключам • Функция reduce() пишет пары key/value в стандартный вывод
  • 36. WordCount на Python Map: countMap.py #!/usr/bin/python import sys for line in sys.stdin: for token in line.strip().split(" "): if token: print token + 't1'
  • 37. Reduce: countReduce.py #!/usr/bin/python import sys (lastKey, sum)=(None, 0) for line in sys.stdin: (key, value) = line.strip().split("t") if lastKey and lastKey != key: print lastKey + 't' + str(sum) (lastKey, sum) = (key, int(value)) else: (lastKey, sum) = (key, sum + int(value)) if lastKey: print lastKey + 't' + str(sum)
  • 38. Запуск и отладка Тест в консоли перед запуском $ cat test.txt | countMap.py | sort | countReduce.py
  • 39. Запуск и отладка Запуск задачи через Streaming Framework: hadoop jar $HADOOP_HOME/hadoop/hadoop-streaming.jar -D mapred.job.name=“WordCount Job via Streaming" -files countMap.py, countReduce.py -input text.txt -output /tmp/wordCount/ -mapper countMap.py -combiner countReduce.py -reducer countReduce.py
  • 40. Python vs. Java #!/usr/bin/python import sys for line in sys.stdin: for token in line.strip().split(""): if token: print token + 't1' #!/usr/bin/python import sys (lastKey, sum)=(None, 0) for line in sys.stdin: (key, value) = line.strip().split("t") if lastKey and lastKey != key: print lastKey + 't' + str(sum) (lastKey, sum) = (key, int(value)) else: (lastKey, sum) = (key, sum + int(value)) if lastKey: print lastKey + 't' + str(sum) public class WordCountJob extends Configured implements Tool{ static public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{ private final static IntWritableone = new IntWritable(1); private final Text word = new Text(); @Override protected void map(LongWritablekey, Text value, Context context) throws IOException, InterruptedException{ StringTokenizer tokenizer = new StringTokenizer(value.toString()); while (tokenizer.hasMoreTokens()){ text.set(tokenizer.nextToken()); context.write(text, one); } } static public class WordCountReducer extends Reducer<Text, IntWritable,Text, IntWritable>{ @Override protected void reduce(Text key, Iterable<IntWritable>values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritablevalue : values) { sum += value.get(); } context.write(key, new IntWritable(sum)); } } @Override public int run(String[] args) throws Exception { Job job = Job.getInstance(getConf(), "WordCount"); job.setJarByClass(getClass()); TextInputFormat.addInputPath(job, new Path(args[0])); job.setInputFormatClass(TextInputFormat.class); job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setCombinerClass(WordCountReducer.class); TextOutputFormat.setOutputPath(job, new Path(args[1])); job.setOutputFormatClass(TextOutputFormat.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); return job.waitForCompletion(true)? 0 : 1; } public static void main(String[] args) throws Exception { int exitCode = ToolRunner.run( new WordCountJob(), args); System.exit(exitCode); } }