通过事件采购和CQRS进行汇总

时间:2018-06-17 13:57:04

标签: azure-functions azure-cosmosdb cqrs event-sourcing materialized-views

为了处理大量的遥测数据并且仍然能够对数据进行快速查询,我使用Azure Functions和Azure Cosmos DB采用了Event Sourcing / CQRS模式。

在我的架构中,入站遥测流存储在充当事件存储的Cosmos DB Collection中。

为了创建原始遥测数据的物化视图,我使用另一个带有Cosmos DB Trigger的Azure功能,该功能在我的事件存储中存储的所有新文档上激活,对这些文档执行转换。

在每个文档的基础上处理文档非常容易。 当我需要引用其他文档以计算我的物化视图时,它变得棘手。

例如,当接收的遥测事件包含相对计数器值(例如,在特定操作中使用的能量)时。在我的物化视图中,我想要一份包含所有能耗总和的文件。

现在,一个简单的实现方法是在物化视图中查看此文档的当前状态,并将该值按新接收的值递增。

我可以使用这种方法得到的问题是当我必须重新计算物化视图时,因为在将来的版本中我需要生成一些额外的视图。

为了重新计算,我只需触摸我想在事件存储中重新计算的所有相关文档,然后触发Azure功能,再次计算实体化视图。这将导致文档进入此Azure函数之前已处理过。

当重新计算发生时,我的计数器现在不再准确,如果我只是增加我的总和,因为已经是已经部分总和的文档将再次添加。

解决这种重新计算的方法(我想到的)将是:

  • 跟踪作为和的一部分的所有源文档并忽略 已经属于和的文件的事件
  • 跟踪已经是和的一部分的最新遥测事件的序列号,并忽略序列号低于重新计算时已经是和的一部分的事件。

你能就如何正确解决这种情况给我一些建议吗?

1 个答案:

答案 0 :(得分:1)

因此,总结@Mikhail和@RomanEremin的评论以及我的想法,这将是处理这些情况的方法:

在重新计算视图的情况下:

  • 删除现有聚合并从头开始重播 事件存储中的事件。

如果事件总线至少一次发送一次(Azure函数与CosmosDb触发器的行为由于基础ChangeFeedProcessor而导致的行为):

  • 版本1:跟踪事件ID(文档ID),它们是聚合文档中聚合的一部分,而忽略了已经是聚合中的事件。
  • 版本2:提供源事件的顺序版本(序列号),并将聚合所基于的版本存储在聚合文档中。在计算汇总时,请对照事件的序列号检查此序列号。如果事件的序列号比聚合文档的序列号低:请忽略,否则重新计算聚合并更新聚合所基于的序列号。