如果我必须在一组Orleans颗粒后面的持久层上执行操作,我如何确保这些受影响的颗粒可以根据更新的数据重新激活?
我的示例是,我在员工记录级别有一个粒度(EmployeeID作为粒度ID),并且我需要对一些记录执行批量操作。显然,重要的是我要确保在此操作后颗粒重新加载到那里的状态。
我已经使用grains创建了一个Orleans竖井来执行各种操作,包括员工变更操作。我正在使用GetGrain功能,如下所示
var employeeGrain = _clusterClient.GetGrain<IEmployeeGrain>(employeeId, "employee");在基于标准的Orleans生命周期使用时,此颗粒将保持活动状态。我的问题是,如果我故意执行更改底层数据的操作,我如何触发受影响的颗粒重新激活?
看起来你可以强迫一个单独的颗粒停用
this.DeactivateOnIdle()但是如果我做一个更大的操作,我会想要避免对每个颗粒执行这个操作?我猜理想的情况是回收所有特定类型的谷物。
发布于 2020-08-31 15:38:45
在基于标准的Orleans生命周期使用时,此颗粒将保持活动状态。我的问题是,如果我故意执行更改底层数据的操作...
我认为你没有完全理解Orleans是如何工作的。你不允许改变底层数据,而不是通过粒度,这就是它的全部单点。如果你这样做了,你就违背了Orleans给予你的“单线程执行”的承诺。
对我来说,你似乎仍然坚持旧的非演员模型的思维方式。
对于Orleans (或一般的角色模式),只需通过角色本身修改粒度。只有这样,才能给出这个保证。
此外,actors还充当一种热缓存,最近访问的actors状态将保留在内存中,不需要任何数据库。这之所以有效,是因为粒度仅由单个竖井中的单个线程处理,这意味着多线程不能同时更改状态(因此不需要同步或锁定)。
“单线程执行”保证了一个参与者在任何给定时间都只能由单个线程执行。这给了Orleans无限扩展的能力,因为没有并发问题(然而,你仍然可以得到颗粒A尝试访问颗粒B的死锁,而颗粒B试图访问颗粒A,并且该方法没有被标记为可重入)。
...如何触发受影响的颗粒重新激活?
当然,作为脱机迁移(到新的数据模型)的一部分,您可以重新启动思洛集群,但我更倾向于小心这一点,因为在粒度之外更改数据可能会破坏任何一致性和保证的类不变性。在这种情况下,您需要关闭集群,更新/迁移现有数据,部署新版本的软件,然后使用更新后的模型启动集群。
或者,如果你的颗粒没有持久化任何状态(无状态),那么你可以作为无状态颗粒运行,在它们被停用后具有特定的生存时间,并且它们的状态将在下一次激活时更新。这在将Orleans用作热缓存(即运行搜索操作并缓存结果以减少数据库命中率)的场景中工作得很好。
https://stackoverflow.com/questions/63610209
复制相似问题