Avro和Kafka通过使用SchemaBuilder

时间:2019-01-15 09:41:36

标签: java apache-kafka avro

我从baeldung开始了本教程的学习。他们提到有两种创建模式的方法。

  • 通过编写json表示并添加maven插件来产生类
  • 通过使用SchemaBuilder,他们也提到这是一个更好的选择。

不幸的是,在git示例中,我仅看到json方式。

让我们说我有这个Avro模式:

{
  "type":"record",
  "name":"TestFile",
  "namespace":"com.example.kafka.data.ingestion.model",
  "fields":[
    {
      "name":"date",
      "type":"long"
    },
    {
      "name":"counter",
      "type":"int"
    },
    {
      "name":"mc",
      "type":"string"
    }
  ]
}

通过在我的pom文件中添加此插件:

<plugin>
   <groupId>org.apache.avro</groupId>
   <artifactId>avro-maven-plugin</artifactId>
   <version>1.8.0</version>
   <executions>
      <execution>
         <id>schemas</id>
         <phase>generate-sources</phase>
         <goals>
            <goal>schema</goal>
            <goal>protocol</goal>
            <goal>idl-protocol</goal>
         </goals>
         <configuration>
            <sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
            <outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
         </configuration>
      </execution>
   </executions>
</plugin>

并使用generate-sources构建一个TestFile.java到我说的目的地。 然后,要发送到kafka主题,我可以执行以下操作:

TestFile test = TestFile.newBuilder()
                                            .setDate(102928374747)
                                            .setCounter(2)
                                            .setMc("Some string")
                                            .build();
kafkaTemplate.send(topicName, test);

使用SchemaBuilder创建模式的等效条件是:

Schema testFileSchema = SchemaBuilder   .record("TestFile")
                                            .namespace("com.example.kafka.data.ingestion.model")
                                            .fields()
                                            .requiredLong("date")
                                            .requiredInt("counter")
                                            .requiredString("mc")
                                            .endRecord();

但是我现在如何生成POJO并将我的TestFile数据发送到我的kafka主题?

1 个答案:

答案 0 :(得分:1)

由于该架构是在运行时创建的,而不是预先编译的,因此您将无权访问TestFile对象。如果要保留该POJO,则需要一个public TestFile(GenericRecord avroRecord)

的构造函数

您将需要使用该GenericRecord对象创建一个Schema,就像从字符串或文件中对其进行解析一样。

例如

Schema schema = SchemaBuilder.record("TestFile")
            .namespace("com.example.kafka.data.ingestion.model")
            .fields()
            .requiredLong("date")
            .requiredInt("counter")
            .requiredString("mc")
            .endRecord();

GenericRecord entry1 = new GenericData.Record(schema);
entry1.put("date", 1L);
entry1.put("counter", 2);
entry1.put("mc", "3");

// producer.send(new ProducerRecord<>(topic, entry1);

完整的Kafka示例为available from Confluent

如果您输入的内容不包含必填字段,则会引发错误,并且不检查类型的值(我可以输入"counter", "2",它会发送一个字符串值(这似乎是(对我来说是个错误)。基本上,GenericRecord == HashMap<String, Object>具有重新设置字段/可空字段的额外好处。

您将需要配置一个Avro序列化程序,例如Confluent的序列化程序,该序列化程序需要运行其架构注册表或Cloudera shows之类的版本

否则,您需要将Avro对象转换为byte[](如链接中所示,只需使用ByteArraySerializer