首页 文章

使用事件采购和CQRS有哪些缺点?

提问于
浏览
23

事件来源和CQRS很棒,因为它让开发人员陷入了一个预先建模的数据库,开发人员必须在应用程序的生命周期内使用该数据库,除非有大数据迁移项目 . CQRS和ES还有其他好处,如扩展事件存储,审计日志等已经遍布互联网 .

But what are the disadvantages ?

在研究和编写小型演示应用程序之后,我可以想到以下一些缺点

  • Complex: 有人说ES很复杂 . 但是我的查询语言功能和分发数据库比分布式应用程序代码更难(只需在另一台机器上部署另一个实例!) .

  • High disk space usage :事件存储可能最终使用大量磁盘空间来存储事件 . 但是我们可以每隔几周安排一次清理并创建快照,也许我们可以在外部HD上本地存储历史事件,这只是因为我们将来需要旧事件吗?

  • High memory usage :每个域对象的状态都存储在内存中,这可能会增加RAM的使用量,而且我们所有的RAM都是多么昂贵 . BIG PROBLEM!! 因为我很穷!任何解决方案?可能是使用Sqlite而不是在内存中存储状态?我是否通过在我的应用程序中引入多个Sqlite实例来使事情变得更复杂?

  • Longer bootup time :失败或软件升级启动速度很慢,具体取决于事件数量 . 但我们可以使用快照来解决这个问题吗?

  • Eventual consistency :某些应用程序出现问题 . 想象一下,如果Facebook使用CQRS的事件采购来存储帖子并考虑到facebook系统的繁忙程度,如果我发布帖子,我会在第二天看到我的fb帖子:)

  • Serialized events in Event store :事件将事件存储为序列化对象,这意味着我们可以在将来为事件添加另一个属性 . 解决方案是将事件存储为JSON对象而不是序列化事件?但这是个好主意吗?或者添加更多事件以支持对orignal事件对象的更改?

有人可以评论我在这里提出的不利因素,如果我错了就纠正我,并建议我可能错过任何其他的吗?

4 回答

  • 26

    这是我对此的看法 .

    • CQRS ES通过拥有丰富的域对象,简单的数据模型,历史跟踪,对并发性问题的更多可见性,可伸缩性等等,可以使复杂软件系统中的事情变得更加简单 . 它确实需要以不同的方式思考系统,因此很难找到合格的开发人员 . 但CQRS使得跨开发人员分离职责变得更加简单 . 例如,初级开发人员可以完全使用读取方而无需触及业务逻辑 .

    • 数据副本肯定需要更多磁盘空间 . 但是这些天存储相对便宜 . 可能需要IT支持团队进行更多备份,并规划在出现问题的情况下如何恢复系统 . 但是,如今的服务器虚拟化使其成为一个更加简化的工作流程 . 此外,在没有单片数据库的情况下,在系统中创建冗余要容易得多 .

    • 我不认为更高的内存使用率是一个问题 . 业务对象水化应按需进行 . 对象不应该保留对已经持久化的事件的引用 . 事件水化应该只在持久数据时发生 . 在读取方面,您没有通常在分层系统中发生的实体 - > DTO - > ViewModel转换,并且您不会进行任何类型的对象更改跟踪,而全功能ORM通常会这样做 . 大多数系统执行的读取比写入要多得多 .

    • 如果由于各种数据上下文的初始化而使用多个异构数据库,则较长的启动时间可能会有轻微问题 . 但是,如果您使用像ADO .NET这样简单的东西来与事件存储进行交互,并使用微型ORM进行读取,那么系统将比任何全功能ORM更快地“冷启动” . 这里重要的是不要过度复杂化访问数据的方式 . 这实际上是CQRS应该解决的问题 . 正如我之前所说的那样,读取端应该为视图建模,而不会有重新映射数据的任何开销 .

    • 根据我的经验,两阶段提交可以很好地适用于不需要为数千个用户扩展的系统 . 您需要选择能够与分布式事务协调器配合使用的数据库 . 例如,PostgreSQL可以很好地用于读写单独的模型 . 如果系统需要针对大量并发用户进行扩展,则必须将其设计为最终的一致性 . 在某些情况下,您将使用不使用CQRS的聚合根或上下文边界来避免最终的一致性 . 它对域的非协作部分有意义 .

    • 如果为事件存储选择正确的数据库,则可以按序列化格式(如JSON或XML)查询事件 . 这应该只是为了分析的目的 . 系统内部的任何内容都不应该通过聚合根id和事件类型之外的任何内容来查询事件存储 . 该数据将被索引并存在于序列化事件之外 .

  • 5

    只是评论第5点 . 我被告知Facebook确实使用ES与最终一致性,这就是为什么你有时会看到一个帖子消失并在你发布后重新出现 .

    通常,您的浏览器访问的读取模型位于“靠近”位置,但在您发布帖子后,SPA会切换到与您的写入模型接近的读取模型 . 写模型(事件)和读模型之间的紧密接近意味着您可以看到自己的帖子 .

    然而,15分钟后,您的SPA切换回第一个更接近的读取模型 . 如果包含您的帖子的事件尚未传播到该读取模型,您将看到自己的帖子仅在稍后重新出现时消失 .

  • 0

    我知道自问这个问题已经差不多3年了,但仍然可能对某人有用 . 关键点是

    • 使用快照进行缩放

    • 数据的可见性

    • 架构正在改变

    • 处理复杂的域名

    • 需要向大多数新团队成员解释

  • 0

    事件源和CQRS非常棒,因为它让开发人员陷入了一个预建模型数据库,开发人员必须在应用程序的生命周期内使用该数据库,除非有大数据迁移项目 .

    这是一个很大的误解 . 关系数据库是为模型的演化而发明的(由于简单的二维表而不是预定义的层次结构) . 通过视图和过程确保数据访问的封装,逻辑和物理模型可以独立发展 . 这也是SQL用同一种语言定义DDL和DML的原因 . 一些RDBMS还允许所有这些演进在线版本(连续交付)作为基于Oracle版本的重新定义进行版本控制和部署 .

    大数据结构是预定义的,只能使用为此结构开发的代码进行读取 . 好的,立即消费,但10年后你将很难阅读它,没有确切的版本,语言编译器或解释器 .

相关问题