当我们谈论源事件时,我们有一个简单的双重写入体系结构,可以在其中写入数据库,然后将事件写入像Kafka这样的队列。其他下游系统可以读取这些事件并相应地采取措施/使用它。
但是当试图使数据库和事件同步时会出现问题,因为需要对这些事件进行排序才能使它们有意义。
为解决这些问题,人们鼓励使用数据库提交日志作为事件源,并且围绕它构建了一些工具,例如Airbnb的Spinal Tap,Redhat的Debezium,Oracle的Golden Gate等。它解决了一致性问题,有序保证的问题。和所有这些。
但是使用数据库提交日志作为事件源的问题是我们与数据库模式紧密结合。公开了微服务的数据库架构,并且数据库架构中的任何重大更改(如数据类型更改/列名更改)实际上都可能破坏下游系统。
那么使用DB CDC作为事件源是个好主意吗?
A talk on these problem and using debezium for event sourcing
答案 0 :(得分:1)
如果您使用的是事件来源:
则该耦合不应该存在。事件存储区是通用的,它并不关心Aggregates的内部状态。在最坏的情况下,您会与事件存储本身的内部结构结合在一起,但这并不特定于特定的微服务。
如果您不使用事件来源:
在这种情况下,聚合的内部结构与CDC组件之间存在耦合(捕获数据更改并将事件发布到消息队列或类似队列)。为了限制这种耦合对微服务本身的影响,CDC组件应该是其中的一部分。这样,当微服务中的聚合的内部结构发生变化时,CDC组件也会发生变化,外界不会注意到。两项更改将同时部署。
答案 1 :(得分:1)
扩展康斯坦丁的答案:
TLDR;
交易日志尾部/挖掘对象应该对其他人隐藏。
严格来说,它不是事件流,因为您不应直接从其他服务访问它。通常在将遗留系统逐渐过渡到基于微服务的系统时使用。流程可能如下所示:
更长的故事:
服务B看不到您的事件源自数据库,也没有直接访问数据库。提交数据应投影到事件中。如果更改数据库,则仅应修改投影规则以将新模式中的提交映射到“旧”事件格式,因此不得更改使用者。 (我不熟悉Debezium,或者它是否可以完成此投影)。
您的事件在发布事件和进行事务时应该是幂等的 从原子上讲,这是一个分布式方案中的问题,并且工具将保证至少一次具有精确的一次处理语义的交付,而完全一次的部分则很少。这是由于事件起源(事务日志)与其他服务将要访问的流不同,即它是分布式的。这仍然是生产者部分,Kafka->消费者渠道也存在相同的问题,但原因不同。另外,Kafka will not behave like an event store也是如此,因此您获得的是一个消息队列。
如果可能的话,我建议改用专用的事件存储,例如Greg Young的https://eventstore.org/。通过将事件存储和消息代理集成到单个解决方案中,可以解决此问题。通过将事件(以JSON形式)存储到流中,您也可以“发布”该事件,因为消费者已订阅该流。如果要进一步分离服务,则可以编写将事件从一个流映射到另一流的投影。您的事件消耗也应该与此有关,但是您将获得一个由聚合划分的事件存储,并且读取起来非常快。
如果您也想将数据存储在SQL DB中,然后侦听这些事件并根据它们插入/更新表,只是不要将SQL DB用作事件存储,因为很难实现它正确(防故障)。
对于排序部分:将从一个流中读取事件进行排序。聚合多个事件流的投影只能保证源自同一流的事件之间的顺序。通常这绰绰有余。 (顺便说一句,如有必要,您可以根据消费者方的某些字段对消息进行重新排序。)
答案 2 :(得分:1)
使用DB CDC作为事件源是一个好主意吗?
“这是个好主意吗?”这个问题将取决于您的情况,需要做出的各种权衡取舍的成本和收益。
也就是说,这与我所学的事件采购的传统并不相符。
事件来源-我们的记录簿是状态变化的分类帐-已经存在了很长时间。毕竟,当我们谈论“分类帐”时,实际上是在暗示几个世纪以前写的跟踪贸易的文件。
但是,有关软件中事件源 的很多讨论都受到领域驱动设计的严重影响; DDD提倡者(除其他外)使您的代码概念与要建模的领域中的概念保持一致。
这就是问题所在:除非您处于极端的情况下,否则数据库可能是要定制/配置以满足您需求的某些通用应用程序。变更数据捕获将受到使用通用机制实现的事实的限制。因此,产生的事件将看起来像通用补丁文件(这是之前和之后的区别)。
但是,如果我们尝试使事件与领域概念保持一致(即,对持久状态 mean 的更改),那么补丁文档将朝错误的方向迈进。
例如,域外可能具有多个“事件”,这些“事件”对模型中相同或非常相似的字段集进行更改。试图通过对差异进行逆向工程来重新发现改变的动机是一个愚蠢的问题。尤其是当我们已经进行过相同类型的问题学习user interface design时。
在某些领域,通用更改就足够了。在某些情况下,目前进行通用更改已经足够了。马匹。
但这并不是“事件源”社区正在谈论的那种实现。