一个典型的问题是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"一次?
看起来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,400,000字节(我只是看了看这些数字并做了基本的数学计算)。I run the job:
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表。
你也可以有两个Hive表:"旧"表按月分区,"新"表按天分区。然后用户可以在查询时对两者进行联合,或者您可以创建一个自动进行联合的视图。