Kafka真的不适用于Event Sourcing

2018 年 9 月 9 日 聊聊架构
作者 | 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,赶紧上车!

登录查看更多
2

相关内容

Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消费。
【干货书】现代数据平台架构,636页pdf
专知会员服务
250+阅读 · 2020年6月15日
干净的数据:数据清洗入门与实践,204页pdf
专知会员服务
160+阅读 · 2020年5月14日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【SIGMOD2020-腾讯】Web规模本体可扩展构建
专知会员服务
29+阅读 · 2020年4月12日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
65+阅读 · 2020年3月9日
【书籍推荐】简洁的Python编程(Clean Python),附274页pdf
专知会员服务
173+阅读 · 2020年1月1日
在K8S上运行Kafka合适吗?会遇到哪些陷阱?
DBAplus社群
9+阅读 · 2019年9月4日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
亿级订单数据的访问与存储,怎么实现与优化?
码农翻身
16+阅读 · 2019年4月17日
Kong 1.1 带来声明式配置与无数据库部署模式
开源中国
8+阅读 · 2019年3月28日
I2P - 适用于黑客的Android应用程序
黑白之道
28+阅读 · 2019年3月6日
逆向 | C++ 加壳程序的编写思路
计算机与网络安全
9+阅读 · 2019年1月1日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
消息队列技术点梳理(思维导图版)
架构文摘
3+阅读 · 2018年4月3日
Rapid Customization for Event Extraction
Arxiv
7+阅读 · 2018年9月20日
Arxiv
25+阅读 · 2018年1月24日
Arxiv
5+阅读 · 2015年9月14日
VIP会员
相关资讯
在K8S上运行Kafka合适吗?会遇到哪些陷阱?
DBAplus社群
9+阅读 · 2019年9月4日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
用Now轻松部署无服务器Node应用程序
前端之巅
16+阅读 · 2019年6月19日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
亿级订单数据的访问与存储,怎么实现与优化?
码农翻身
16+阅读 · 2019年4月17日
Kong 1.1 带来声明式配置与无数据库部署模式
开源中国
8+阅读 · 2019年3月28日
I2P - 适用于黑客的Android应用程序
黑白之道
28+阅读 · 2019年3月6日
逆向 | C++ 加壳程序的编写思路
计算机与网络安全
9+阅读 · 2019年1月1日
Python3.7中一种懒加载的方式
Python程序员
3+阅读 · 2018年4月27日
消息队列技术点梳理(思维导图版)
架构文摘
3+阅读 · 2018年4月3日
Top
微信扫码咨询专知VIP会员