11

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

~~~~~~~

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

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

我正在尝试使用多级分区规范将这些加载到 Elastic Map Reduce (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/'

我可以写一个脚本来做到这一点,但感觉就像我错过了一些基本的东西'恢复分区'。

更新#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 的扩展。我强烈怀疑这个组件中存在错误。据我所知,本地 Hive 没有探索文件根目录以进行分区发现的概念......

4

1 回答 1

10

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

于 2012-11-13T21:36:38.580 回答