我接近的当前问题域是我们的事件存储;我们的应用程序的部分基于事件源和CQRS,我正在评估如何将此事件存储移到服务结构平台。事件存储将包含很多时间序列数据,因为它是我们唯一的真实数据来源,在那里持久化,它必须是一致的,复制和存储到某种形式的耐久存储。
我认为这样做的一种方式是有状态的“EventStream”actor;使用事件源的聚合的每个实例将其事件存储在隔离的流内。这意味着有状态的actor可以跟踪其自己的流的所有事件,并且我已经满足了我对数据如何存储(事务,复制和持久)的要求。但是,一些流可能会增长非常大(成千上万,如果不是数百万的事件),这是我开始不确定的地方。我想,当这些大数据模型需要序列化或反序列化从磁盘时,具有大量状态的actor将影响系统的性能。
另一个选择是保持这些actors是无状态的,让他们只是从一些外部存储(如Azure sql)读取数据 – 或者只使用无状态服务而不是actors。
基本上,当一个演员/服务的状态量“太多”,你应该开始考虑处理状态的其他方式?
此外,在Service Fabric Actors design pattern: Some anti-patterns文档中的这一节让我有点困惑:
Treat Azure Service Fabric Actors as a transactional system. Azure Service Fabric Actors is not a two phase commit-based system offering ACID. If we do not implement the optional persistence,and the machine the actor is running on dies,its current state will go with it. The actor will be coming up on another node very fast,but unless we have implemented the backing persistence,the state will be gone. However,between leveraging retries,duplicate filtering,and/or idempotent design,you can achieve a high level of reliability and consistency.
“如果我们不实现可选持久化”是什么意思?我的印象是,只要你的事务修改状态成功,你的数据被持久化到持久存储,并复制到至少一个子集的副本。这一段让我想知道,如果有的情况下,我的演员/服务中的状态会迷路,如果这是我需要处理自己。我从文档的其他部分的有状态模型得到的印象似乎抵消了这个声明。
很难有一个关于太多局部状态的一般规则,但也许,它有助于思考热与冷的数据。
可靠的Actors还提供了自定义StateProvider的能力,因此您还可以考虑使用特定的策略实现一个自定义的StateProvider(通过实现IActorStateProvider),您需要更高效地满足您在数据量,延迟,可靠性等等(注意:文档在StateProvider接口上仍然很少,但是如果这是你想要的,我们可以发布一些示例代码)。
关于反模式:注意更多是关于跨多个角色实现事务。可靠的参与者对一个行为者边界内的数据的可靠性提供完全的保证。由于Actor模型的分布式和松散耦合的性质,实现涉及多个actors的事务不是一个简单的任务。如果“分布式”事务是一个强大的要求,可靠的服务编程模型可能是更好的适合。