Hive 3.1+不会反序列化来自Kafka 1.0+的Avro 1.8.3+消息

时间:2019-02-05 16:31:37

标签: hive apache-kafka hiveql avro confluent

假设我有一个通过Confluent的kafka流创建的主题,其中包含以io.confluent.kafka.streams.serdes.avro.SpecificAvroSerializer在avro中序列化的消息

然后我在Hive中创建一个外部kafka表

CREATE EXTERNAL TABLE k_table
(`id` string , `sequence` int) 
STORED BY 'org.apache.hadoop.hive.kafka.KafkaStorageHandler' 
TBLPROPERTIES 
( 
  "kafka.topic" = "sample-topic", 
  "kafka.bootstrap.servers"="kafka1:9092", 
  "kafka.serde.class"="org.apache.hadoop.hive.serde2.avro.AvroSerDe", 
  "avro.schema.url"="Sample.avsc"

);

当我运行查询时:

select * from k_table WHERE `__timestamp` >  1000 * to_unix_timestamp(CURRENT_TIMESTAMP - interval '2' DAYS)

我遇到了意外的IO错误:

INFO  : Executing command(queryId=root_20190205160129_4579b5ff-9a5c-496d-8d03-9a7ccc0f6d90): select * from k_tickets_prod2 WHERE `__timestamp` >  1000 * to_unix_timestamp(CURRENT_TIMESTAMP - interval '1' minute)
INFO  : Completed executing command(queryId=root_20190205160129_4579b5ff-9a5c-496d-8d03-9a7ccc0f6d90); Time taken: 0.002 seconds
INFO  : Concurrency mode is disabled, not creating a lock manager
Error: java.io.IOException: java.lang.ArrayIndexOutOfBoundsException: 55 (state=,code=0)

对于Confluent kafka消费者来说,一切都很好,我还尝试在TBLPROPERTIES中设置confluent kafka解串器,这似乎很有效果。

环境:

Hive 4.0 + Beeline 3.1.1 + Kafka 1.1 (Clients & Broker) + Confluent 4.1

1 个答案:

答案 0 :(得分:1)

问题在于Confluent生产者将具有自定义格式的avro消息序列化为<magic_byte 0x00><4 bytes of schema ID><regular avro bytes for object that conforms to schema>。因此,Hive kafka处理程序无法对cuz进行反序列化,因为它使用了基本的字节数组kafka反序列化器,并且消息开头的这5个字节是意外的。

我已经在配置单元中创建了一个bug以支持Confluent格式和Schema注册表,并且我已经创建了一个PR with quick fix,该属性在"avro.serde.magic.bytes"="true"属性为在TBLPROPERTIES中设置。

在此补丁之后,它就像魅力一样。