这个问题是关于架构和kafka主题迁移的。
原来的问题:没有向后兼容性的架构演变。
https://docs.confluence.io/current/schema-registry/avro.html
我请求社区给我建议或分享文章,我可以从中获得启发,也许可以找到解决我的问题的方法。也许存在架构或流模式。没有必要给我特定于语言的解决方案;只是给我一个可以前进的方向...我的问题很大,对于后来想要的人来说可能会很有趣
- a) 更改消息格式并将消息生成到新主题中。
- b) 停止向一个主题生成消息并“立即”开始向另一个主题生成消息;换句话说,一旦有消息
v2
已生成,没有新消息附加到v1
.
Problem
我正在更改消息格式,该格式与以前的版本不兼容。为了不破坏现有的消费者,我决定向新主题生成消息。
上施法者的想法
我读过有关上施法者的文章。
https://docs.axoniq.io/reference-guide/operations-guide/product-considerations/versioning-events
正式任务
Let v1
and v2
成为话题。目前,我以以下格式生成消息format_v1
进入主题v1
。我想以以下格式生成消息format_v2
进入主题v2
。切换应该在我可以选择的某个时刻发生。
换句话说,在某个时刻,生产者的所有实例都停止向v1
,并开始发送消息到v2
;因此最后一条消息m1
in v1
在第一条消息之前产生m2
in v2
.
Details
我有一个想法,我可以生成针对该主题的消息v1
有一个已订阅的 kafka steam up-casterv1
并将转换后的消息推送到v2
。假设变压器 (当然就我而言)能够转换消息format_v1
into format_v2
没有错误。
正如上面关于 avro 模式演变的链接中所述,当我添加了一个向上转型者并将消息生成到v1
,我的所有消费者v1
改变成v2
.
现在,这是一个棘手的部分。我们有两个要求:
1.无生产停机时间。
2.保留消息顺序。
它的意思是:
1)我们不允许丢失消息;客户可以随时使用我们的系统,因此我们的系统应该随时产生消息。
2)我们正在运行生产者的多个实例。在某个时刻,可能(可能)有生产者生成以下格式的消息format_v1
进入主题v1
,以及一些产生格式消息的实例format_v2
进入主题v2
.
众所周知,kafka不保证不同分区和主题的消息排序。
我可以通过使用与 v1 相同的分区选择器将消息写入 v2 来解决分区问题。或者现在,我可以想象我们只使用一个分区v1
和一个分区v2
.
我的简化和尝试
1)我想象当我想要更改生产者以将消息生成到新主题时,我有一个向上投射器(kafka流组件),它能够将消息从v1
into v2
没有错误。这个 kafka 流组件是可扩展的。
2)我所有的消费者都已经切换到v2
话题。他们不断收到来自v2
。此时,我的生产者实例正在向主题生成消息v1
向上脚轮的工作做得很好。
3)为了简化问题,我们现在假设format_v1
and format_v2
没关系,它们是一样的。
4)假设我们有一个分区v1
和一个分区v2
.
现在我的问题是,如何立即切换给定时间点的所有生产者;所有实例都会将消息生成到主题 v2 中。
我的同事兼卡夫卡专家告诉我,只要停机就可以完成
如果您依赖分区中消息的顺序,则无法在不停机的情况下切换到新版本。为了最大限度地减少停机时间,我们可以执行以下操作。
Upcaster 组件必须将数据写入相同的分区,并且应尝试进行相同的偏移量。然而,这并不总是可能的,因为偏移量可能有间隙,因此必须保留旧偏移量和新偏移量之间的映射。没有所有记录,只有每个分区的最后一批记录。如果upcaster崩溃了,重新启动即可,生产者仍然不参与v2。
启动 v2 消费者。如果它以与 v1 相同的消费者组开始,则无需执行任何操作,如果它有新的消费者组,请根据新的偏移量更新 Kafka 中的偏移量。
现在生产者写入v1,upcaster转换数据,消费者从v2消费
时间到了。当upcaster的滞后接近0时,关闭v1生产者,等待upcaster转换其余记录,关闭upcaster,启动v2生产者,写入v2主题。
我想在数据库中手动操作(通过一些休息端点等)来更改标志;生产者在生成消息之前总是检查该标志。当旗帜说v2
or true
,生产者将开始将消息写入v2
。但是,如果在标志为 false 的时刻,生产者开始将消息生成到v1
,然后标志已更改,并且另一个生产者已将消息发送到v2
在前一个生产者完成生产之前v1
.