java - 架构演变上的 Avro 反序列化错误
问题描述
我有 2 个模式:
schema1(旧架构):
{
"namespace": "com.org.package",
"type": "record",
"name": "EventModel",
"fields": [
{
"name":"name",
"type":"string"
},
{
"name":"id",
"type":"long"
}
]
}
我用一个布尔字段更新了架构:
schema2(新架构):
{
"namespace": "com.org.package",
"type": "record",
"name": "EventModel",
"fields": [
{
"name":"name",
"type":"string"
},
{
"name":"id",
"type":"long"
},
{
"name":"isActive",
"type":"boolean",
"default":false
}
]
}
kafka 主题包含属于旧模式(模式 1)的消息。更新消费者模式后,即使更新字段中存在默认值,消费者也无法反序列化较旧的模式消息。
根据 Avro 文档:
if the reader's record schema has a field that contains a default value, and writer's schema does not have a field with the same name, then the reader should use the default value from its field.
if the reader's record schema has a field with no default value, and writer's schema does not have a field with the same name, an error is signalled.
反序列化时出现以下错误:
java.io.EOFException: null
at org.apache.avro.io.BinaryDecoder.readBoolean(BinaryDecoder.java:140) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.io.ValidatingDecoder.readBoolean(ValidatingDecoder.java:77) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:194) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.specific.SpecificDatumReader.readField(SpecificDatumReader.java:136) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:237) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.specific.SpecificDatumReader.readRecord(SpecificDatumReader.java:123) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:170) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:151) ~[avro-1.9.1.jar!/:1.9.1]
at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144) ~[avro-1.9.1.jar!/:1.9.1]
当记录缺少字段时,为什么默认值不应用于消费者?非常感谢任何帮助。提前致谢!
解决方案
尝试将类型更改为boolean
andnull
而isActive
不是 just boolean
。就像是:
{
"name": "isActive",
"type": ["boolean", "null"],
"default": false
}
它将使模式向后兼容。
推荐阅读
- python - 如何在 Python 中使用 Matplotlib 弯曲文本?
- javascript - 在 JavaScript 中查找数组内具有重复名称的对象
- eclipse - 无法在 Eclipse 中运行项目。运行按钮消失。我可以看到在菜单中运行,但它不起作用
- c++ - 重命名 COM 类属性会破坏向后兼容性吗?
- python - 如何执行没有“.exe”扩展名的文件
- postgresql - postgresql中'For fetch only'的解决方案是什么?
- c# - 如何在 C# 中向 Switch-Cases 添加 Y/N?
- python - 如何绘制 Pandas Dataframe 中每一列的空值计数
- java - 应用程序因 StackOverflow 错误而崩溃
- c# - Azure 存储帐户使用托管标识和 C# 进行身份验证