Итак, если вы внимательно прочитали все мои предыдцщие посты - вы теперь знаете достаточно, что бы воспринять 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)
- Используйте где это возможно условие where (сократит выход map)
Mijatovic, спасибо тебе за предоставляемую информацию.
ReplyDeleteСкажи пожалуйста ты сам исследуешь эту область и работаешь с Hadoop ?
Я так понимаю в ближайшее время данная тема будет популярна в России, но еще мало где используется.
С уважением,
Николай.
Mijatovc, еще вопрос.
ReplyDeleteС твоей точки зрения какие программы будут быстрее работать:
написанные на языке Java?
Написанные на языке Hive?
Хотелось бы услышать твое мнение по этому вопросу.
С уважением,
Николай.
> С твоей точки зрения какие программы будут быстрее работать:
ReplyDeleteHive это всего лишь интерпретатор, то есть те селекты которые вы пишете трансформируются в Java (собираются как конструктор из уже скомпилированных). Иногда будет выгоднее написать кастомный код на java, иногда на java можно наделат ошибок. Писать на hive намного проще. Вопрос в общем философский, но как правило производительность будет соизмерима.