2. План лекции
Модель программирования MapReduce
Реализация Google
Знакомство с Apache Hadoop
О.В. Сухорослов () 07 MapReduce 06.04.2012 2 / 77
3. MapReduce
Модель программирования для описания алгоритмов обработки
больших массивов данных
Среда выполнения для параллельной обработки больших объемов
данных
Программная реализация (Google, Hadoop, ...)
О.В. Сухорослов () 07 MapReduce 06.04.2012 3 / 77
4. Феномен Big Data
Коммерческие приложения
Web
десятки миллиардов страниц, сотни терабайт текста
Google MapReduce: 100 TB данных в день (2004), 20 PB (2008)
Социальные сети
Facebook - петабайты пользовательских данных (15 TB/день)
Поведенческие данные пользователей (business intelligence)
Научные приложения
Физика высоких энергий
Большой Адронный Коллайдер - 15 PB/год
Астрономия и астрофизика
Large Synoptic Survey Telescope (2015) - 1.28 PB/год
Биоинформатика
Секвенирование ДНК, European Bioinformatics Institute - 5 PB
(2009)
О.В. Сухорослов () 07 MapReduce 06.04.2012 4 / 77
5. Наблюдения
Мы можем хранить все больше данных
Но латентность и пропускная способность жестких дисков не
успевают за ростом объема
Современные задачи намного превышают возможности одной
машины
Требуются кластеры из сотен и тысяч машин
Стратегия scale out выгоднее стратегии scale up
Данные нельзя разместить полностью в памяти, приходится
обращаться к диску
Последовательные чтение и запись данных при обработке гораздо
эффективнее случайного доступа
О.В. Сухорослов () 07 MapReduce 06.04.2012 5 / 77
6. Наблюдения (2)
Отказы становятся нормой
10K серверов с MTBF=1000d -> 10 отказов в день
Необходимы автоматическая обработка и восстановление после
отказов
Традиционные HPC-системы имеют отдельные системы хранения
данных
Большие объемы данных эффективнее обрабатывать там же, где
они хранятся
Разрабатывать приложения для подобных систем на низком
уровне очень сложно
Требуются высокоуровневые модели программирования,
скрывающие детали системного уровня
Требуются универсальные среды выполнения, масштабируемые и
проверенные на корректность
О.В. Сухорослов () 07 MapReduce 06.04.2012 6 / 77
7. Web Search
Сбор содержимого Web (crawling)
offline, загрузка большого объема данных, выборочное обновление,
обнаружение дубликатов
Построение инвертрованного индекса (indexing)
offline, периодическое обновление, обработка большого объема
данных, предсказуемая нагрузка
Ранжирование документов для ответа на запрос (retrieval)
online, сотни миллисекунд, большое кол-во клиентов, пики
нагрузки
О.В. Сухорослов () 07 MapReduce 06.04.2012 7 / 77
11. Модель программирования MapReduce
Базовой структурой данных являются пары (ключ, значение)
Программа описывается путем определения функций
map : (k1, v 1) → [(k2, v 2)]
reduce : (k2, [v 2]) → [(k3, v 3)]
Между map и reduce происходит группировка и сортировка
промежуточных данных по ключу k2
О.В. Сухорослов () 07 MapReduce 06.04.2012 11 / 77
17. Дополнительные функции
partition : (k2, num_reducers) → reducer _id
Определяет распределение промежуточных данных между
reduce-процессами
Простейший случай: hash(k2) mod num_reducers
combine : (k2, [v 2]) → [(k2 , v 2 )]
Осуществляет локальную агрегацию промежуточных данных после
map() в рамках одного map-процесса
Для ассоциативных и коммутативных операций может
использоваться reduce()
compare(k2, k2 ) → {−1, 0, 1}
Определяет отношение порядка между промежуточными ключами
О.В. Сухорослов () 07 MapReduce 06.04.2012 17 / 77
19. Запуск MapReduce-программы
Конфигурация задания
Входные данные, способ получения (k1,v1)
Функции map, reduce, partition, combine, compare
Местоположение и формат выходных данных
Параметры запуска (число map- и reduce-заданий...)
Запуск задания: MapReduce.runJob(config)
Остальное берет на себя реализация среды выполнения
О.В. Сухорослов () 07 MapReduce 06.04.2012 19 / 77
20. Обязанности реализации
Декомпозиция на параллельные подзадачи (map- и reduce-задачи)
Запуск рабочих процессов
Распределение задач по рабочим процессам и балансировка
нагрузки
Передача данных рабочим процессам (требуется минимизировать)
Синхронизация и передача данных между рабочими процессами
Обработка отказов рабочих процессов
О.В. Сухорослов () 07 MapReduce 06.04.2012 20 / 77
21. Реализации MapReduce
Распределенная память (кластер)
Google MapReduce (C++ / С++, Python, Java)
Apache Hadoop (Java / any)
Disco (Erlang / Python)
Skynet (Ruby)
Holumbus-MapReduce (Haskell)
FileMap: File-Based Map-Reduce
Yandex MapReduce (С++ / any)
...
Общая память (многоядерные процессоры)
QtConcurrent (C++)
Phoenix (C, C++)
GPU
Mars: A MapReduce Framework on Graphics Processors
О.В. Сухорослов () 07 MapReduce 06.04.2012 21 / 77
22. Инфраструктура Google
Кластеры из дешевых серверов
PC-class motherboards, low-end storage/networking
Linux + свое ПО
Сотни тысяч машин
Отказы являются нормой
Распределенная файловая система GFS
Поблочное хранение файлов большого размера
Последовательные чтение и запись в потоковом режиме
write-once-read-many
Репликация, отказоустойчивость
Узлы кластера одновременно отвечают за хранение и обработку
данных
Перемещение вычислений дешевле, чем перемещение данных
Планировщик
Распределяет ресурсы кластера между приложениями
О.В. Сухорослов () 07 MapReduce 06.04.2012 22 / 77
25. Мастер
Управляет выполнением одного MapReduce-задания
Распределяет задачи между рабочими узлами кластера
Хранит состояния всех задач
status, workerId
Осуществляет координацию между map- и reduce-задачами
Получает информацию о файлах с промежуточными данными от
map-процессов
Передает эту информацию reducе-процессам
Предоставляет информацию о статусе вычислений через
встроенный HTTP-сервер
О.В. Сухорослов () 07 MapReduce 06.04.2012 25 / 77
26. Оптимизации
Локальность данных
Направлять map-задачи на узлы, хранящие требуемые данные или
находящиеся рядом
Локальная редукция
Выполнять после map функцию сombine
Совмещение операций
Загрузка и сортировка промежуточных данных
Спекулятивное выполнение
В конце map или reduce запустить незавершенные задания на
нескольких машинах
О.В. Сухорослов () 07 MapReduce 06.04.2012 26 / 77
28. Отказоустойчивость
Сбой при выполнении задачи
Отказ рабочего узла
Сбой аппаратуры, ПО или отзыв узла планировщиком (preemption)
Определяется через heartbeat
Перезапуск задач
Map - всех выполненных или незаконченных + уведомление
reduce-процессов
Reduce только незаконченных
Отказ мастера
О.В. Сухорослов () 07 MapReduce 06.04.2012 28 / 77
29. Семантика распределенного выполнения программы
Для детерминированных функций map и reduce гарантируется
совпадение результата вычислений с результатом
последовательного выполнения программы
Для недетерминированных функций map и reduce гарантируется
совпадение результата каждой reduce-задачи с результатом
последовательного выполнения программы
Результаты разных reduce-задач могут соответствовать разным
последовательным выполнениям
Атомарные операции
Передача списка промежуточных файлов от map-процесса к
мастеру
Переименование файла в GFS с результатом reduce-задания
Поддержка выполнения на локальной машине
О.В. Сухорослов () 07 MapReduce 06.04.2012 29 / 77
30. Количество задач
Много больше числа машин
Динамическая балансировка нагрузки
Восстановление после отказов
Число map-задач M
Input / M ∼ 16-64 Mb
Число reduce-задач R
В несколько (∼2) раз больше числа машин
Для N=2000: M=200000, R=5000
О.В. Сухорослов () 07 MapReduce 06.04.2012 30 / 77
31. MapReduce в Google
large-scale machine learning problems
clustering problems for the Google News and Froogle products
extracting data to produce reports of popular queries
extracting properties of Web pages for new experiments and products
processing of satellite imagery data
language model processing for statistical machine translation
large-scale graph computations
О.В. Сухорослов () 07 MapReduce 06.04.2012 31 / 77
32. Пример кода (Map)
1 # include " mapreduce / mapreduce . h "
2
3 // User ’s map function
4 class WordCounter : public Mapper {
5 public :
6 virtual void Map ( const MapInput & input ) {
7 const string & text = input . value ();
8 const int n = text . size ();
9 for ( int i = 0; i < n ; ) {
10 // Skip past leading whitespace
11 while (( i < n ) && isspace ( text [ i ]))
12 i ++;
13
14 // Find word end
15 int start = i ;
16 while (( i < n ) && ! isspace ( text [ i ]))
17 i ++;
18 if ( start < i )
19 Emit ( text . substr ( start ,i - start ) , " 1 " );
20 }
21 }
22 };
23 REGISTER_MAPPER ( WordCounter );
О.В. Сухорослов () 07 MapReduce 06.04.2012 32 / 77
33. Пример кода (Reduce)
1 // User ’s reduce function
2 class Adder : public Reducer {
3 virtual void Reduce ( ReduceInput * input ) {
4 // Iterate over all entries with the
5 // same key and add the values
6 int64 value = 0;
7 while (! input - > done ()) {
8 value += StringToInt ( input - > value ());
9 input - > NextValue ();
10 }
11
12 // Emit sum for input - > key ()
13 Emit ( IntToString ( value ));
14 }
15 };
16 REGISTER_REDUCER ( Adder );
О.В. Сухорослов () 07 MapReduce 06.04.2012 33 / 77
34. Пример кода (main)
1 int main ( int argc , char ** argv ) {
2 Par se C o m m a n d L i n e Flag s ( argc , argv );
3
4 Ma pR e d u c e S p e c i f i c ati on spec ;
5
6 // Store list of input files into " spec "
7 for ( int i = 1; i < argc ; i ++) {
8 MapReduceInput * input = spec . add_input ();
9 input - > set_format ( " text " );
10 input - > set_filepattern ( argv [ i ]);
11 input - > set_mapper_class ( " WordCounter " );
12 }
13
14 // Specify the output files :
15 MapReduceOutput * out = spec . output ();
16 out - > set_filebase ( " / gfs / test / freq " );
17 out - > set_num_tasks (100);
18 out - > set_format ( " text " );
19 out - > set_r educer_class ( " Adder " );
О.В. Сухорослов () 07 MapReduce 06.04.2012 34 / 77
35. Пример кода (main)
1 // Optional : do partial sums within map
2 // tasks to save network bandwidth
3 out - > s et _co mb in er_class ( " Adder " );
4
5 // Tuning parameters : use at most 2000
6 // machines and 100 MB of memory per task
7 spec . set_machines (2000);
8 spec . set_m ap_megabytes (100);
9 spec . s e t _ r e du c e _ megabytes (100);
10
11 // Now run it
12 MapReduceResult result ;
13 if (! MapReduce ( spec , & result )) abort ();
14
15 // Done : ’ result ’ structure contains info
16 // about counters , time taken , number of
17 // machines used , etc .
18 return 0;
19 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 35 / 77
36. Преимущества MapReduce
Модель программирования
Высокий уровень абстракции за счет скрытия деталей организации
вычислений внутри библиотеки
Позволяет разработчику сконцентрироваться на решаемой задаче
Легкость добавления новых стадий обработки
Реализация
Автоматическое распараллеливание, распределение заданий и
балансирование нагрузки
Устойчивость к отказам
Масштабируемость
О.В. Сухорослов () 07 MapReduce 06.04.2012 36 / 77
40. Цели
Открытые реализации технологий Google (GFS, MapReduce...)
Программная платформа для хранения и обработки больших
объемов данных
Надежность
Масштабируемость
Эффективность
Экономичность
Open Source
О.В. Сухорослов () 07 MapReduce 06.04.2012 40 / 77
41. Подпроекты
Hadoop Common
Общие компоненты
HDFS
Распределенная файловая система по образу GFS
MapReduce
Реализация MapReduce для распределенной обработки больших
объемов данных на кластере
О.В. Сухорослов () 07 MapReduce 06.04.2012 41 / 77
43. Hadoop Distributed File System (HDFS)
Хранение больших наборов данных
Отказоустойчивость
Модель "write-once-read-many"
Streaming data access
Перемещение вычислений дешевле, чем перемещение данных
О.В. Сухорослов () 07 MapReduce 06.04.2012 43 / 77
44. HDFS
Иерархическая структура
Управляется выделенным узлом namenode
Файлы разбиваются на блоки (chunks)
По умолчанию 64 Mb
Файлы хранятся на узлах datanodes
Репликация, по умолчанию 3 копии
Клиенты
Поиск ближайшей реплики с помощью namenode
Получение данных напрямую с datanode
О.В. Сухорослов () 07 MapReduce 06.04.2012 44 / 77
48. Hadoop MapReduce
JobTracker
Принимает задания (job) от приложений
Разбивает задание на много задач (tasks)
Распределяет задачи по узлам
Отслеживает выполнение задач
Осуществляет перезапуск задач
TaskTracker
Запрашивает новые задачи
Загружает код и запускает задачу в новой JVM
Уведомляет JobTracker о статусе задачи
Предоставляет доступ к промежуточным файлам
О.В. Сухорослов () 07 MapReduce 06.04.2012 48 / 77
49. Реализация MapReduce-программ для Hadoop
Java
Стандартный Java API
Другие языки и скрипты
Hadoop Streaming
C++ (и другие языки через SWIG)
Hadoop Pipes
О.В. Сухорослов () 07 MapReduce 06.04.2012 49 / 77
51. Общая структура программы
Реализации Mapper и Reducer (Partitioner, Combiner...)
Код формирования и запуска задания
Ожидание результата или выход
О.В. Сухорослов () 07 MapReduce 06.04.2012 51 / 77
53. Реализация по умолчанию
1 protected void map ( KEYIN key , VALUEIN value , Context context )
2 throws IOException , I n te r r u pt e d E xc e p t ion {
3 context . write (( KEYOUT ) key , ( VALUEOUT ) value );
4 }
5
6 public void run ( Context context )
7 throws IOException , I n te r r u pt e d E xc e p t ion {
8 setup ( context );
9 while ( context . nextKeyValue ()) {
10 map ( context . getCurrentKey () , context . getCurrentValue () ,
11 context );
12 }
13 cleanup ( context );
14 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 53 / 77
54. WordCount: Mapper
1 public static class TokenizerMapper
2 extends Mapper < LongWritable , Text , Text , IntWritable > {
3
4 private final static IntWritable one = new IntWritable (1);
5 private Text word = new Text ();
6
7 public void map ( LongWritable key , Text value , Context context )
8 throws IOException , I n t e r r u pt edException {
9 StringTokenizer tok = new StringTokenizer ( value . toString ())
10 while ( tok . hasMoreTokens ()) {
11 word . set ( tok . nextToken ());
12 context . write ( word , one );
13 }
14 }
15 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 54 / 77
56. Реализация по умолчанию
1 protected void reduce ( KEYIN key , Iterable < VALUEIN > values ,
2 Context context ) throws IOException , Inter ru pt ed Ex ce pt ion {
3 for ( VALUEIN value : values ) {
4 context . write (( KEYOUT ) key , ( VALUEOUT ) value );
5 }
6 }
7
8 public void run ( Context context )
9 throws IOException , I n te r r u pt e d E xc e p t ion {
10 setup ( context );
11 while ( context . nextKey ()) {
12 reduce ( context . getCurrentKey () , context . getValues () ,
13 context );
14 }
15 cleanup ( context );
16 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 56 / 77
57. WordCount: Reducer
1 public static class IntSumReducer
2 extends Reducer < Text , IntWritable , Text , IntWritable > {
3 public void reduce ( Text key , Iterable < IntWritable > values ,
4 Context context )
5 throws IOException , I n t e r r u pt edException {
6 int sum = 0;
7 for ( IntWritable val : values ) {
8 sum += val . get ();
9 }
10 context . write ( key , new IntWritable ( sum ));
11 }
12 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 57 / 77
58. Конфигурация и запуск задания
1 public class WordCount extends Configured implements Tool {
2
3 public static void main ( String [] args ) throws Exception {
4 int ret = ToolRunner . run ( new WordCount () , args );
5 System . exit ( ret );
6 }
7
8 public int run ( String [] args ) throws Exception {
9 if ( args . length != 2) {
10 System . err . println (
11 " Usage : lecture7 . WordCount < input > < output > " );
12 return -1;
13 }
14
15 Job job = new Job ( getConf ());
16 job . setJarByClass ( WordCount . class );
17 job . setJobName ( " wordcount " );
18
19 job . setMapperClass ( TokenizerMapper . class );
20 job . setCombinerClass ( IntSumReducer . class );
21 job . setReducerClass ( IntSumReducer . class );
О.В. Сухорослов () 07 MapReduce 06.04.2012 58 / 77
59. Конфигурация и запуск задания
1 job . s et M a pOu t p u tKe y C l a s s ( Text . class );
2 job . s e t M a p O u t p u t V a lu e C l a s s ( IntWritable . class );
3 job . set OutputKe yClass ( Text . class );
4 job . s et Output Va lu e Cl a ss ( IntWritable . class );
5
6 job . s et InputF or ma t Cl a ss ( TextInputFormat . class );
7 job . s et O u tpu t F o rma t C l a s s ( TextOutputFormat . class );
8
9 FileInputFormat . addInputPath ( job , new Path ( args [0]));
10 FileOutputFormat . setOutputPath ( job , new Path ( args [1]));
11
12 boolean success = job . waitF orCompletion ( true );
13 return success ? 0 : 1;
14 }
15 }
О.В. Сухорослов () 07 MapReduce 06.04.2012 59 / 77
60. Входные и выходные данные
(input) → (k1, v 1) → map → (k2, v 2) → combine → (k2, v 2) →
reduce → (k3, v 3) → (output)
Базовые интерфейсы
Входные данные: InputFormat
Выходные данные: OutputFormat
Ключи: WritableComparable
Значения: Writable
О.В. Сухорослов () 07 MapReduce 06.04.2012 60 / 77
61. Типы данных
Text
BooleanWritable
IntWritable
LongWritable
FloatWritable
DoubleWritable
BytesWritable
ArrayWritable
MapWritable
...
См. пакет org.apache.hadoop.io
О.В. Сухорослов () 07 MapReduce 06.04.2012 61 / 77
62. InputFormat
TextInputFormat (по умолчанию)
< LongWritable, Text > = < byte_offset, line >
KeyValueTextInputFormat
< Text, Text >
Текстовый файл со строками вида: key [tab] value
SequenceFileInputFormat<K,V>
Двоичный формат с поддержкой сжатия
...
О.В. Сухорослов () 07 MapReduce 06.04.2012 62 / 77
64. Установка Hadoop на локальной машине
Установить Java
Загрузить дистрибутив Hadoop и распаковать в любую
директорию (далее HADOOP_HOME)
Linux
Открыть файл HADOOP_HOME/conf/hadoop-env.sh и прописать в
переменной JAVA_HOME путь к Java (путь с пробелами надо
взять в кавычки)
Windows
Прописать переменную окружения JAVA_HOME с путем к Java
(Мой компьютер > Свойства > закладка Дополнительно >
Переменные среды)
Дополнительно установить Cygwin, эмулятор Unix shell
Команды hadoop под Windows следует запускать внутри Cygwin
shell
О.В. Сухорослов () 07 MapReduce 06.04.2012 64 / 77
65. Альтернативный вариант
Виртуальная машина с Hadoop
Cloudera’s Hadoop Demo VM
О.В. Сухорослов () 07 MapReduce 06.04.2012 65 / 77
66. Компилируем и создаем jar
Eclipse
Добавить в проект HADOOP_HOME/hadoop-*-core.jar
Build project
File -> Export -> Java / JAR file
Вручную
1 $ mkdir classes
2 $ javac
3 - classpath $ { HADOOP_HOME }/ hadoop - $ { HADOOP_VERSION } - core . jar
4 -d classes WordCount . java
5 $ jar - cvf wordcount . jar -C classes / .
О.В. Сухорослов () 07 MapReduce 06.04.2012 66 / 77
67. Запускаем программу локально
Находясь в HADOOP_HOME
1 $ bin / hadoop jar wordcount . jar lecture7 . WordCount IN OUT
IN - директория с входными файлами
OUT - директория с результатами
не должна существовать перед запуском
О.В. Сухорослов () 07 MapReduce 06.04.2012 67 / 77
68. Запуск из IDE (Eclipse)
Подключаем к проекту HADOOP_HOME/hadoop-*-core.jar и все
библиотеки из HADOOP_HOME/lib
Project->Properties->Java Build Path->Libraries->Add External
JARs...
Создаем Run Configuration, где указываем свой Java-класс
(вкладка Main) и аргументы main (Arguments/Program Arguments)
в VM arguments следует добавить -Xmx512M во избежание
OutOfMemoryError
пути к локальным input- и output-директориям можно указывать
относительно директории проекта
Под Windows может потребоваться Cygwin
О.В. Сухорослов () 07 MapReduce 06.04.2012 68 / 77
69. Число задач
Maps
Определяется числом блоков во входных файлах, размером блока,
параметром mapred.min.split.size, реализацией InputFormat
Reduces
По умолчанию 1 (всегда в локальном режиме)
Опция -D mapred.reduce.tasks=N или метод
job.setNumReduceTasks(int)
Обычно подбирается опытным путем
Время выполнения reduce должно быть не менее минуты
0, если Reduce не нужен
О.В. Сухорослов () 07 MapReduce 06.04.2012 69 / 77
70. Стандартные опции
1 - conf < configuration file > // specify a configuration file
2
3 -D < property = value > // use value for given property
4 -D mapred . reduce . tasks =10
5
6 - files < comma separated list of files >
7 // files to be copied to the map reduce cluster
8
9 - libjars < comma seperated list of jars >
10 // jar files to include in the classpath
11
12 - archives < comma separated list of archives >
13 // archives to be unarchived on the compute machines
О.В. Сухорослов () 07 MapReduce 06.04.2012 70 / 77
71. Запуск на учебном кластере
Копируем jar и исходные данные в домашнюю директорию на
кластере (/home/USER) по SCP
Заходим на кластер по SSH
Загружаем исходные данные в HDFS
Запускаем MapReduce-задание
Загружаем результаты из HDFS
О.В. Сухорослов () 07 MapReduce 06.04.2012 71 / 77
72. Загружаем исходные данные в HDFS
Копирование из локальной директории в HDFS
1 $ hadoop dfs - put local_dir hdfs_dir
dfs_dir лучше задавать в относительном виде, тогда полный путь
будет /user/USER/dfs_dir
1 $ hadoop dfs - mkdir wordcount
2 $ hadoop dfs - put / home / USER / input wordcount / input
О.В. Сухорослов () 07 MapReduce 06.04.2012 72 / 77
73. Запускаем MapReduce-задание
В одну строку
1 $ hadoop jar wordcount . jar lecture7 . WordCount
2 -D mapred . reduce . tasks =1
3 wordcount / input wordcount / output
О.В. Сухорослов () 07 MapReduce 06.04.2012 73 / 77
74. Загружаем результаты из HDFS
Копирование из HDFS в локальную директорию
1 $ hadoop dfs - get wordcount / output output
Просто просмотр
1 $ hadoop dfs - cat wordcount / output / part -00000
О.В. Сухорослов () 07 MapReduce 06.04.2012 74 / 77
75. Повторный запуск
Перед каждым запуском надо удалять из HDFS
output-директорию (wordcount/output)
Или каждый раз указывать новую output-директорию
wordcount/output2(3...)
О.В. Сухорослов () 07 MapReduce 06.04.2012 75 / 77
76. Web-интерфейсы
HDFS
http://hadoop2.yandex.ru:50070
MapReduce
http://hadoop2.yandex.ru:50030
Для доступа необходимо настроить прокси через SSH
См. инструкцию к учебному кластеру на вики
О.В. Сухорослов () 07 MapReduce 06.04.2012 76 / 77
77. Домашнее задание №3 - Подготовка
Задачи
Определить 20 наиболее часто встречающихся слов в русской
(только русские слова) и английской Википедиях
Построить инвертированный индекс для русской и английской
Википедий
Подробности будут на следующем занятии
До следующего занятия
установить Hadoop на своей машине
скомпилировать сегодняшний пример WordCount
(запустить WordCount на своей машине)
запустить WordCount на учебном кластере
в качестве входных данных можно использовать любые текстовые
файлы
убедиться, что все работает и понятно
если нет - задать вопрос на shad-pdc-2012@yandex.ru
О.В. Сухорослов () 07 MapReduce 06.04.2012 77 / 77