kafka在有状态处理中验证消息

xzabzqsa  于 2021-06-07  发布在  Kafka
关注(0)|答案(1)|浏览(764)

我有一个应用程序,多个用户可以发送rest操作来修改共享对象的状态。修改对象时,将发生多个操作(db、audit、logging…)。
并不是所有的操作都是有效的,例如不能在删除对象后对其进行修改。
使用Kafka,我想到了以下架构:
rest操作在kafka主题中排队。
对同一对象的操作将被转移到同一分区。因此,所有对象的操作都将按顺序由使用者处理
使用者正在侦听分区并使用内存中的数据库验证操作
如果操作有效,则发送到“有效操作主题”,否则发送到“无效操作主题”
其他使用者(db、log、audit)正在侦听“有效操作主题”
我不太清楚第三点。我不喜欢保持我所有物体的状态(我有几十亿个对象,即使一个对象的大小可以是10mb,我需要存储来验证它的状态只有几KB……)
然而,这是一种常见的模式吗?否则如何验证某些操作的有效性?
另外,您会使用什么作为内存中的数据库?当然,它必须具有高可用性、容错性和支持事务(读写)。

7xzttuei

7xzttuei1#

我相信这是一个非常有效的模式,本质上是一个事件源cqrs模式的变体。
例如,lagom以非常相似的方式实现了它们的cqrs持久性(尽管基于完全不同的工具集)
有几点:
关于顺序操作的需要,您是对的:因为您的所有状态突变都需要基于前一个突变的结果,所以它们的执行必须有一个很强的顺序。这种情况经常发生,因此我们希望能够尽可能水平地缩放这些操作,以便这些序列操作中的每一个都与许多其他序列并行发生。在你的例子中,每个共享对象有一个这样的序列。
依靠kafka按键分区是实现这一点的好方法(假设您不设置 max.in.flight.requests.per.connection 高于默认值1)。在这里,lagom也有一个类似的方法,它的持久实体是分布式的,并且是单线程的。我并不是说拉格姆更好,我只是安慰你,事实上,其他人都在使用这种方法:)
模式的一个关键方面是将命令转换为事件:在这个术语中,命令被视为影响状态的请求,并且可能会由于各种原因而被拒绝。事件是对过去发生的状态更新的描述,从接受它的人的Angular 来看,它是无可辩驳的:事件总是说真话。您所描述的进程将是位于两者之间边界的控制器:它负责将命令转换为事件。
在这种意义上,您提到的“有效操作主题”将是流程状态更新的事件源描述。因为它都是由Kafka支持的,所以它是任意可分割的,因此是可伸缩的,这太棒了:)
不要担心你所有物体的状态的大小,它一定在某个地方。由于您有一个将命令转换为事件的控制器,所以这个控制器成为与该对象相关的真相的主要来源,而这个控制器负责存储它:这个控制器处理事件的主要存储,因此您必须为它预留空间。您可以使用kafka streams的键值存储:这些键值存储是每个处理示例的本地存储,但是如果将它们持久化,则它们在处理比可用ram大得多的数据方面没有问题。由于rocksdb的存在,幕后数据会溢出到磁盘上,更重要的是幕后数据都是来自kafka主题的事件,因此状态存储会被复制,并在必要时在另一台机器上透明地重新创建
我希望这能帮助你完成你的设计:)

相关问题