我想使用apache nifi将一些通用数据生成kafka主题,并且我希望这些数据采用avro格式。 我为此做了什么:
{“ type”:“ record”,“ name”:“ my_schema”,“ namespace”: “ my_namespace”,“ doc”:“”,“ fields”:[ { “ name”:“键”, “ type”:“ int” }, { “ name”:“ value”, “类型”:[ “空值”, “ int” ] }, { “ name”:“ event_time”, “ type”:“ long” }]}
然后我尝试使用kafka流阅读它:
公共课程测试{ 私人最终静态Logger logger = Logger.getLogger(KafkaFilterUsingCacheAvro.class);
public static void main(String[] args) {
Properties properties = new Properties();
properties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "broker:9092");
properties.put(StreamsConfig.APPLICATION_ID_CONFIG, "app");
properties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
properties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, GenericAvroSerde.class);
properties.put(AbstractKafkaAvroSerDeConfig.SCHEMA_REGISTRY_URL_CONFIG, "registry:8081");
StreamsBuilder builder = new StreamsBuilder();
KStream<String, GenericRecord> source = builder.stream("topic");
source.foreach((k, v) -> logger.info(String.format("[%s]: %s", k, v.toString())));
Topology topology = builder.build();
KafkaStreams streams = new KafkaStreams(topology, properties);
streams.start();
}
}
GenericAvroSerde-https://github.com/JohnReedLOL/kafka-streams/blob/master/src/main/java/io/confluent/examples/streams/utils/GenericAvroSerde.java
结果我得到了错误:
由以下原因引起:org.apache.kafka.common.errors.SerializationException: 反序列化ID -1的Avro消息时出错,原因是: org.apache.kafka.common.errors.SerializationException:未知魔术 字节!
我还尝试在avroreader \ writer中显式设置avro模式,但这无济于事。另外,如果我尝试从主题中读取字节并将其转换为字符串表示形式,我将得到以下信息:
Objavro.schema {“ type”:“ record”,“ name”:“ my_schema”,“ namespace”:“ my_namespace”,“ doc”:“”,“ fields”:[{“ name”:“ key “,” type“:” int“},{” name“:” value“,” type“:[” null“,” int“]},{” name“:” event_time“,” type“:” long “}]}avro.codecsnappyÛ4ým[©q ÃàG0ê¸ä»/}½{Û4ým[©qÃààG0
我该如何解决?
答案 0 :(得分:3)
在PublishKafka处理器中,您的Avro编写器配置为“嵌入式Avro架构”的“架构写入策略”。这意味着写入Kafka的消息是标准的Avro消息,其中嵌入了完整的架构。
在用户端(Kafka流)上,它看起来像希望使用融合的模式注册表,在这种情况下,它不希望使用嵌入式Avro模式,而是希望使用特殊的字节序列指定模式ID,然后通过裸露的Avro消息。
假设您希望保持消费者的状态不变,那么在NiFi方面,您将需要将Avro编写器的“架构写入策略”更改为“融合架构注册表参考”。我认为这可能还需要您更改Avro阅读器,才能使用Confluent Schema Registry服务访问架构。
或者,也许有一种方法可以使Kafka Streams读取嵌入式模式,而不使用Confluent模式注册表,但是我以前没有使用过Kafka Streams,所以我不能说这是否可行。