17

Azure Service Fabric 似乎专注于所有数据都可以放入 RAM 并且持久性用作后备存储的方案。Reliable Services 旨在将信息存储在 Reliable Collections 中,该集合使用日志检查点系统,将记录的信息写入 RAM。同时,对于 Reliable Actors,默认的 Actor 状态提供者是“Service Fabric 平台提供的分布式 Key-Value 存储”。这似乎表明同样的限制也适用。

但是,在某些情况下,人们可能希望将 Service Fabric 用于“热数据”,但将“冷数据”写入某种形式的永久存储。处理这种过渡的最佳做法是什么?

在奥尔良,这似乎是使用 Azure 表等持久性存储自动处理的。但似乎 Service Fabric 和 Reliable Collections 的主要设计目的是避免需要外部服务,从而增强数据局部性。当前的文档预计将数据移动到某个永久存储以进行灾难恢复和分析的可能性,但它没有讨论在持久性支持的内存中参与者和更永久的存储形式之间来回移动数据的可能性.

一个可能的答案是 Service Fabric 已经这样做了。也许 Reliable Dictionary 有一些内置机制,用于在持久支持的内存存储和永久存储之间切换。

或者,也许答案是必须自己管理。一种方法可能是让 Actor 跟踪它的“热”程度并根据需要切换其持久性存储。但这牺牲了 Actor 模型的好处之一,即 Actor 的自动分配和释放。类似地,我们可能会定期从 Reliable Dictionary 中删除项目并将其添加到其他一些持久性存储中,然后再将它们添加回来。不过,这同样需要了解何时进行过渡是有意义的。

几个例子可能有助于明确这一点:

(1) 假设我们正在实现一个有许多不同“房间”的多人游戏。我们不需要同时在内存中的所有房间,但我们需要将它们移动到内存中,并在玩家加入它们时使用本地持久性作为备份。

(2) 假设我们正在实现一个仅附加 B-Tree 作为数据库的一部分。诱惑是让每个 B-Tree 节点成为有状态的参与者。我们希望热 b-trees 保留在内存中,但当然整个索引不能在内存中。似乎这是一个已经为 DocumentDB 之类的东西实现的核心场景,但是从文档中我不清楚如何做到这一点。

我发现的一个相关问题是here。但这个问题集中在何时使用 Azure Service Fabric 与外部服务。我的问题是是否需要在它们之间进行转换,或者 Azure Service Fabric 是否已经具备此处所需的所有功能。

4

2 回答 2

14

Key-Value 存储状态提供程序不需要将所有内容都保存在内存中。这个提供者实际上将所有参与者的状态存储在本地磁盘上,并且状态也会复制到其他节点上的本地磁盘上。所以 KVS 存储被认为是持久可靠的存储。

除此之外,活动参与者的状态也存储在内存中。当一个演员有一段时间没有被使用时,它会被停用并被垃圾收集。发生这种情况时,内存中的副本被释放,只保留磁盘上的副本。当actor再次被激活时,状态会从磁盘中获取,并且只要actor处于活动状态就一直保留在内存中。

此外,KVS 不是唯一的内置状态提供程序。我们还有 VolatileActorStateProvider ( http://azure.microsoft.com/en-gb/documentation/articles/service-fabric-reliable-actors-platform/#actor-state-provider-choices )。这是将所有内容保存在内存中的状态提供程序。

于 2015-05-07T02:25:14.703 回答
6

KvsActorStateProvider 确实将 Actor 状态存储在 KeyValueStore 中,它与 ReliableDictionary 的结构类似。

我要问的第一个问题是您是否需要将旧演员状态降级为冷库?将所有内容保存在内存中的限制并不限制您的参与者总数,而是每个副本的总数。因此,您必须首先考虑分区策略,以便您的参与者分布在许多不同的副本中。随着您的需求增长,您可以将更多机器添加到集群中,ServiceFabric 将协调将副本移动到新机器。有关 Actor 服务分区的更多信息,请参阅http://azure.microsoft.com/en-gb/documentation/articles/service-fabric-reliable-actors-platform/

如果您确实想在一段时间后使用冷藏库,那么您有几个选择。首先,您可以使用自定义ActorStateProviderAttribute装饰您的演员,该属性返回您自己的 IActorStateProvider 实现,可以根据您的决定处理持久性。

或者,您可以完全在您的 Actor 实现中处理它。连接到Actor 生命周期和 OnDeactivateAsync 中,这样当实例被垃圾回收时,或在未来某个指定时间使用Actor 提醒时,序列化状态并存储在冷存储(如 blob 或表存储)中并将状态清空财产。然后可以使用 ActivateAsync 覆盖从脱机存储中检索此状态并进行反序列化。

于 2015-05-06T17:11:19.943 回答