用Hive,S3,EMR加载数据,并恢复分区



已解决:有关此问题的'解决方案',请参见下面的更新#2。

~~~~~~~~

在S3中,我有一些log*.gz文件存储在嵌套目录结构中,例如:

s3://($BUCKET)/y=2012/m=11/d=09/H=10/

我正在尝试使用多级分区规格上的弹性地图减少(EMR)将它们加载到Hive中。

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 =)
  • 正确运行恢复分区可以发现这些分区...
  • 但随后将它们内部存储为小写(h)

"恢复分区"命令是亚马逊撰写的Hive的扩展。我强烈怀疑该错误是在此组件中。据我所知

这是小时字段上的案例问题!

最新更新