当我们不关心过去的状态时,使用事件采购案例

时间:2017-08-04 08:27:33

标签: sql cassandra event-sourcing nosql

我一直在阅读有关事件采购模式的内容,我已经看到它在我所参与的项目中使用过,但我仍然没有看到它的任何好处,同时它使设计更加复杂。

也就是说,很多消息来源都提到如果你想看看审计日志,事件采购是好的,能够重建15天前的状态,我看到事件采购解决了所有这些问题。但除此之外,有什么意义呢?

是的,我可以想象如果你处于关系世界,那么写入锁定数据等相对较慢。但是通过使用no-sql并使用像Cassandra之类的东西来解决这个问题要容易得多。 Cassandra的写作非常快,因为它们只是附加(有点临时事件源),它也可以很好地扩展。消息来源还提到事件采购有助于扩展 - 它如何帮助您扩展,而不是每个用户存储~1行数据,现在您有9000而不是检索该单行,现在您正在重放9000行(或者更少,如果你使设计更复杂,并添加一些状态的时间快照,并从最后一个快照重播当前状态。)

事件采购解决或链接的任何现实生活问题的例子将非常受欢迎。

1 个答案:

答案 0 :(得分:2)

虽然我还没有实现分布式,事件源子系统(所以我不是专家),但我一直在研究和评估这种方法。活动采购提供了许多重要的好处:

  1. 可靠性
  2. 可扩展性
  3. 进化性
  4. 审核
  5. 我确定还有更多。在很大程度上,事件采购的好处取决于您与之比较的基线(CRUD,事件驱动的DDD,CQRS或其他)以及域。

    让我们依次看看每一个:

    <强>可靠性 使用事件驱动系统,在系统更新时触发事件,您经常遇到问题:如何更新系统状态并一次性触发事件?如果第二个操作失败,则表明系统处于损坏的不一致状态。事件来源为此提供了一个简洁的解决方案,因为系统只需要一个操作来进行状态更改,这将以原子方式成功或失败 - 写入事件。其他解决方案往往更复杂,可扩展性更低 - 两阶段提交等等。

    这对于大型高交易系统来说是一个很大的好处,在交易正在进行的过程中,组件发生故障,不断更新或更换。在不担心数据损坏或一致性的情况下随时终止进程的能力是一个很大的好处,可以帮助您在晚上睡觉。

    在许多领域,您不会有并发写入,或者您不会要求事件,因为状态更改没有连锁效应,在这种情况下,事件采购不太可能是一个好方法,并且像CRUD这样简单的方法可能没问题。

    <强>可扩展性 首先,事件流使得一致的写入非常有效 - 它只是一个仅附加日志,这使得复制和比较和设置&#39;简单优化。在你需要保护你的不变量的场景中,像Cassandra这样的东西很慢 - 也就是说,你需要根据行的当前状态验证命令,如果行更改之前拒绝更新你有机会更新它。您需要使用&#39;轻量级交易&#39;确保一致性,或每个分区具有一个写入程序线程,以便您可以确保在允许更新之前可以针对系统的当前状态成功验证命令。当然,您可以使用这些方法中的任何一种(单线程/轻量级事务)在Cassandra中实现事件存储。

    读取可伸缩性是最大的性能优势 - 因为您可以通过读取事件流在数据上构建尽可能多的不同最终一致的投影(视图),并根据需要在这些视图上水平扩展查询服务。这些视图可以根据需要使用自定义数据库(Cassandra,图形数据库),以允许根据需要优化查询。它们可以存储非规范化数据,以允许在单个(非连接)数据库查询中获取所有必需数据。它们甚至可以将投影状态存储在内存中,以获得最佳性能。虽然这可以在没有事件源的情况下实现,但实现起来要复杂得多。

    如果您没有复杂的查询和高可扩展性要求,事件采购可能不是正确的解决方案。

    <强>进化性 如果您需要以新的方式查看数据,例如在应用程序中创建新的客户端应用程序或屏幕,则可以非常轻松地将事件流的新投影添加为新的独立服务。如果您需要将一些数据添加到您错过的现有读取视图中,或者修复读取视图中的错误,则可以使用事件流重建视图并丢弃旧视图。这里的优势与非事件来源的案例有:

    • 您不需要编写数据库迁移代码,然后编写代码以在事件进入时使视图保持最新。相反,您只需编写代码以使其保持最新,然后在从一开始就发生的事件。
    • 与此相关,您可以进行更新而无需关闭查询服务来进行架构更改 - 而只是让旧服务版本针对旧数据库运行,生成具有新服务版本的新数据库,当它赶上事件流时,只需原子切换然后清理旧服务和数据库,一旦你对新服务稳定感到高兴(注意旧服务将保持自己的状态)在此期间,如果您需要回滚!)。如果没有事件采购,这可能非常难以实现。
    • 如果您需要将任何时态信息添加到您的视图中(例如,何时是最后一次更新,何时创建),那么这些信息已经可用且易于添加,但无法在没有事件源的情况下追溯添加。

    请注意,上述内容并非关于修改事件流(这是一个诡计,请参阅我对下面的挑战的评论) - 它是关于使用现有事件流来增强视图或创建新视图。

    有一些简单的方法可以在没有事件源的情况下执行此操作,例如使用数据库视图(使用RDBMS),但它们不具有可伸缩性。

    事件采购对可演化性也有一些挑战 - 您需要处理事件版本控制,可能使用弱事件架构的组合(因此您可以添加具有默认值的属性)和流替换(当您想要做更大的事情时)改变你的活动)。 Greg Young正在为此写一本好书。

    <强>审核 如你所说,你对此并不感兴趣。