Apache kafka 对新列使用不同的avro模式

Apache kafka 对新列使用不同的avro模式,apache-kafka,hdfs,avro,flume,Apache Kafka,Hdfs,Avro,Flume,我正在使用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 '

我正在使用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模式的最佳方式是什么?

这确实是一个挑战。最好的方法是确保您所做的所有架构更改都与旧数据兼容,因此只删除具有默认值的列,并确保在要添加的列中提供默认值。通过这种方式,您可以安全地交换模式而不发生冲突,并继续读取旧数据。Avro在这方面非常聪明,它被称为“模式进化”(如果你想在谷歌上搜索更多的话),并且允许读写器模式有点不同


顺便说一句,我想提到Kafka有一个本地HDFS连接器(即没有Flume),它使用Confluent的模式注册表自动处理这些类型的模式更改-您可以使用注册表检查模式是否兼容,如果是,只需使用新模式写入数据,配置单元表就会自动演变为匹配。

我向avro模式添加了新列,就像这样

{"name":"newColumn1", "type": "string", "default": ""},
{"name":"newColumn2", "type": "string", "default": ""},
{"name":"newColumn3", "type": "string", "default": ""},
使用
default
属性时,如果当前数据中不存在该列,则返回默认值;如果当前数据中确实存在该列,则返回预期的数据值

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

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


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

如何将null添加为默认值?这
{“name”:“newColumn5”,“type”:[“null”,“string”]}
是否也向后兼容?我一直在谷歌上搜索,所有人都说必须有
default
字段才能使其向后兼容。是的,它可以工作。若将“string”作为第一个参数,将“null”作为第二个参数,那个么需要使用默认关键字进行向后兼容。但若在类型属性中将第一个参数设置为“null”,则不需要默认声明@勇气
{ "name": "newColumn5", "type": [ "null", "string" ]},