Могут ли два раздела Hive совместно использовать один набор файлов?

Типичный вопрос: может ли раздел Hive состоять из нескольких файлов? Мой вопрос обратный. Могут ли несколько разделов Hive указывать на один и тот же файл? Я начну с того, что я имею в виду, а затем прецедент.

Что я имею в виду:

Hive Partition      File Name
20120101            /file/location/201201/file1.tsv
20120102            /file/location/201201/file1.tsv
20120103            /file/location/201201/file1.tsv

Вариант использования: в течение последних многих лет мы загружали данные в Hive в ежемесячном формате. Так это выглядело так:

Hive Partition      File Name
201201              /file/location/201201/file1.tsv
201202              /file/location/201202/file1.tsv
201203              /file/location/201203/file1.tsv

Но сейчас месяцы слишком велики, поэтому нам нужно разделить по дням. Поэтому мы хотим, чтобы новые файлы, начиная с 201204, были ежедневными:

Hive Partition      File Name
20120401            /file/location/20120401/file1.tsv
20120402            /file/location/20120402/file1.tsv
20120403            /file/location/20120403/file1.tsv

Но мы хотим, чтобы все существующие разделы также были переделаны ежедневно, поэтому мы разбили бы его, как я предлагаю выше. Я подозреваю, что это на самом деле не будет работать, за исключением того, что я подозреваю, что Hive будет перечитывать один и тот же файл данных N раз для каждого дополнительного раздела, определенного для файла. Например, в самом первом блоке кода "Что я имею в виду" выше разделы 20120101..20120103 указывают на файл 201201 / file1.tsv. Так что, если запрос имеет:

and partitionName >= '20120101' and partitionName <= '20120103"

Будет ли он читать "201201 / file1.tsv" три раза, чтобы ответить на запрос? Или Hive будет достаточно умен, чтобы знать, что сканировать "201201 / file1.tsv" нужно всего один раз?

2 ответа

Похоже, Hive будет сканировать файл (ы) только один раз. Я наконец решил просто дать ему шанс и выполнить запрос и выяснить.

Сначала я настроил свой набор данных в файловой системе следующим образом:

tableName/201301/splitFile-201301-xaaaa.tsv.gz
tableName/201301/splitFile-201301-xaaab.tsv.gz
...
tableName/201301/splitFile-201301-xaaaq.tsv.gz

Обратите внимание, что хотя у меня много файлов, для Hive это эквивалентно наличию одного гигантского файла для целей этого вопроса. Если это облегчает, сделайте вид, что я просто вставил один файл выше.

Затем я установил свою таблицу Hive с такими разделами:

alter table tableName add partition ( dt = '20130101' ) location '/tableName/201301/' ;
alter table tableName add partition ( dt = '20130102' ) location '/tableName/201301/' ;
...
alter table tableName add partition ( dt = '20130112' ) location '/tableName/201301/' ;

Общий размер моих файлов в tableName/201301 составил около 791 400000 байт (я просто набрал цифры и выполнил базовую математику). Я выполнил работу:

hive> select dt,count(*) from tableName where dt >= '20130101' and dt <= '20130112' group by dt ;

JobTracker сообщил:

Counter     Map             Reduce    Total
Bytes Read  795,308,244     0         795,308,244

Так что читать данные можно только один раз. ОДНАКО... вывод запроса был весь подбит:

20130112    392606124

Таким образом, он думает, что был только один "dt", и это был последний "раздел", и в нем были все строки. Поэтому вы должны быть очень осторожны, включая "dt" в свои запросы, когда вы делаете это, это может показаться.

Улей будет сканировать файл несколько раз. Ранее ответ был неверным. Hive читает файл один раз, но генерирует "дубликаты" записей. Проблема заключается в том, что столбцы разделов включены в общую запись, поэтому для каждой записи в файле вы получите несколько записей в Hive, каждая из которых имеет разные значения раздела.

У вас есть какой-нибудь способ восстановить фактический день из предыдущих данных? Если это так, то идеальный способ сделать это - полностью перераспределить все старые данные. Это больно, но это единовременная плата, которая избавила бы вас от действительно странного стола Hive.

Вы также можете перейти к созданию двух таблиц Hive: "старой", разделенной по месяцам, и "новой", разделенной по дням. Затем пользователи могут объединить эти два элемента при запросе, или вы можете создать представление, которое выполняет объединение автоматически.

Другие вопросы по тегам