了解何时使用有状态服务以及何时依赖Azure Service Fabric中的外部持久性

我花了我的晚上评估Azure服务结构作为我们当前的WebApps / CloudServices堆栈的替代品,并且对于如何确定服务/具有状态的angular色何时应该是有状态的angular色以及何时应该是无状态的angular色外部持久状态(Azure SQL,Azure存储和DocumentDB)。 我知道这是一个相当新的产品(至less对于普通大众),所以关于这方面可能还没有很多最佳实践,但是我已经阅读了Microsoft提供的大多数文档 ,但没有find明确的为此回答。

目前我接近的问题领域是我们的活动商店; 部分应用程序基于事件采购和CQRS,我正在评估如何将此事件存储转移到Service Fabric平台。 事件存储将包含大量的时间序列数据,因为它是我们保存数据的唯一真实来源,因此它必须一致,复制并存储到某种forms的持久存储中。

我曾经考虑过这样做的一种方式是使用有状态的“EventStream”actor。 使用事件采购的每个聚合实例将其事件存储在隔离的stream中。 这意味着有状态的演员可以跟踪所有事件的自己的stream,我已经满足了我的要求,如何存储数据(交易,复制和持久)。 然而,有些stream可能会变得非常大(数十万,如果不是数百万的话),这就是我开始不确定的地方。 有一个具有大量状态的angular色,我想可能会影响系统的性能,当这些大型数据模型需要从磁盘序列化或反序列化时。

另一个select是让这些actor无状态,让他们只从Azure SQL等外部存储中读取数据,或者只是使用无状态服务而不是actor。

基本上,演员/服务的状态数量是多less,你应该开始考虑处理状态的其他方式?

此外, 服务结构演员devise模式中的这一部分:一些反模式文档让我有点困惑:

将Azure服务结构参与者视为交易系统。 Azure服务结构参与者不是基于提交ACID的两阶段提交系统。 如果我们没有实现可选的持久化,而且这个actor正在运行的机器就不存在了,它的当前状态就会随之而来。 这个angular色会很快到达另一个节点,但是除非我们已经实现了支持持久性,否则状态将会消失。 但是,在利用重试,重复过滤和/或幂等devise之间,可以实现高度的可靠性和一致性。

“如果我们不执行可选的持久性”在这里表示什么? 我的印象是,只要修改状态的事务成功,您的数据就会持久化存储并复制到副本的至less一个子集。 这段话让我想知道是否有情况,我的演员/服务中的状态会丢失,如果这是我需要处理自己的事情。 我在文档的其他部分从有状态模型得到的印象似乎抵消了这种说法。

您拥有的一个select是在演员中保留“某些”状态(假设可能被认为是需要快速获取的热点数据),并将其他所有内容存储在“传统”存储基础结构中,例如SQL Azure ,DocDB,….对于太多的本地状态有一个普遍的规则是困难的,但也许有助于考虑热数据和冷数据。 可靠的Actor还可以自定义StateProvider,所以你也可以考虑实现一个自定义的StateProvider(通过实现IActorStateProvider)和特定的策略,你需要更高效的数据量,延迟,可靠性等等(注意:StateProvider接口上的文档仍然非常小,但是如果这是你想要的东西,我们可以发布一些示例代码)。

关于反模式:这个说明更多的是关于跨多个参与者的事务。 可靠的演员提供了在演员边界内的数据可靠性的充分保证。 由于Actor模型的分布式和松散耦合性质,实现涉及多个参与者的事务并不是一件简单的事情。 如果“分布式”交易是一个强有力的要求,可靠服务编程模型可能更适合。

我知道这已经得到了回答,但是最近发现自己和CQRS / ES系统处于同一个困境,下面是我如何去做的

  1. 每个Aggregate都是一个只存在当前状态的actor。
  2. 在一个命令上,聚合会影响状态的改变并引发一个事件。
  3. 事件本身存储在一个DocDb中。
  4. 激活时,AggregateActor实例从DocDb读取事件(如果可用的话)以重新创build它的状态。 这显然是每个演员激活只有一次。 这照顾到一个actor实例从一个节点迁移到另一个节点的情况。

要回答@Trond的中间问题,即“如果我们没有实现可选的持久性,那么'在这里表示什么?

一个参与者总是一个有状态的服务,并且可以使用参与者类的属性来configuration其状态,以三种模式之一进行操作:

  1. 持续存在。 状态被复制到所有副本实例,并且也被写入磁盘。 即使所有副本都closures,状态也会保持不变。
  2. 挥发性。 状态被复制到所有副本实例,仅在内存中。 这意味着只要一个副本实例处于活动状态,就保持状态。 但是当所有副本都closures时,状态会丢失,重新启动后无法恢复。
  3. 没有持久性。 状态不会复制到其他副本实例,也不会复制到磁盘。 这提供了最less的状态保护。

有关该主题的完整讨论可以在Microsoft文档中find