Kafka真的不适用于Event Sourcing

百家 作者:聊聊架构 2018-09-09 05:15:41
作者 | Jesper Hammarbäck
编辑 | 无明

首先,我先说 Apache Kafka 是一款很酷的产品,但如果你想用它来实现事件溯源,请先慎重考虑一下。

Kafka 是一个在生产者和消费者之间传递消息的绝佳工具,主题持久性特性可以让你永久地存储消息。因此,如果你的消息是事件类型,就可以将 Kafka 作为事件存储或事件日志,但它并不适合用作事件溯源。

下面是我的具体分析,你看看是否有道理,也欢迎你在留言区和我一起讨论交流。

加载当前状态

当服务收到一个要求事件溯源实体做出状态变更的命令时,我们首先需要重新创建这个对象的当前状态。我们从事件存储中加载这个实体之前所有的事件,将它们重新应用于这个对象上,然后得到对象的当前状态。

在 Kafka 中加载特定实体的事件并不容易。主题通常按照“订单”、“支付”或“通知”等实体类型进行分区,因此我们必须检查“订单”的所有事件,并根据 ID 来过滤它们,最后得到单个“订单”实体。虽然这样做是可行的,但并不实用。

一种替代方案是为每个实体创建一个主题,但如果这样,我们就会拥有数以千计的主题,而且最重要的是,下游的订阅服务需要自动发现为每个新实体创建的主题。所以,这样也不太实际。

写入一致性

在重新创建好实体的状态后,就可以执行请求命令所要求的业务逻辑了。如果业务逻辑执行失败,就会向客户端返回错误,如果执行成功,就会发出新的事件。在这种情况下,我们必须能够将新事件保存到事件存储中,同时要保证在此期间没有其他与这个实体相关的事件被写入,否则可能会破坏领域对象的一致性。

乐观并发控制

保证写入一致性的一种方法是利用事件存储的乐观并发控制(OCC)。事件存储一般会为用户提供 OCC 支持,即“只有当实体的版本仍为 x 时才保存这个事件”。但 Kafka 不支持这一功能,专家们的建议是通过增加一个“数据库”来提供一致性保存点。虽然在某些情况下这个建议可能是一个可行的解决方案,但从长远来看,选择更适合特定问题的工具可能更明智。

单个写入线程

另一种保证一致性的方法是确保写入是串行化的,即使用单个写入线程原则,也就是说,我们要确保所有关于某个实体的写入都发生在单个线程上。我们可以让生产者成为自己事件的消费者,并让自己阻塞,直到事件被提交并能够在 Kafka 的另一端看到这个事件,但这样的设计会对性能产生严重影响。

真的完全不能用吗?

那么,Kafka 在事件溯源架构中是否尚存一席之地?也许吧。它可能可以作为事件存储的一个很好的补充,将其作为将事件传输到下游查询服务或读取模型的方式。

不管怎样,在为系统添加大量复杂的基础设施时,我们应该十分小心——它们都需要我们为之付出相应的成本,因此请确保它们足以用来解决你手头的问题!

英文原文:https://medium.com/serialized-io/apache-kafka-is-not-for-event-sourcing-81735c3cf5c


《推荐系统 36 式》开启超级拼团!

如何零基础搭建一个推荐系统?资深算法专家刑无刀,用 39 篇文章手把手带你解决推荐系统起步阶段 80% 的问题,分享给你大厂的推荐算法与实战案例。原价¥68,超级拼团只要¥49,赶紧上车!

关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接