Orleans grain 目录
grain 具有稳定的逻辑标识,并且在应用程序的整个生命周期内可以多次激活(实例化)和取消激活,但在任意时间点最多只能存在一个 grain 激活。 每次激活某个 grain 时,它可能被放置在群集中的不同 silo 上。 在群集中激活某个 grain 时,它将在全局注册表(grain 目录)中注册。 这可以确保后续对该 grain 的调用将传递给该 grain 激活,并且不会创建该 grain 的其他激活(实例)。 grain 目录负责保持 grain 标识与其当前激活所在位置(哪个 silo )之间的映射。
默认情况下,Orleans 使用内置的分布式内存中目录。 该目录最终是一致的,并以分布式哈希表的形式在群集中的所有 silo 之间进行分区。
从 3.2.0 开始,Orleans 还支持 grain 目录的可插式实现。
3.2.0 版本中包含两个这样的插件:
- Azure 表实现:Microsoft.Orleans.GrainDirectory.AzureStorage
- Redis 存储实现:Microsoft.Orleans.GrainDirectory.Redis
你可以根据每个 grain 的类型配置要使用的 grain 目录实现,甚至可以注入自己的实现。
应使用哪个 grain 目录?
我们建议始终从默认的目录(内置的内存中分布式目录)开始。 尽管此目录最终是一致的,并允许在群集不稳定时存在偶尔重复的激活,但内置目录是自给性的,没有任何外部依赖项,不需要任何配置,且一直在生产环境中使用。
如果对具有更强单激活保证的粒度目录有一定的经验 Orleans 和/或希望最大程度地减少群集中接收器关闭时停用的粒度数量,请考虑使用基于存储的粒度目录实现(例如 Redis 实现)。 首先尝试将它用于一种或少数几种 grain 类型,从那些生存期较长且具有大量状态或高开销初始化进程的类型开始。
配置
默认情况下,不必要面面俱到;内存中 grain 目录将在整个群集中自动使用和分区。 如果你想要使用非默认的 grain 目录配置,则需要指定要使用的目录插件的名称。 可以在 silo 配置期间,通过 grain 类的属性并使用依赖项注入以及具有该名称的目录插件来做到这一点。
Grain 配置
使用 GrainDirectoryAttribute 指定 grain 目录插件名称:
[GrainDirectory(GrainDirectoryName = "my-grain-directory")]
public class MyGrain : Grain, IMyGrain
{
// ...
}
Silo 配置
此处我们配置了 Redis grain 目录实现:
siloBuilder.AddRedisGrainDirectory(
"my-grain-directory",
options => options.ConfigurationOptions = redisConfiguration);
Azure grain 目录的配置方式如下:
siloBuilder.AddAzureTableGrainDirectory(
"my-grain-directory",
options => options.ConnectionString = azureConnectionString);
可以配置多个具有不同名称的目录以用于不同的 grain 类:
siloBuilder
.AddRedisGrainDirectory(
"redis-directory-1",
options => options.ConfigurationOptions = redisConfiguration1)
.AddRedisGrainDirectory(
"redis-directory-2",
options => options.ConfigurationOptions = redisConfiguration2)
.AddAzureTableGrainDirectory(
"azure-directory",
options => options.ConnectionString = azureConnectionString);