60

我晚上都在评估 Azure Service Fabric 作为我们当前 WebApps/CloudServices 堆栈的替代品,并且有点不确定如何决定何时具有状态的服务/参与者应该是有状态的参与者,以及何时应该是无状态的参与者外部持久化状态(Azure SQL、Azure 存储和 DocumentDB)。我知道这是一个相当新的产品(至少对公众而言),因此可能还没有很多关于此的最佳实践,但我已经阅读了 Microsoft 提供的大部分文档,但没有找到明确的回答这个。

我正在接近的当前问题域是我们的事件存储;我们的部分应用程序基于事件溯源和 CQRS,我正在评估如何将此事件存储转移到 Service Fabric 平台。事件存储将包含大量时间序列数据,并且由于它是我们保存在那里的数据的唯一真实来源,因此它必须是一致的、复制的并存储到某种形式的持久存储中。

我考虑过的一种方法是使用有状态的“EventStream”演员;使用事件源的聚合的每个实例都将其事件存储在一个隔离的流中。这意味着有状态的参与者可以跟踪它自己的流的所有事件,并且我已经满足了我对数据存储方式(事务性、复制性和持久性)的要求。但是,某些流可能会变得非常大(数十万,如果不是数百万,事件),这就是我开始不确定的地方。我想,当这些大型数据模型需要序列化到磁盘或从磁盘反序列化时,拥有大量状态的参与者会对系统的性能产生影响。

另一种选择是让这些参与者保持无状态,让他们从 Azure SQL 等外部存储中读取数据 - 或者只使用无状态服务而不是参与者。

基本上,演员/服务的状态量何时“过多”,您应该开始考虑其他处理状态的方式?

另外,Service Fabric Actors 设计模式中的这一部分:一些反模式文档让我有点困惑:

将 Azure Service Fabric Actors 视为事务系统。Azure Service Fabric Actors 不是提供 ACID 的基于两阶段提交的系统。如果我们不实现可选的持久性,并且actor正在运行的机器死亡,它的当前状态将随之消失。演员将很快出现在另一个节点上,但除非我们实现了支持持久性,否则状态将消失。但是,在利用重试、重复过滤和/或幂等设计之间,您可以实现高水平的可靠性和一致性。

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

4

3 回答 3

24

您拥有的一种选择是在参与者中保留“一些”状态(假设哪些可以被认为是需要快速可用的热门数据)并将其他所有内容存储在“传统”存储基础架构上,例如 SQL Azure , DocDB, .... 很难有一个关于太多本地状态的一般规则,但也许考虑一下热数据和冷数据会有所帮助。Reliable Actors 还提供自定义 StateProvider 的能力,因此您还可以考虑使用特定策略实现自定义 StateProvider(通过实现 IActorStateProvider),以便更高效地满足数据量、延迟方面的要求,可靠性等(注:

关于反模式:该说明更多地是关于跨多个参与者实现事务。Reliable Actors 为参与者边界内数据的可靠性提供了充分保证。由于 Actor 模型的分布式和松耦合性质,实现涉及多个 Actor 的事务并非易事。如果“分布式”事务是一个强需求,那么 Reliable Services 编程模型可能更适合。

于 2015-05-06T22:14:08.297 回答
5

我知道这已经得到解答,但最近发现自己在使用 CQRS/ES 系统时遇到了同样的困境,这就是我的解决方法:

  1. 每个聚合都是一个参与者,其中只存储了当前状态。
  2. 在命令上,聚合将影响状态更改并引发事件。
  3. 事件本身存储在 DocDb 中。
  4. 激活时,AggregateActor 实例从 DocDb 读取事件(如果可用)以重新创建其状态。这显然只在每个actor激活时执行一次。这处理了参与者实例从一个节点迁移到另一个节点的情况。
于 2016-05-25T05:31:13.207 回答
3

回答@Trond 的sedcondary 问题,“如果我们不实现可选的持久性”,这意味着什么?

Actor 始终是一个有状态的服务,它的状态可以使用 Actor 类上的属性进行配置,以在以下三种模式之一中运行:

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

可以在 Microsoft 文档中找到对该主题的完整讨论

于 2017-11-04T04:00:45.243 回答