我一直在考虑使用apachekafka作为事件源配置中的事件存储。已发布的事件将与特定资源相关联,传递到与资源类型关联的主题,并按资源id分片到分区中。因此,例如,创建类型为folder且id为1的资源将生成foldercreate事件,该事件将传递到分区中的“folders”主题,该分区通过在主题中的总分区数上分片id为1给出。即使我不知道如何处理使日志不一致的并发事件。
最简单的场景是有两个并发操作,可以使彼此失效,例如一个更新文件夹,另一个销毁同一个文件夹。在这种情况下,该主题的分区可能最终包含无效的序列[folderdestroy,folderupdate]。这种情况通常是通过对事件进行版本控制来解决的,如本文所述,但是kafka不支持这种特性。
在这些情况下,如何确保Kafka日志本身的一致性?
1条答案
按热度按时间gupuwyp21#
我认为有可能使用Kafka的事件来源(在ddd的意义上),或'资源'。注意事项:
使用每个分区(或多个分区)的单个进程来管理每个分区的串行写入。如果您负担不起回滚,请确保在同一kafka连接上串行发送消息,并在向命令发送方报告成功之前使用ack=all。确保producer进程跟踪每个资源的当前成功事件偏移量/版本,以便在发送消息之前自己进行乐观检查。
由于即使写入实际成功,也可能返回写入失败,因此您需要重试写入并通过在每个事件中包括一个id来处理重复数据消除,或者通过重新读取流中的(最近的消息)来重新初始化生产者,以查看写入是否实际有效。
以原子方式编写多个事件—只需发布包含事件列表的复合事件。
按资源id查找。这可以通过在启动时读取分区中的所有事件(或特定跨资源快照中的所有事件)并将当前状态存储在ram或缓存在db中来实现。
https://issues.apache.org/jira/browse/kafka-2260 会以一种更简单的方式解出1,但似乎被搁置了。
Kafka溪流似乎为你提供了很多。例如,4是一个ktable,您可以让事件生成器在发送事件之前使用它来确定事件对于当前资源状态是否有效。