事件源意味着我们许多人在设计和开发web应用程序的方式上发生了180度的转变,有很多优点,但也有很多挑战。
apache kafka是一个非常棒的平台,通过它的apache kafka streams api被宣传为一个工具,允许我们通过它的许多特性(解耦、容错、可伸缩性……)来实现这个paradimg:https://www.confluent.io/blog/event-sourcing-cqrs-stream-processing-apache-kafka-whats-connection/
另一方面,有些文章不鼓励我们将其用于活动采购:https://medium.com/serialized-io/apache-kafka-is-not-for-event-sourcing-81735c3cf5c
以下是我对Kafka作为活动采购平台的适用性提出的问题:
上面的文章来自杰斯珀·哈马尔布äck(他为serialized.io工作,后者是一个事件源平台)。我想回答一下他提出的主要问题:
正在加载当前状态。在我看来,对于日志压缩和状态存储,这不是问题。我说得对吗?
一致写入。
当将某些功能移到Kafka流中时,我不确定它们是否适合自然:
身份验证和安全性:假设您的客户存储在由客户主题生成的状态存储中。我们应该把他们的密码保存在主题/存储中吗?听起来不够安全,是吗?那么,我们应该如何管理这方面的客户在状态存储和他们的密码在其他地方?有什么好的建议吗?
查询:交互式查询是一个很好的工具,可以生成数据的可查询视图(按键)。按id获取实体是可以的,但是复杂的查询(连接)呢?我们需要为每个查询生成状态存储吗?例如,一个商店按id为客户提供服务,另一个商店按州为客户提供服务,另一个商店为去年购买产品的客户提供服务。。。听起来不太好管理。另一点是缺少分页:在查询状态存储时,我们如何处理大型数据集?还有一点,我们不能再进行动态查询(比如jpa criteriaapi)。这可能导致cqrs?复杂性不断增长。。。
数据增长:对于数据库,我们习惯于每个表有成千上万的行。kafka streams应用程序保留一个本地状态存储,它将随着时间的推移不断增长。那有多大?如何保存本地存储(本地磁盘/ram)?如果是磁盘,我们应该为应用程序提供足够的空间,如果是ram,我们应该提供足够的内存。
1条答案
按热度按时间x6h2sr281#
加载当前状态:博客中描述的机制,关于为单个实体临时重新React当前状态,对于Kafka来说确实是昂贵的。然而,Kafka流遵循的哲学,以保持目前的状态为所有对象在一个特定的位置
KTable
(分布/分片)。因此,它不需要这样做——当然,它需要一定的内存开销。基于不同事件的Kafka流并行化。因此,单个事件(处理、状态更新)的所有交互都由单个线程执行。因此,我不明白为什么会有不一致的写入。
我不确定具体要求是什么。在当前的实现中,kafka streams不提供任何特定于存储的身份验证或安全特性。不过,为了安全起见,可以做以下几件事:(a)加密本地磁盘:这可能是保护数据最简单的方法(2) 在将消息放入存储之前,对业务逻辑中的消息进行加密。
交互式查询提供了有限的支持,原因有很多(不想详述),而且它的设计目标从来都不是支持复杂的查询。其思想是通过简单的查找来快速计算结果。正如您所指出的,如果您有很多不同的查询,那么这种方法的可伸缩性(成本密集型)不是很高。为了解决这个问题,将数据加载到数据库中,并让数据库执行它的构建任务是有意义的。kafka streams本身并不是这种atm的正确工具——但是,没有理由不将两者结合起来。
默认情况下,kafka streams使用rocksdb来保持本地状态(您也可以切换到内存存储)。因此,可以写入磁盘并使用非常大的状态。当然,您需要相应地提供示例(参见:https://docs.confluent.io/current/streams/sizing.html). 除此之外,Kafka流水平伸缩,是完全有弹性的。因此,您可以在任何时间点添加新示例,如果您有较大的磁盘和足够的示例,就可以保存terra字节的状态。注意,输入主题分区的数量限制了您可以使用的示例的数量(在内部,kafka streams是一个使用者组,您的示例不能多于分区)。如果这是一个问题,建议首先过度划分输入主题。