Могут ли два раздела 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: "старой", разделенной по месяцам, и "новой", разделенной по дням. Затем пользователи могут объединить эти два элемента при запросе, или вы можете создать представление, которое выполняет объединение автоматически.