Apache kafka 为什么kafka avro console producer不遵守字段的默认值?

Apache kafka 为什么kafka avro console producer不遵守字段的默认值?,apache-kafka,avro,kafka-producer-api,confluent-schema-registry,Apache Kafka,Avro,Kafka Producer Api,Confluent Schema Registry,虽然为字段定义了默认值,但kafka avro console producer完全忽略它: $ kafka-avro-console-producer --broker-list localhost:9092 --topic test-avro \ --property schema.registry.url=http://localhost:8081 --property \ value.schema='{"type":"record","name":"myrecord1","fields"

虽然为字段定义了默认值,但kafka avro console producer完全忽略它:

$ kafka-avro-console-producer --broker-list localhost:9092 --topic test-avro \
--property schema.registry.url=http://localhost:8081 --property \
value.schema='{"type":"record","name":"myrecord1","fields": \
[{"name":"f1","type":"string"},{"name": "f2", "type": "int", "default": 0}]}'

{"f1": "value1"}

org.apache.kafka.common.errors.SerializationException: Error 
deserializing json {"f1": "value1"} to Avro of schema 
{"type":"record","name":"myrecord1","fields": 
[{"name":"f1","type":"string"},{"name":"f2","type":"int","default":0}]}
Caused by: org.apache.avro.AvroTypeException: Expected int. Got END_OBJECT
    at org.apache.avro.io.JsonDecoder.error(JsonDecoder.java:698)
    at org.apache.avro.io.JsonDecoder.readInt(JsonDecoder.java:172)
    at org.apache.avro.io.ValidatingDecoder.readInt(ValidatingDecoder.java:83)
    at org.apache.avro.generic.GenericDatumReader.readInt(GenericDatumReader.java:511)
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:182)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152)
    at org.apache.avro.generic.GenericDatumReader.readField(GenericDatumReader.java:240)
    at org.apache.avro.generic.GenericDatumReader.readRecord(GenericDatumReader.java:230)
    at org.apache.avro.generic.GenericDatumReader.readWithoutConversion(GenericDatumReader.java:174)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:152)
    at org.apache.avro.generic.GenericDatumReader.read(GenericDatumReader.java:144)
    at io.confluent.kafka.formatter.AvroMessageReader.jsonToAvro(AvroMessageReader.java:213)
    at io.confluent.kafka.formatter.AvroMessageReader.readMessage(AvroMessageReader.java:180)
    at kafka.tools.ConsoleProducer$.main(ConsoleProducer.scala:54)
    at kafka.tools.ConsoleProducer.main(ConsoleProducer.scala)

那么如何使用它来接受默认值呢?顶级配置设置为向后兼容性级别检查,尽管我认为这与问题无关。此模式为版本2,版本1仅定义了f1字段,但正如我所说的,我认为这无关紧要。

错误表明消息与您定义的Avro模式不兼容。据我所知,您希望为字段f2允许空值。为此,您需要更改value.schema以记录类型的定义:

但您仍然需要使用空值定义f2键。以下内容可以帮您解决问题:

kafka-avro-console-producer --broker-list localhost:9092 --topic test-avro \ 
    --property schema.registry.url=http://localhost:8081 \ 
    --property value.schema='{"type":"record","name":"myrecord1","fields": [{"name":"f1","type":"string"},{"name": "f2", "type": ["null", "int"], "default": 0}]}'

{"f1":"value1","f2":null} 
您可以使用kafka avro console consumer确认这一点:


该错误表示消息与您定义的Avro架构不兼容。据我所知,您希望为字段f2允许空值。为此,您需要更改value.schema以记录类型的定义:

但您仍然需要使用空值定义f2键。以下内容可以帮您解决问题:

kafka-avro-console-producer --broker-list localhost:9092 --topic test-avro \ 
    --property schema.registry.url=http://localhost:8081 \ 
    --property value.schema='{"type":"record","name":"myrecord1","fields": [{"name":"f1","type":"string"},{"name": "f2", "type": ["null", "int"], "default": 0}]}'

{"f1":"value1","f2":null} 
您可以使用kafka avro console consumer确认这一点:

默认值:此字段的默认值,在读取缺少此字段的实例时使用

因此,生产商仍然需要供应该油田

我不确定在使用Avro console producer时是否可以完全排除字段,因为即使您将字段设置为Giorgos显示的可空字段,仍然需要显式设置它

默认值:此字段的默认值,在读取缺少此字段的实例时使用

因此,生产商仍然需要供应该油田


我不确定在使用Avro console producer时是否可以完全排除字段,因为即使您将字段设置为Giorgos显示的可空字段,仍然需要显式设置它

好的,默认值仅适用于读卡器/消费者。该字段仍然需要由作者/制作人定义。我已经投票认为这是一个有用的评论,如果你将其推广为答案,我将接受它作为解决问题的答案,并且是最有用的。@hdjur_jcv我相信我的答案解释了如何做cricket_007所描述的事情。嗨,Giorgos Myriathous,我认为你的答案也很有用,我为此感谢你,但我认为cricket_007的答案是正确的,因为它揭示了我的误解。从您的示例可以看出,在生产者端启用空输入值并不意味着在消费者端使用默认零值,这应该是我的唯一目标。好的,默认值仅适用于读者/消费者。该字段仍然需要由作者/制作人定义。我已经投票认为这是一个有用的评论,如果你将其推广为答案,我将接受它作为解决问题的答案,并且是最有用的。@hdjur_jcv我相信我的答案解释了如何做cricket_007所描述的事情。嗨,Giorgos Myriathous,我认为你的答案也很有用,我为此感谢你,但我认为cricket_007的答案是正确的,因为它揭示了我的误解。在生产者端启用空输入值并不意味着在消费者端使用默认的零值,这应该是我的唯一目标,从您的示例可以看出。
kafka-avro-console-consumer --bootstrap-server localhost:9092 --topic test-avro --from-beginning
{"f1":"value1","f2":null}
^CProcessed a total of 1 messages