为新列使用不同的avro架构

时间:2016-11-01 08:20:26

标签: apache-kafka hdfs avro flume bigdata

我正在使用flume + kafka将日志数据接收到hdfs。我的接收器数据类型是Avro。在avro架构(.avsc)中,有80个字段作为列。

所以我创建了一个像这样的外部表

CREATE external TABLE pgar.tiz_biaws_fraud
PARTITIONED BY(partition_date INT)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.avro.AvroSerDe'
STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat'
LOCATION '/data/datapool/flume/biaws/fraud'
TBLPROPERTIES ('avro.schema.url'='hdfs://xxxx-ns/data/datapool/flume/biaws/fraud.avsc')

现在,我需要向avro架构添加25个列。在那种情况下,

如果我创建一个包含105列新架构的新表,我将为一个项目创建两个表。如果我在未来几天添加或删除一些列,我必须为此创建一个新表。我害怕有很多表使用不同的模式为同一个项目。

如果我将旧架构与当前表中的新架构交换,我将只有一个表用于一个项目,但由于架构冲突,我无法读取并获取旧数据。

在这种情况下使用avro架构的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

这确实具有挑战性。最好的方法是确保您所做的所有架构更改都与旧数据兼容 - 因此只删除具有默认值的列,并确保在要添加的列中提供默认值。这样,您可以安全地交换模式而不会发生冲突,并继续读取旧数据。 Avro对此非常聪明,它被称为“模式演化”(如果你想要谷歌更多)并允许读者和作者模式有点不同。

顺便说一下,我想提一下Kafka有一个原生的HDFS连接器(即没有Flume),它使用Confluent的模式注册表来自动处理这些类型的模式 - 你可以使用注册表检查模式是否兼容,如果它们是 - 只需使用新架构写入数据,Hive表将自动演变为匹配。

答案 1 :(得分:0)

我为avro架构添加了新列

{"name":"newColumn1", "type": "string", "default": ""},
{"name":"newColumn2", "type": "string", "default": ""},
{"name":"newColumn3", "type": "string", "default": ""},

当我使用default属性时,如果当前数据中不存在该列,则返回默认值,如果当前数据中存在该列,则返回预期的数据值。

要将空值设置为默认值,您需要

{ "name": "newColumn4", "type": [ "string", "null" ], "default": "null" },

{ "name": "newColumn5", "type": [ "null", "string" ]},

type属性中null的位置可以是第一位,也可以是默认属性的第二位。