gpt4 book ai didi

cqrs - 为什么事件存储应该在写端?

转载 作者:行者123 更新时间:2023-12-03 22:17:25 24 4
gpt4 key购买 nike

事件采购被认为是许多事情的奖励,例如。事件历史记录/审计跟踪、完整且一致的 View 重新生成等。听起来很棒。我是粉丝。但这些是读取端的实现细节,您可以通过将事件存储完全移动到读取端作为另一个订阅者来完成相同的操作。为什么不呢?

这里有一些想法:

  • View /非规范化器本身并不关心事件存储。他们只是处理来自域的事件。
  • 将事件存储移动到读取端仍然会为您提供事件历史记录/审计
  • 您仍然可以从事件存储中重新生成 View 。除了现在它不必是写入模型泄漏。给他读模范公民!

  • 这似乎是将其保留在写入端的一个技术论据。这是格雷格·杨(Greg Young)的 http://codebetter.com/gregyoung/2010/02/20/why-use-event-sourcing/ :

    There are however some issues that exist with using something that is storing a snapshot of current state. The largest issue revolves around the fact that you have introduced two models to your data. You have an event model and a model representing current state.



    我觉得有趣的是术语“快照”,它最近也成为事件溯源中的一个显着术语。在写入端引入事件存储会增加加载聚合的一些开销。您可以争论多少开销,但这显然是一个感知或预期的问题,因为现在有从快照加载聚合和自快照以来的所有事件的概念。所以现在我们又有了……两个模型。不仅如此,我看到的快照建议旨在作为基础设施泄漏来实现,后台进程会遍历整个数据存储以保持性能。

    在拍摄快照之后,快照之前的事件从写入的角度来看 100% 无用,除了……重建读取端!这似乎是错误的。

    另一个与性能相关的话题:文件存储。有时我们需要将大型二进制文件附加到实体。从概念上讲,有时这些与实体相关联,但有时它们是实体。将这些放在事件存储中意味着您必须在每次加载实体时物理加载该数据。这已经够糟糕的了,但想象一下其中有几个或数百个这样的大集合。我看到的每个答案基本上都是咬紧牙关并将uri传递给文件。这是一种逃避,会破坏分布式系统。

    然后是维护。重建 View 需要一个涉及事件存储的过程。因此,现在您编写的每个 View 维护任务都进一步将您的写入模型绑定(bind)到使用事件存储......永远。

    CQRS 的重点不是围绕读模型和写模型的用例根本不兼容吗?那么为什么我们要把读模型的东西放在写端,牺牲灵 active 和性能,然后再把它们耦合起来。为什么要花时间?

    所以总而言之,我很困惑。在我所坐的所有方面,事件存储作为读取模型细节更有意义。您仍然可以获得保留事件存储的许多好处,但您不会过度抽象写入端持久性,这可能会降低灵 active 和性能。而且您不会通过泄漏的抽象和维护任务将您的读/写端耦合起来。

    那么有人可以向我解释一个或多个令人信服的理由将其保留在写入方面吗?或者,为什么不应该将其作为维护/报告问题放在读取端?同样,我不是在质疑商店的实用性。就在它应该去的地方:)

    最佳答案

    这是一个长期死的问题,有人指出我。有很多原因可以更好地在写入端存储事件。

    据我了解,您所谈论的架构是我看到的一种非常常见的架构……失败了。我们将域模型存储在关系数据库中,然后输出事件。您添加它们的扭曲,将读取端的事件保存在事件存储中。这很可能会导致困惑。

    您将遇到的第一个问题是发布您的事件。当我保存到数据库并发布到 MSMQ 时会发生什么(我死在中间)。因此在它们之间引入了 DTC。这是一件大事,应该像瘟疫一样避免分布式事务。它也非常低效,因为我可能使数据持久化两次(一次排队到数据库)。这将大大限制系统吞吐量(200-300 条消息/秒的 DTC 基准​​很常见,而事件只有 20-30k/秒是常见的)。

    有些人通过在他们的数据库中放置一个包含事件并作为队列操作的表来解决对 DTC 的需求。这将避免对 DTC 的需要,但这仍会遇到下一个问题。

    当你有错误时会发生什么?我知道您永远不会编写有错误的代码,但后来有一位 Jrs/维护开发人员使用该项目。例如,当域对象更改和引发的事件不匹配时会发生什么?假设您将域对象上的状态设置为“LA”(硬编码),但您正确地将事件上的状态设置为 cmd.State(“CT”)。

    您将如何检测正在发生的此类错误?正在讨论的最大问题是现在有两个“真相”来源,即写入端的数据库和出现的事件流。没有办法证明它们是等价的。这将导致各种奇怪的错误。

    关于cqrs - 为什么事件存储应该在写端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10588286/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com