Service Fabric Actors - 将状态保存到数据库

时间:2016-07-15 11:47:31

标签: azure-service-fabric

我正在开发一个示例Service Fabric项目,我必须在该项目中维护购物清单。为此我有一个ShoppingList actor,可以通过特定的id识别。它使用StateManager将当前列表内容存储在其状态中。一切正常。

然而,与此同时,我希望在sql数据库中维护购物清单内容。特别是:

  • 存储所有添加/删除项目请求以供将来分析(ML)
  • 关于来自db的第一个actor初始化加载列表内容(例如,在重新创建集群之后)

实现这一目标的最佳方法是什么?创建一个自定义StateProvider(如何?找不到示例)? 或者可能有另一个服务/ actor来处理所有数据库操作(可能使用队列和提醒)?

所有示例似乎完全依赖于默认的StateManager,没有数据持久性存储到外部存储,因此我不确定最佳做法是什么。

1 个答案:

答案 0 :(得分:5)

最好的方法是让一个单独的实体负责将数据存储到DB。演员只会发送一个事件(不是暗示SF事件)和一些有关已执行操作的数据,而另一个实体将捕获它并执行其余的工作。

但是当然你可以在演员本身实现这个东西,但它会带来两个可能的问题:

  • 如果在演员和数据库之间存在数据库或连接存在问题,或者如果数据库本身存在高负载并且它将缓慢处理请求,那么Actor将无法处理其他请求。演员必须等到转发到DB成功完成。
  • 可能会因为许多参与者的多个单一连接而不是来自其他实体的一个或多个连接以及批量插入而导致DB过载。

因此,您的最终解决方案将取决于您系统的工作量。但是,如果此类数据的价值太高而无法承受损失,您肯定需要一个可靠的队列来安全地将数据存储在数据库中。

此外,我认为您可以使用默认状态管理器存储日志和有关事务的信息,然后将其传输到数据库并在事务完成后从服务的状态中删除。没有必要在服务中永久存储此类数据。

另外需要考虑的事项 - 从DB读取。也许,如果你有关系数据库并且将使用新记录只更新一个表+如果有大量的参与者将在激活时查询这些数据,那么你将会因为这个表被锁定以便读取或写入而导致性能下降不会将其配置为行为不同。因此,您可能需要缓存系统来读取演员激活的数据 - 取决于您的工作量。

关于实现自定义状态管理器:请查看this示例。基本上,您需要做的就是实现IReliableStateManagerReplica接口并将其传递给StatefullService构造函数。