【问题标题】:How can I trigger Orleans Grain to re-activate?如何触发奥尔良谷物重新激活?
【发布时间】:2020-12-15 23:54:34
【问题描述】:

如果我必须在 Orleans 一组 Grains 后面的持久层上执行操作,我如何确保受影响的 Grains 可以针对更新的数据重新激活?

我的示例是我在 Employee 记录级别有一个grain(EmployeeID 作为 Grain ID),我需要对一些记录执行批量操作。显然,重要的是我确保在此操作后谷物重新加载到那里。

我创建了一个带有谷物的奥尔良筒仓来执行各种操作,包括员工更换。我正在使用如下 GetGrain 功能

var employeeGrain = _clusterClient.GetGrain<IEmployeeGrain>(employeeId, "employee");

根据标准奥尔良生命周期,该颗粒在使用时将保持活动状态。我的问题是,如果我故意执行更改基础数据的操作,我该如何触发受影响的颗粒重新激活?

来自官方文档 https://dotnet.github.io/orleans/1.5/Documentation/Advanced-Concepts/Activation-Garbage-Collection.html

您似乎可以强制停用单个颗粒

this.DeactivateOnIdle()

但是,如果我做一个更大的操作,我想避免按粒料做吗?我想理想情况下回收特定类型的所有谷物。

【问题讨论】:

  • 乔恩,欢迎来到 SO。您能否详细说明您已经尝试过的内容以及无效的内容?

标签: .net orleans


【解决方案1】:

根据标准奥尔良生命周期,该颗粒在使用时将保持活动状态。我的问题是我是否故意执行更改基础数据的操作...

我认为您还没有完全了解奥尔良的运作方式。不允许您更改底层数据而不经过粒度,这就是它的全部单点。如果你这样做了,你就破坏了奥尔良授予你的“单线程执行”承诺。

对我来说,您似乎仍然坚持旧的非演员模型思维方式。

对于 Orleans(或一般的 Actor 模式),grain 只需要通过 Actor 本身进行修改。只有这样才能得到保证。

同样,Actor 还充当一种热缓存,最近访问的 Actor 状态将保留在内存中,不需要任何数据库。这是可行的,因为grain 只由单个孤岛中的单个线程处理,这意味着状态不能被多个线程同时更改(因此不需要同步或锁定)。

“单线程执行”保证一个actor在任何给定时间都只会被一个线程执行。这使 Orleans 能够无限扩展,因为没有并发问题(但是,您仍然可以遇到死锁的谷物 A 尝试访问谷物 B,而谷物 B 尝试访问谷物 A 并且该方法未标记为可重入) .

...如何触发受影响的谷物重新激活?

当然,您可以在离线迁移(到新数据模型)的过程中重新启动 silo 集群,但我更愿意再次注意这一点,在粒度之外更改数据可能会破坏任何一致性并保证这样做是类不变的。在这种情况下,您需要关闭集群、更新/迁移现有数据、部署新版本的软件,然后使用更新后的模型启动集群。

或者,如果您的颗粒不保持任何状态(无状态),那么您可以在它们被停用后作为具有特定生存时间的无状态颗粒运行,并且它们的状态将在下次激活时更新。这在 Orleans 用作热缓存的场景中效果很好(即,用于运行搜索操作并将结果缓存一段时间以减少数据库命中)

【讨论】:

    猜你喜欢
    • 2021-06-10
    • 1970-01-01
    • 2019-01-05
    • 2021-10-21
    • 1970-01-01
    • 2020-11-10
    • 2016-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多