无法对 HDFS 支持的配置单元表进行分区

Posted

技术标签:

【中文标题】无法对 HDFS 支持的配置单元表进行分区【英文标题】:Unable to partition hive table backed by HDFS 【发布时间】:2018-01-23 21:10:43 【问题描述】:

也许这是一个简单的问题,但是我很难解决这个问题。目前,我有一个伪分布式 HDFS,其中包含使用 protobuf 3.0.0 编码的记录。然后,使用 Elephant-Bird/Hive 我可以将这些数据放入 Hive 表中进行查询。我遇到的问题是对数据进行分区。

这是我正在使用的表创建语句

CREATE EXTERNAL TABLE IF NOT EXISTS test_messages
  PARTITIONED BY (dt string)
    ROW FORMAT SERDE 
        "com.twitter.elephantbird.hive.serde.ProtobufDeserializer"
    WITH serdeproperties (
      "serialization.class"="path.to.my.java.class.ProtoClass")
  STORED AS SEQUENCEFILE;

表已创建,我在查询表时未收到任何运行时错误。

当我尝试如下加载数据时:

ALTER TABLE test_messages_20180116_20180116 ADD PARTITION (dt = '20171117') LOCATION '/test/20171117'

我收到“OK”声明。但是,当我查询表时:

select * from test_messages limit 1;

我收到以下错误:

Failed with exception java.io.IOException:java.lang.IllegalArgumentException: FieldDescriptor does not match message type.

我一直在阅读 Hive 表,发现分区列不需要是正在加载的数据的一部分。我尝试对日期进行分区的原因既是为了提高性能,更重要的是,因为“LOAD DATA ...”语句会在 HDFS 中的目录之间移动文件。

附:我已经证明我能够在不分区的情况下对 hive 表运行查询。

有什么想法吗?

【问题讨论】:

【参考方案1】:

我看到你已经创建了 EXTERNAL TABLE。所以你不能使用 hive 添加或删除分区。您需要使用 hdfs 或 MR 或 SPARK 创建一个文件夹。 EXTERNAL 表只能被 hive 读取,不能被 HDFS 管理。您可以检查 hdfs 位置“/test/dt=20171117”,您会看到该文件夹​​尚未创建。

我的建议是使用“hadoop fs -mkdir '/test/20171117'”创建文件夹(分区),然后尝试查询表。虽然它会给 0 行。但您可以将数据添加到该文件夹​​并从 Hive 中读取。

【讨论】:

【参考方案2】:

您需要为 EXTERNAL TABLE 指定 LOCATION

CREATE EXTERNAL TABLE 
... 
LOCATION '/test';

那么,数据实际上是一个序列文件吗?你所说的只是它是protobuf数据。我不确定大象鸟库是如何工作的,但您需要仔细检查一下。

然后,您的表位置需要看起来像 /test/dt=value 以便 Hive 读取它们。

在 HDFS 位置创建外部表后,必须运行 MSCK REPAIR TABLE table_name 以将分区添加到 Hive 元存储

【讨论】:

以上是关于无法对 HDFS 支持的配置单元表进行分区的主要内容,如果未能解决你的问题,请参考以下文章

无法将数据加载到配置单元表中

如何插入配置单元表,按从临时表读取的日期进行分区? [复制]

无法从 spark sql 插入配置单元分区表

为数据集创建了外部 Bigquery 配置单元分区表,但无法查看具有分区键的列

如何将按月分区的配置单元表中的数据加载到按周分区的配置单元表中

审计配置单元表