MSR Orleans - 如何使用并行读取创建读写器粒度

时间:2018-01-08 06:48:52

标签: c# multithreading parallel-processing orleans

我需要一个读写器粒子(s?)来保存一些值,以便系统的其他部分可以经常并行地引用它们。

我之后存储的是一些系统范围的配置值,这些配置值经常被访问,并且可能会发生变化,但只是非常罕见(最多每月一次)。系统应该可以重新配置,无需停机。我目前正在考虑的是将数据存储在某个数据库中。然后它将在silo启动时读取,并且会有一个特殊的回调函数,在外部更改后再次读取数据。我不想每次需要时都从数据库中读取数据,因为:

  • 它会在孤岛内部创建不必要的处理开销,因为必须处理和过滤掉一些数据。
  • 它会增加数据库的负载,我不能保证在处理高负载时要像筒仓环境一样好。
  • 数据在更新前由筒仓环境进行验证。直接从数据库中读取意味着当操作员更新并修复新数据时,将没有中间层来保存最后已知的有效数据。

我可以很容易地创建一个读写器锁定的内存数据存储,但奥尔良'单线程执行策略不允许并行访问保存数据的粒度。我可以想到以下几种方法来绕过这个:

  • 在多个谷物中有多个数据副本。这显然不是最佳的。
  • 使用静态字段存储数据并使谷物成为无状态工作者。这意味着每个孤岛都有自己的数据副本(这也有助于减少网络负载),但是没有办法让每个孤岛更新其数据副本(我至少知道)。

建议?

2 个答案:

答案 0 :(得分:2)

你看过类似Smart cache pattern的东西吗?

也许使用Reentrant颗粒也可以提供帮助,这将允许方法调用交错。

我在github上发现this issue要求相同。

答案 1 :(得分:1)

我们找到了一种解决方案,它不需要基于GitHub的基于计时器的更新。我在这里详细说明解决方案:

  1. 有一个主谷物,负责从数据库中读取数据。当配置更改时,此粒度还会接收外部UpdateConfig调用。数据库会手动更新,因此我不在乎它是否自动选择更新。
  2. 每个筒仓都有无国籍的工人缓存谷物。这些粒子将数据存储在静态对象中(以帮助填充内存)并使用读写器锁来管理对数据的访问。当第一个在筒仓上醒来时,它会更新数据,其余的只是使用该数据。它们还支持外部UpdateConfig调用,该调用将依次向主粒子请求新数据。
  3. 有一个引导程序提供程序可以完成两件事。首先,它在初始化时唤醒主粒度,因此数据在需要之前可用,因此我们可以避免延迟初始化打嗝。其次,提供程序还支持控制命令(有关可控提供程序的示例,请参阅here)。收到此命令后,它将询问第一个可用的缓存粒度(保证是本地的)以更新静态对象。这样,数据就会在每个孤岛中更新。无论何时更新数据,master grain都会发送此控制命令。