2015-05-06 21 views
16

Azure服务结构似乎专注于所有数据都适合RAM的情况,并且将持久性用作后备存储。可靠服务旨在将信息存储在可靠集合中,这些集合使用将日志信息写入RAM的log-checkpoint system。同时,对于Reliable Actors,default actor state provider是“Service Fabric平台提供的分布式键值存储”。这似乎表明,同样的限制也适用。Azure服务结构中有状态服务和外部持久性之间的转换

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

在Orleans中,这似乎是使用持久性存储库(如Azure表)自动处理的。但是,服务结构和可靠集合的主要设计目的似乎是避免需要外部服务,从而增强了数据的局部性。目前的文档预计人们可能希望将数据移动到disaster recovery and analytics的某个永久存储中,但它不讨论在持久性支持的内存中的操作员和更永久的存储形式之间来回移动数据的可能性。

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

或者,也许答案是,一个人必须管理这一点。一种方法可能是让Actor跟踪它的“热”程度,并根据需要切换其持久性存储。但是这牺牲了Actor模型的一个好处,即actor的自动分配和释放。同样,我们可能会定期从Reliable Dictionary中删除项目并将其添加到其他一些持久性存储中,然后将其添加回来。但是,这又需要知道什么时候进行转换才有意义。

几个例子可以帮助结晶这样的:“房间”

(1)假设我们正在实施一个多人游戏有许多不同的我们并不需要同时记忆所有的房间,但是我们需要将它们移动到内存中,并且在玩家加入时使用本地持久性作为备份。 (2)假设我们正在实现一个仅作为附加的B树作为数据库的组成部分。诱惑将是让每个B-Tree节点成为有状态的演员。我们希望热B树留在记忆中,但当然整个索引都不能记忆。看起来这是一个已经为DocumentDB这样的事情实现的核心场景,但从文档中我不清楚如何做到这一点。

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

回答

13

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

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

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

+0

感谢您的澄清。所以,KVS商店不同于可靠的收藏,因为它们不会一直在追求所有状态。 (或者也许可靠的集合有时会分页存储,尽管这些文档似乎有其他建议?)这样做更有意义。当然,在某些时候,KVS商店会在磁盘上耗尽内存,但我认为这可以通过监控来避免。 – user357783

+2

可靠的集合也将它们的状态保存在磁盘上。本页面上的文档明确提到它。 http://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-reliable-collections/。 “坚持:数据持久保存到磁盘,以抵御大规模停机(例如,数据中心停电)。”在文档中是否有其他地方提供的地方? –

+0

此外,为解决磁盘空间不足的问题,您可以阅读关于可伸缩性的文章(http://azure.microsoft.com/zh-cn/documentation/articles/service-fabric-concepts-scalability/)策略来扩展您的服务并避免这种情况。正如您已经指出的那样,监测也是一个好主意。 –

5

KvsActorStateProvider确实将actor状态存储在一个与ReliableDictionary类似的结构的KeyValueStore中。

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

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

或者,您可以在您的Actor实现中完全处理它。钩入Actor Lifecycle和OnDeactivateAsync,以便在将来某个指定时间垃圾收集实例或使用Actor Reminder时,将该状态序列化并存储在诸如blob或table存储的冷存储中,并清空状态属性。然后可以使用ActivateAsync覆盖从离线存储和反序列化中检索此状态。

+0

这非常有帮助。令我费解的是为什么Reliable Actors框架包含垃圾回收功能,但随后将KvsActorStateProvider用作默认存储(我相信,只包含在内)存储提供程序。如果KvsActorStateProvider有效地将所有内容保存在RAM和磁盘上,那么这不会消除垃圾收集的好处吗?当然,在节点之间移动actor是有好处的,但通常我们会认为垃圾回收是释放RAM内存。 – user357783

+0

存储在KVS中的是有状态演员的状态。 actor对象本身坐在内存中,当Actor被垃圾收集时,可以有局部变量从内存中释放。 – Darran

相关问题