无法对HDFS支持的hive表进行分区

时间:2018-01-23 21:10:44

标签: hadoop hive elephantbird

也许这是一个简单的问题但是,我很难解决这个问题。这时,我有一个伪分布式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中的目录之间移动文件。

P.S。我已经证明我可以在没有分区的情况下对hive表运行查询。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我看到你创建了EXTERNAL TABLE。因此,您无法使用配置单元添加或删除分区。您需要使用hdfs或MR或SPARK创建一个文件夹。 EXTERNAL表只能由配置单元读取,但不能由HDFS管理。您可以检查hdfs位置'/ test / dt = 20171117',您将看到该文件夹​​尚未创建。

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

答案 1 :(得分:0)

您需要为EXTERNAL TABLE指定LOCATION

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

那么,数据实际上是一个序列文件吗?你所说的只是它的protobuf数据。我不确定elephantbird图书馆是如何运作的,但是你想要仔细检查一下。

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

在HDFS位置上创建外部表后,必须运行MSCK REPAIR TABLE table_name才能将分区添加到Hive Metastore