如何使用kafka模式管理和Avro进行重大更改

时间:2019-06-03 17:43:48

标签: java apache-kafka avro

使用avro的kafka模式管理为我们提供了向后兼容的灵活性,但是我们如何处理方案中的重大更改?

假设生产者A将消息M发布到消费者C

假设消息M的方案发生重大变化(例如,名称字段现在分为first_name和last_name),并且我们有了新的方案M-New

现在,我们正在部署生产者A-New和消费者C-New

问题在于,在我们的部署过程完成之前,我们可以让Producer A-new发布消息M-new,而消费者C(旧的)将收到M-new,因此我们可能会丢失消息。

因此,唯一的方法是同步新生产者和消费者的部署,这会增加大量开销

关于如何处理的任何建议?

2 个答案:

答案 0 :(得分:0)

一种简单的方法是延长主题的保留期限。然后,您只需为重大更改创建一个新主题。所有消费者都可以在保留期内转移到新主题,而不会丢失任何消息。

答案 1 :(得分:0)

  

例如,名称字段现在分为名字和姓氏

“向后兼容”模式的Avro定义不允许您添加以下新字段,而不需要1)保留旧名称字段2)将默认值添加到新字段-https://docs.confluent.io/current/schema-registry/avro.html

如果您的使用者首先升级其架构,他们将看到旧名称字段,该字段继续由旧的生产者发送,并解释新字段的默认值,直到生产者升级并开始发送新字段

如果生产者首先升级,那么消费者将永远看不到新字段,因此生产者仍应发出name字段,或选择发送一些垃圾值以开始有意破坏消费者(例如,使该字段可为空开头,但从不实际发送空值,然后开始发送空值,而消费者认为该值不能为空)

无论哪种情况,我都觉得您的记录处理逻辑必须检测哪些字段可用,而不是null或它们的默认值。

但是,将其与JSON或任何纯字符串(例如CSV)进行比较,您不能保证应该存在哪些字段,它们是否可以为空或它们是什么类型(是日期是字符串还是长字符串?),因此您不能保证客户会在内部将消息映射到哪些对象进行处理……与兼容性规则相比,我发现Avro的更大优势

我个人认为,当您的Kafka用户之间几乎没有通信时,在注册表上强制FULL_TRANSITIVE兼容性最有效