【问题标题】:Performance issues with large datasets大型数据集的性能问题
【发布时间】:2019-06-29 01:24:17
【问题描述】:

有没有办法通过aggregateId过滤与读取模型关联的投影中的事件?

在进行的测试中,我们总是收到所有个注册事件。是否可以在前一阶段应用过滤器?

我们有 100,000 个 aggregateId,每个 id 关联了 15,000 个 events。无法按aggregateId 过滤,我们的预测必须遍历所有 events

【问题讨论】:

  • 您能详细说明一下吗?您是否正在为单个聚合构建读取模型?读取模型本质上是整个应用程序的读取数据库,因此它应该是持久的。在您的情况下,第一次构建可能需要一段时间,但它只会消耗新事件。
  • 我们不知道什么是满足我们要求的最佳方法。我们也尝试使用 ViewModel 检索状态(应用 aggregateId 过滤器),但是当事件记录增长时,它的性能似乎非常低。例如,对于 15.000 个事件,ViewModel 投影需要 50 秒...我们的系统在现实世界中将有更多的事件...我们知道后续请求会提高很多性能,但我们担心应用程序初始化时的第一个请求响应时间...
  • 好的,我明白了。我正在写一个完整的答案。

标签: resolvejs


【解决方案1】:

所以你有 100.000 个聚合,每个聚合有 15.000 个事件。

你可以使用ReadModel or ViewModel:

读取模型

可以将读取模型视为您的应用程序的读取数据库。因此,如果您想存储有关每个聚合的一些数据,您应该为每个聚合在某个表中插入/更新行或条目,请参阅Hacker News example read model code

了解解析读取模型是按需构建的,这一点很重要 - 在第一次查询时。如果您有很多活动,可能需要一些时间。

另一件需要考虑的事情 - 一个新创建的解析应用程序被配置为使用内存数据库来读取模型,因此在每个应用程序启动时您都会重新构建它。

如果您有很多事件,并且不想在每次启动应用程序时等待构建读取模型,则必须为您的读取模型配置一个真实的数据库存储。

配置适配器没有很好的文档,we'll fix this。以下是您需要在 mongoDB 的相关配置文件中编写的内容:

readModelAdapters: [
  {
    name: 'default',
    module: 'resolve-readmodel-mongo',
    options: {
      url: 'mongodb://127.0.0.1:27017/MyDatabaseName',
    }
  }
]

既然你有一个数据库引擎,你也可以将它用于事件存储:

storageAdapter: {
  module: 'resolve-storage-mongo',
  options: {
    url: 'mongodb://127.0.0.1:27017/MyDatabaseName',
    collectionName: 'Events'
  }
}

视图模型 ViewModel 在查询期间动态构建。它不需要存储,但它会读取给定aggregateId 的所有事件。

resolve 视图模型正在使用快照。因此,如果给定聚合有 15.000 个事件,那么在第一次请求时,所有这些事件都将首次应用于计算 vie 状态。此后,此状态将被保存,所有后续请求将读取快照和所有后续事件。默认情况下,每 100 个事件完成一次快照。因此,在第二个查询中,reSolve 将读取此视图模型的快照,并对其应用不超过 100 个事件。

同样,请记住,如果您希望快照存储持久化,您应该配置一个快照适配器:

snapshotAdapter: {
  module: 'resolve-snapshot-lite',
  options: {
    pathToFile: 'path/to/file',
    bucketSize: 100
  }
}

ViewModel 还有一个好处 - 如果您在客户端使用 resolve-redux 中间件,它将在那里保持最新状态,响应式应用应用通过 websocket 接收的事件。

【讨论】:

  • 谢谢!在我们的例子中,我们需要经常使这些缓存失效。由于这个原因,读取模型选项被丢弃。如果您有 1 个包含 15,000 个事件的聚合,则使用读取模型生成状态比使用查看模型快得多,但如果我们有 100,000 个聚合,每个聚合包含 15,000 个事件,则读取模型也不是一个选项。我们不会在客户端使用 resolve-redux 中间件。为什么 View Model 的状态生成比 Read Model 慢得多?我们可以配置读取模型,使其仅读取给定的聚合吗?
  • 我想我不明白你的情况 - 你为什么要经常使读取模型无效?您能否分享一个示例项目和一些说明您的问题的测试数据?
  • 我们需要使状态无效,因为用户可以请求放置在时间线中的任何点,这会迫使我们重新计算状态。
  • 简而言之——你的阅读模型应该包含所有问题的答案。它不应该在查询时重建。
  • 好的!非常感谢!
猜你喜欢
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2016-11-29
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
相关资源
最近更新 更多