2

我需要一个读写器粒度来保存一些值,以便系统的其他部分可以频繁地并行引用它们。

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

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

我可以轻松地创建一个读写器锁定的内存数据存储,但是 Orleans 的单线程执行策略不允许并行访问保存数据的粒度。我可以想到以下方法来绕过这个:

  • 在多个grain中拥有多个数据副本。这显然不是最优的。
  • 使用静态字段来存储数据,让grain成为一个无状态的worker。这意味着每个筒仓都有自己的数据副本(这也有助于减少网络负载),但没有办法要求每个筒仓更新其数据副本(至少我知道)。

建议?

4

2 回答 2

2

你看过类似智能缓存模式的东西吗?

也许使用Reentrant颗粒也有帮助,这将允许方法调用交错。

我在 github 上发现了这个问题,要求相同。

于 2018-01-08T08:41:28.767 回答
2

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

  1. 有一个主grain,负责从数据库中读取数据。当配置更改时,此grain 还会接收外部 UpdateConfig 调用。数据库是“手动”更新的,所以我不在乎它是否不会自动获取更新。
  2. 每个筒仓上都有无状态工作者缓存颗粒。这些grain将数据存储在静态对象中(以帮助减少内存占用)并使用读写锁来管理对数据的访问。当第一个在筒仓中醒来时,它会更新数据,其余的只是使用该数据。它们还支持外部 UpdateConfig 调用,该调用反过来会向主粒度请求新数据。
  3. 有一个引导提供程序可以做两件事。首先,它在 init 时唤醒 master grain,因此数据在需要之前可用,因此我们可以避免惰性 init 打嗝。其次,提供者还支持控制命令(有关可控提供者的示例,请参见此处)。收到此命令后,它将要求第一个可用的缓存颗粒(保证是本地的)更新静态对象。这样,数据会在每个孤岛内更新。每当更新其数据时,主grain 只需发送此控制命令。
于 2018-01-10T08:56:14.133 回答