Tuesday, 19 March 2013

Пост 9. Hive и MapReduce. Агрегаты.

Итак, если вы внимательно прочитали все мои предыдцщие посты - вы теперь знаете достаточно, что бы воспринять Hive как MapReduce инструмент. Только задания Map и Reduce вы пишете не на Java, а на HQL (язык весьма напоминающий SQL, но там нет некоторых конструкций - одиночной вставки, update...). На самом деле MapReduce вы "пишете в двух метах" - при создании таблицы и при написании select.
Рассмотрим пример. У Вас есть плоский файл (csv), который лежит в HDFS. Плоский файл вида:
col1, col2, col3, col4
........
Лежит допустим где то в /user/examples/csv (естественно в hdfs).
Описываем его следующим DDL:
CREATE EXTERNAL TABLE `simplest_csv`
(
  `a` string ,
  `b` string ,
  `c` string ,
  `d` string )
ROW FORMAT   DELIMITED
    FIELDS TERMINATED BY ','
  STORED AS TextFile LOCATION "/user/examples/csv"

Возьмен конкретный пример файла, который поместим в HDFS:
333, wqer, 56, 88m
2, wqer, 56, 88m
334, wqert, 54, 88w
335, wqerty, 59, 88e

Напишем запрос к этиму файлу

select sum(a),b from simplest_csv
group by b

Что будет происходить на фазах Map и Reduce?
На вход будет подаваться строка, RR будет преобразовывать ее в пару ключ-значение (ключом будет являться смещением строки относительно начала файла). Внутри Map будет происходить преобразование к новой паре ключ-значение: будут "викинуты" не перечисленые колонки (так что перечисляйте только то что надо перечислить!) колонка (колонки) по которой идет группировка - будет ключом, та котонка которую надо суммировать - значением. Новая пара KV идет на Reduce (как и многие другие). Но перед пересылкой на Reduce в Hive всегда на агрегационных функцияю применяется combiner. Что делает reduce думаю объяснять не надо.
Описав этот процесс думаю так же бессмысленно говорить о том что подобные запросы линейно масштабируемы - я думаю все и так все поняли:)

Окей, с csv все вроде бы ясно. А как быть с полуструктурированными даными? Допустим с JSON? Все опять предельно просто и алгоритмично! 
Возьмем файл данных 
{column1:333, column2: wqer, column3: 56}
{column1: 2, column2: wqer, column3: 56}
{column1: 334, column2: wqert, column3: 54}
{column1: 335, column2: wqerty, column3: 59}

и положим его в HDFS
[root@cdh ~]# sudo -u hdfs hadoop fs -mkdir /user/examples/json
[root@cdh ~]# sudo -u hdfs hadoop fs -put /tmp/1234 /user/examples/json/

Создаем таблицу:
CREATE EXTERNAL TABLE simplest_json
(column1 string,column2 string,column3 string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde'
LOCATION '/user/examples/json/'

И пишем запрос. Запрос к слову ничем не отличается от предыдущего:
select sum(column1),column2 from simplest_json
group by column2

И что же происходит? Практически то же самое что и в случае CSV, только на стадии Map происходит еще и парсинг строки (разбор JSON).


Просто магия какая то:)
Подытожим: 

1) Map:
- Перекомбинирование пар Key-Value
- Парсинг строчки
- Фильтрация по условию where
- Combiner (локальный reduce)
- Применение функций к некоторым
- Локальная свертка по колонкам если это необходимо

2) Reduce:
- свертка
Вывоы:
- Перечисляйте только нужные колонки (сократит выход map)
- Используйте где это возможно условие where (сократит выход map)

3 comments:

  1. Mijatovic, спасибо тебе за предоставляемую информацию.

    Скажи пожалуйста ты сам исследуешь эту область и работаешь с Hadoop ?

    Я так понимаю в ближайшее время данная тема будет популярна в России, но еще мало где используется.

    С уважением,
    Николай.

    ReplyDelete
  2. Mijatovc, еще вопрос.

    С твоей точки зрения какие программы будут быстрее работать:
    написанные на языке Java?
    Написанные на языке Hive?

    Хотелось бы услышать твое мнение по этому вопросу.

    С уважением,
    Николай.

    ReplyDelete
  3. > С твоей точки зрения какие программы будут быстрее работать:
    Hive это всего лишь интерпретатор, то есть те селекты которые вы пишете трансформируются в Java (собираются как конструктор из уже скомпилированных). Иногда будет выгоднее написать кастомный код на java, иногда на java можно наделат ошибок. Писать на hive намного проще. Вопрос в общем философский, но как правило производительность будет соизмерима.

    ReplyDelete