解决了: 有关此问题的“解决方案”,请参阅下面的更新#2。
~~~~~~~
在s3中,我有一些log * .gz文件存储在嵌套目录结构中,如:
s3://($BUCKET)/y=2012/m=11/d=09/H=10/
我试图使用多级分区规范将这些加载到Hlastic on Elastic Map Reduce(EMR)上,如:
create external table logs (content string)
partitioned by (y string, m string, d string, h string)
location 's3://($BUCKET)';
创建表工作。然后我尝试恢复所有现有分区:
alter table logs recover partitions;
这似乎工作,它确实钻取我的s3结构并添加所有不同级别的目录:
hive> show partitions logs;
OK
y=2012/m=11/d=06/h=08
y=2012/m=11/d=06/h=09
y=2012/m=11/d=06/h=10
y=2012/m=11/d=06/h=11
y=2012/m=11/d=06/h=12
y=2012/m=11/d=06/h=13
y=2012/m=11/d=06/h=14
y=2012/m=11/d=06/h=15
y=2012/m=11/d=06/h=16
...
因此,Hive似乎可以成功查看和解释我的文件布局。但是,没有实际数据被加载。如果我尝试做一个简单的计数或选择*,我什么也得不到:
hive> select count(*) from logs;
...
OK
0
hive> select * from logs limit 10;
OK
hive> select * from logs where y = '2012' and m = '11' and d = '06' and h='16' limit 10;
OK
思考?我是否缺少一些额外的命令来加载数据而不是恢复分区?
如果我手动添加具有显式位置的分区,那么它的工作原理如下:
alter table logs2 add partition (y='2012', m='11', d='09', h='10') location 's3://($BUCKET)/y=2012/m=11/d=09/H=10/'
我可以写一个脚本来做这件事,但感觉我错过了一些基本的w.r.t'恢复分区'。
更新#1
感谢Joe K在下面的评论中的精彩和敏锐的观察,我认为这里可能涉及区分大小写的问题。
文件肯定像下面的路径规范一样组织,大写H(我想这可能是对iso8601格式的一些点头):
s3://($BUCKET)/y=2012/m=11/d=09/H=10/
我使用分区规范创建我的外部表,该规范执行正确的大小写:
partitioned by (y string, m string, d string, H string)
(注意'H')。我做了一个恢复分区,它似乎通过目录递归并适当地找到分区,但不知何故(尽管到目前为止在所有指导性地方使用'H'),Hive似乎确实将它保存为小写'h' :
hive> show partitions logs;
OK
y=2012/m=11/d=06/h=08
(注意'h')。所以似乎Hive能够发现分区,但是然后以小写形式存储它们......后来当它去寻找数据时,这些路径(当然)是空的,因为S3区分大小写。
我将把我的数据移动到一个全小写的目录结构,看看是否有效......
更新#2
实际上,我已经确认大写的'H'作为分区名称(在s3文件布局中)是这里的问题。据我所知,这就是发生的事情:
- 我在S3上的布局有一个区分大小写的分区名称(H =)
- 正确运行RECOVER PARTITIONS会发现这些分区......
- 但是它们在内部存储为小写(h)
'recover partitions'命令是Amazon创建的Hive的扩展。我强烈怀疑这个bug是在这个组件中。据我所知,本地Hive没有探索分区发现的文件根的概念......