将通用avro记录序列化为Array [Byte]将架构保留在对象中

时间:2018-08-01 13:32:58

标签: scala apache-kafka avro bijection

情况

我目前正在使用AVRO和模式存储库编写消费者/生产者。

从我收集的数据中,我选择的序列化此数据的方法是使用Confluent的avro序列化程序,或者使用Twitter的Bijection。

Bijection看起来最直接。

所以我想以以下格式ProducerRecord[String,Array[Byte]]生成日期,这归结为[一些字符串ID,序列化的GenericRecord]

(注意:我要使用通用记录,因为此代码库必须处理从Json / csv / ...解析的数千个模式)。

问题:

我序列化并使用AVRO的全部原因是,您不需要在数据本身中拥有架构(就像使用Json / XML / ...一样)。
但是,在检查主题中的数据时,我看到整个方案与数据一起包含在其中。我是在做根本上是错误的事情,是设计使然,还是应该使用融合的串行器?

代码:

  def jsonStringToAvro(jString: String, schema: Schema): GenericRecord = {
    val converter = new JsonAvroConverter
    val genericRecord = converter.convertToGenericDataRecord(jString.replaceAll("\\\\/","_").getBytes(), schema)

    genericRecord
  }
def serializeAsByteArray(avroRecord: GenericRecord): Array[Byte] = {
    //val genericRecordInjection = GenericAvroCodecs.toBinary(avroRecord.getSchema)
    val r: Array[Byte] = GenericAvroCodecs.toBinary(avroRecord.getSchema).apply(avroRecord)

    r
  }

//schema comes from a rest call to the schema repository
new ProducerRecord[String, Array[Byte]](topic, myStringKeyGoesHere, serializeAsByteArray(jsonStringToAvro(jsonObjectAsStringGoesHere, schema)))


        producer.send(producerRecord, new Callback {...})

1 个答案:

答案 0 :(得分:1)

如果您查看Confluent source code,则会发现与模式存储库进行交互的操作顺序为

  1. 从Avro记录中获取模式,并计算其ID。理想情况下,将模式发布到存储库中,否则对其进行哈希处理应为您提供一个ID。
  2. 分配ByteBuffer
  3. 将返回的ID写入缓冲区
  4. 将Avro对象值(不包括架构)作为字节写到缓冲区中
  5. 将该字节缓冲区发送到Kafka

当前,您的Bijection用法将在字节中包含模式,而不是将其替换为ID