Apache kafka 在Kafka上并发写入事件源
我一直在考虑在事件源配置中使用ApacheKafka作为事件存储。发布的事件将与特定资源关联,传递到与资源类型关联的主题,并按资源id分成分区。因此,例如,创建Folder类型和id为1的资源将生成FolderCreate事件,该事件将传递到“folders”分区中的主题,通过在主题中的分区总数上分片id 1。即使我不知道如何处理导致日志不一致的并发事件 最简单的场景是有两个可以使彼此失效的并发操作,例如一个更新文件夹,另一个销毁同一文件夹。在这种情况下,该主题的分区可能最终包含无效序列[FolderDestroy,FolderUpdate]。这种情况通常通过对事件进行版本控制来解决,但卡夫卡不支持这种功能Apache kafka 在Kafka上并发写入事件源,apache-kafka,cqrs,event-sourcing,Apache Kafka,Cqrs,Event Sourcing,我一直在考虑在事件源配置中使用ApacheKafka作为事件存储。发布的事件将与特定资源关联,传递到与资源类型关联的主题,并按资源id分成分区。因此,例如,创建Folder类型和id为1的资源将生成FolderCreate事件,该事件将传递到“folders”分区中的主题,通过在主题中的分区总数上分片id 1。即使我不知道如何处理导致日志不一致的并发事件 最简单的场景是有两个可以使彼此失效的并发操作,例如一个更新文件夹,另一个销毁同一文件夹。在这种情况下,该主题的分区可能最终包含无效序列[Fol
在这些情况下,如何确保Kafka日志本身的一致性?我认为使用Kafka进行聚合事件源(DDD意义上的)或“资源”是可能的。一些注意事项:
卡夫卡溪流似乎为您提供了很多这方面的信息。例如,4是一个KTable,您可以让事件生成器在发送事件之前使用它来确定事件对于当前资源状态是否有效。您读过这个吗?如果每个分区只有一个进程,则不需要等待ACK—所有的处理都可以在该进程内序列化,而且就顺序/一致性而言,某些消息是否仍然在线并不重要(保证写入是一个单独的问题,可能不应同时混入解释)但是,如果资源1、事件写入A失败,但您在不等待A的确认的情况下写入事件B,而B写入ok呢?那么B在流中没有A,打破了不变量。或者A以某种方式延迟,并在B之后进入流。或者这是不可能的,因为两者都将使用相同的TCP连接?无论如何,如果可以的话,这将简化一些事情是这样的。我认为不可能将事件A和B从单个程序发送到单个kafka频道,然后在那里只发送B。它将是nothing、A only或A和B。生产者连接是具有重新连接的无损TCP流。当然,如果你故意搞砸了你的kafka代理(将消息删除时间设置为几秒钟,在处理过程中重新启动,清理内容等)一切都是可能的,但在正常操作中(即使有错误),事件不应该从生产者流的中间丢失。恐怕这是可能的,我们已经看到这种情况发生。生产者发送A,代理拒绝它,因为重新平衡刚刚发生,它不再是该分区的领导者。生产者发现新的领导者并发送B。B已存储,但A未存储。如果您喜欢thr,请仅使用acks=0应该考虑一致性,并愿意为(相对而言)消息丢失付出代价正常操作。对于#2,我强烈建议不要在再次发布之前尝试读取流的内容,以确定某个记录之前是否已发布,以避免重复。这会使制作人的实现大大复杂化。卡夫卡背后的一般设计理念至少是一次交付表示消费者生态系统中的幂等行为。您的消费者应该已经能够处理重复事件。