Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los granos pueden tener varios objetos de datos persistentes con nombre asociados. Estos objetos de estado se cargan desde el almacenamiento durante la activación de los granos para que estén disponibles durante las solicitudes. La persistencia de Grain utiliza un modelo de complemento extensible, permitiéndole utilizar proveedores de almacenamiento para cualquier base de datos. Este modelo de persistencia está diseñado para simplificar y no está pensado para cubrir todos los patrones de acceso a datos. Los granos también pueden acceder a las bases de datos directamente sin usar el modelo de persistencia de granos.
En el diagrama anterior, UserGrain tiene un estado perfil y un estado Cart , cada uno almacenado en un sistema de almacenamiento independiente.
Objetivos
- Admite varios objetos de datos persistentes con nombre por grano.
- Permitir varios proveedores de almacenamiento configurados, cada uno de los cuales puede tener una configuración diferente y respaldada por un sistema de almacenamiento diferente.
- Habilite a la comunidad para desarrollar y publicar proveedores de almacenamiento.
- Proporcione a los proveedores de almacenamiento control total sobre cómo almacenan los datos de estado detallados en el almacén de respaldo persistente. Corollary: Orleans no proporciona una solución completa de almacenamiento ORM, pero permite a los proveedores de almacenamiento personalizados admitir requisitos ORM específicos según sea necesario.
Paquetes
Puede encontrar Orleans proveedores de almacenamiento de grano en NuGet. Los paquetes mantenidos oficialmente incluyen:
- Microsoft.Orleans. Persistence.AdoNet: para bases de datos SQL y otros sistemas de almacenamiento compatibles con ADO.NET. Para obtener más información, consulte ADO.NET persistencia de grano.
- Microsoft.Orleans.Persistence.AzureStorage: para Azure Storage, incluyendo Azure Blob Storage y Azure Table Storage (a través de la API de Azure Table Storage). Para más información, consulte Persistencia de granos en Azure Storage.
- Microsoft.Orleans. Persistence.Cosmos: el proveedor de Azure Cosmos DB. Para más información, consulte Persistencia de granos de Azure Cosmos DB.
- Microsoft.Orleans. Persistence.DynamoDB: para Amazon DynamoDB. Para obtener más información, consulte Persistencia de granos de Amazon DynamoDB.
- Microsoft.Orleans. Persistence.Redis: para Redis. Para más información, consulte Persistencia de grano de Redis.
Interfaz de Programación de Aplicaciones (API)
Los granos interactúan con su estado persistente mediante IPersistentState<TState>, donde TState es el tipo de estado serializable:
public interface IPersistentState<TState> : IStorage<TState>
{
}
public interface IStorage<TState> : IStorage
{
TState State { get; set; }
}
public interface IStorage
{
string Etag { get; }
bool RecordExists { get; }
Task ClearStateAsync();
Task WriteStateAsync();
Task ReadStateAsync();
}
public interface IPersistentState<TState> where TState : new()
{
TState State { get; set; }
string Etag { get; }
Task ClearStateAsync();
Task WriteStateAsync();
Task ReadStateAsync();
}
Orleans inserta instancias de IPersistentState<TState> en el grano como parámetros de constructor. Puede anotar estos parámetros con un PersistentStateAttribute atributo para identificar el nombre del estado que se inserta y el nombre del proveedor de almacenamiento que lo proporciona. En el ejemplo siguiente se muestra esto insertando dos estados con nombre en el UserGrain constructor:
public class UserGrain : Grain, IUserGrain
{
private readonly IPersistentState<ProfileState> _profile;
private readonly IPersistentState<CartState> _cart;
public UserGrain(
[PersistentState("profile", "profileStore")] IPersistentState<ProfileState> profile,
[PersistentState("cart", "cartStore")] IPersistentState<CartState> cart)
{
_profile = profile;
_cart = cart;
}
public Task<string> GetNameAsync() => Task.FromResult(_profile.State.Name);
public async Task SetNameAsync(string name)
{
_profile.State.Name = name;
await _profile.WriteStateAsync();
}
}
Los distintos tipos de grano pueden usar proveedores de almacenamiento configurados diferentes, incluso si ambos son del mismo tipo (por ejemplo, dos instancias de proveedor de Azure Table Storage diferentes conectadas a diferentes cuentas de Azure Storage).
Estado de lectura
El estado del grano se lee automáticamente cuando se activa el grano, pero los granos son responsables de activar explícitamente la escritura de cualquier cambio en el estado del grano cuando sea necesario.
Si un grano desea volver a leer explícitamente su estado más reciente desde el almacén de respaldo, debe llamar al ReadStateAsync método . Esto vuelve a cargar el estado de grano del almacén persistente a través del proveedor de almacenamiento. La copia anterior en memoria del estado del grano se sobrescribe y se reemplaza cuando se completa el Task de ReadStateAsync.
Acceda al valor del estado mediante la State propiedad . Por ejemplo, el método siguiente accede al estado del perfil declarado en el código anterior:
public Task<string> GetNameAsync() => Task.FromResult(_profile.State.Name);
No es necesario llamar ReadStateAsync durante el funcionamiento normal; Orleans carga el estado automáticamente durante la activación. Sin embargo, puede usar ReadStateAsync para actualizar el estado modificado externamente.
Consulte la sección Modos de error a continuación para obtener más información sobre los mecanismos de control de errores.
Estado de escritura
Puede modificar el estado a través de la State propiedad . El estado modificado no se conserva automáticamente. En su lugar, decide cuándo conservar el estado llamando al WriteStateAsync método . Por ejemplo, el método siguiente actualiza una propiedad en State y conserva el estado actualizado:
public async Task SetNameAsync(string name)
{
_profile.State.Name = name;
await _profile.WriteStateAsync();
}
Conceptualmente, el Orleans entorno de ejecución toma una copia profunda del objeto de datos del estado del 'grain' para su uso durante cualquier operación de escritura. En segundo plano, el entorno de ejecución podría usar reglas de optimización y heurística para evitar realizar alguna o toda la copia profunda en determinadas circunstancias, siempre que se conserve la semántica de aislamiento lógico esperada.
Consulte la sección Modos de error a continuación para obtener más información sobre los mecanismos de control de errores.
Limpiar estado
El ClearStateAsync método borra el estado del grano en el almacenamiento. Dependiendo del proveedor, esta operación podría eliminar opcionalmente el estado de grano por completo.
Comienza
Antes de que un grano pueda usar la persistencia, debe configurar un proveedor de almacenamiento en el silo.
En primer lugar, configure proveedores de almacenamiento, uno para el estado del perfil y otro para el estado del carro:
El uso de DefaultAzureCredential con un punto final de URI es el enfoque recomendado para entornos de producción.
var tableEndpoint = new Uri(configuration["AZURE_TABLE_STORAGE_ENDPOINT"]!);
var blobEndpoint = new Uri(configuration["AZURE_BLOB_STORAGE_ENDPOINT"]!);
var credential = new DefaultAzureCredential();
var builder = Host.CreateApplicationBuilder();
builder.UseOrleans(siloBuilder =>
{
siloBuilder.AddAzureTableGrainStorage(
name: "profileStore",
configureOptions: options =>
{
options.TableServiceClient = new TableServiceClient(tableEndpoint, credential);
})
.AddAzureBlobGrainStorage(
name: "cartStore",
configureOptions: options =>
{
options.BlobServiceClient = new BlobServiceClient(blobEndpoint, credential);
});
});
using var host = builder.Build();
var host = new HostBuilder()
.UseOrleans(siloBuilder =>
{
siloBuilder.AddAzureTableGrainStorage(
name: "profileStore",
configureOptions: options =>
{
// Use JSON for serializing the state in storage
options.UseJson = true;
// Configure the storage connection key
options.ConnectionString =
"DefaultEndpointsProtocol=https;AccountName=data1;AccountKey=SOMETHING1";
})
.AddAzureBlobGrainStorage(
name: "cartStore",
configureOptions: options =>
{
// Use JSON for serializing the state in storage
options.UseJson = true;
// Configure the storage connection key
options.ConnectionString =
"DefaultEndpointsProtocol=https;AccountName=data2;AccountKey=SOMETHING2";
});
})
.Build();
Importante
Microsoft recomienda usar el flujo de autenticación más seguro disponible. Si se conecta a Azure SQL, el método de autenticación recomendado es Identidades administradas para recursos de Azure.
Ahora que ha configurado un proveedor de almacenamiento denominado "profileStore", puede acceder a este proveedor desde una unidad.
Puede agregar un estado persistente a un grano de dos maneras principales.
- Inyectando IPersistentState<TState> en el constructor del objeto 'grain'.
- Al heredar de Grain<TGrainState>.
La manera recomendada de agregar almacenamiento a un grano es insertar IPersistentState<TState> en el constructor del grano con un atributo asociado [PersistentState("stateName", "providerName")] . Para obtener más información sobre Grain<TGrainState>, consulte Using Grain<TGrainState> to add storage to a grain a continuación. El uso de Grain<TGrainState> sigue siendo compatible, pero se considera un método obsoleto.
Declare una clase para mantener el estado de su grano.
[Serializable]
public class ProfileState
{
public string Name { get; set; }
public Date DateOfBirth { get; set; }
}
Inserte IPersistentState<TState> en el constructor del grano:
public class UserGrainSimple : Grain, IUserGrain
{
private readonly IPersistentState<ProfileState> _profile;
public UserGrainSimple(
[PersistentState("profile", "profileStore")]
IPersistentState<ProfileState> profile)
{
_profile = profile;
}
public Task<string> GetNameAsync() => Task.FromResult(_profile.State.Name);
public async Task SetNameAsync(string name)
{
_profile.State.Name = name;
await _profile.WriteStateAsync();
}
}
Importante
El estado del perfil no se cargará en el momento en que se inserta en el constructor, por lo que acceder a él no es válido en ese momento. El estado se cargará antes de que se llame a OnActivateAsync.
Ahora que el grano tiene un estado persistente, puede agregar métodos para leer y escribir el estado:
public class UserGrainComplete : Grain, IUserGrain
{
private readonly IPersistentState<ProfileState> _profile;
public UserGrainComplete(
[PersistentState("profile", "profileStore")]
IPersistentState<ProfileState> profile)
{
_profile = profile;
}
public Task<string> GetNameAsync() => Task.FromResult(_profile.State.Name);
public async Task SetNameAsync(string name)
{
_profile.State.Name = name;
await _profile.WriteStateAsync();
}
}
Modos de falla para las operaciones de persistencia
Modos de fallo para las operaciones de lectura
Los errores devueltos por el proveedor de almacenamiento durante la lectura inicial de los datos de estado para un grano determinado producen un error en la operación de activación de ese grano. En tales casos, no habrá ninguna llamada al método de devolución de llamada de ciclo de vida de OnActivateAsync ese grano. La solicitud original al grano que provocó los errores de activación de vuelta al autor de la llamada, al igual que cualquier otro error durante la activación específica. Los errores detectados por el proveedor de almacenamiento al leer los datos de estado de un grain en particular dan lugar a una excepción de ReadStateAsyncTask. El grano puede elegir controlar o omitir la Task excepción, al igual que cualquier otro Task en Orleans.
Cualquier intento de enviar un mensaje a un grano que no se pudo cargar al iniciar el silo debido a una configuración de proveedor de almacenamiento que está faltante o incorrecta devuelve el error permanente BadProviderConfigException.
Modos de error para las operaciones de escritura
Los errores detectados por el proveedor de almacenamiento al escribir datos de estado para un grain específico dan lugar a una excepción lanzada por WriteStateAsyncTask. Normalmente, esto significa que la excepción de llamada de grain se devuelve al autor de la llamada del cliente, siempre que se WriteStateAsyncTask encadene correctamente en la devolución Task final de este método de grain. Sin embargo, en determinados escenarios avanzados, puede escribir código específico para controlar específicamente estos errores de escritura, al igual que controlar cualquier otro error.Task
Los granos que ejecutan el control de errores o el código de recuperación deben detectar excepciones o fallas WriteStateAsyncTask y no volver a lanzarlas, lo que significa que han controlado correctamente el error de escritura.
Recomendaciones
Uso de la serialización JSON u otro formato de serialización tolerante a versiones
El código evoluciona y esto suele incluir tipos de almacenamiento. Para dar cabida a estos cambios, configure un serializador adecuado.
Orleans A partir de la versión 7.0, puede configurar el serializador de almacenamiento de granos mediante la IGrainStorageSerializer interfaz. De forma predeterminada, el estado de grano se serializa mediante JSON (Newtonsoft.Json). Asegúrese de que, al desarrollar contratos de datos, todavía se pueden cargar los datos almacenados. Para más información, consulte Serializadores de almacenamiento de granos.
El código evoluciona y esto suele incluir tipos de almacenamiento. Para dar cabida a estos cambios, configure un serializador adecuado. Para la mayoría de los proveedores de almacenamiento, hay una UseJson opción o similar disponible para usar JSON como formato de serialización. Asegúrese de que, al desarrollar contratos de datos, todavía se pueden cargar los datos almacenados.
Uso de Grain<TGrainState> para agregar almacenamiento a un grano
Importante
El uso de Grain<TGrainState> para agregar almacenamiento a un grano se considera funcionalidad heredada. Agregue almacenamiento de grano usando IPersistentState<TState> como se ha descrito anteriormente.
Las clases de grano que heredan de Grain<TGrainState> (donde T es un tipo de datos de estado específico de la aplicación que necesita persistencia) tienen su estado cargado automáticamente desde el almacenamiento especificado.
Marque estos granos con una StorageProviderAttribute especificación de una instancia con nombre de un proveedor de almacenamiento que se usará para leer y escribir los datos de estado para este grano.
[StorageProvider(ProviderName = "store1")]
public class MyGrain : Grain<MyGrainState>, IMyGrain
{
public Task DoSomethingAsync() => Task.CompletedTask;
}
La Grain<TGrainState> clase base define los métodos siguientes para que las subclases llamen a:
public abstract class GrainBaseExample<TState>
{
protected virtual Task ReadStateAsync() { return Task.CompletedTask; }
protected virtual Task WriteStateAsync() { return Task.CompletedTask; }
protected virtual Task ClearStateAsync() { return Task.CompletedTask; }
}
El comportamiento de estos métodos corresponde a sus homólogos en IPersistentState<TState> definidos anteriormente.
Creación de un proveedor de almacenamiento
Hay dos partes en las API de persistencia de estado: la API expuesta al grano a través de IPersistentState<TState> o Grain<TGrainState>, y la API del proveedor de almacenamiento, centrada en IGrainStorage: los proveedores de almacenamiento de interfaz deben implementar.
/// <summary>
/// Interface to be implemented for a storage able to read and write Orleans grain state data.
/// </summary>
public interface ICustomGrainStorage
{
/// <summary>Read data function for this storage instance.</summary>
/// <param name="stateName">Name of the state for this grain</param>
/// <param name="grainId">Grain ID</param>
/// <param name="grainState">State data object to be populated for this grain.</param>
/// <typeparam name="T">The grain state type.</typeparam>
/// <returns>Completion promise for the Read operation on the specified grain.</returns>
Task ReadStateAsync<T>(
string stateName, GrainId grainId, IGrainState<T> grainState);
/// <summary>Write data function for this storage instance.</summary>
/// <param name="stateName">Name of the state for this grain</param>
/// <param name="grainId">Grain ID</param>
/// <param name="grainState">State data object to be written for this grain.</param>
/// <typeparam name="T">The grain state type.</typeparam>
/// <returns>Completion promise for the Write operation on the specified grain.</returns>
Task WriteStateAsync<T>(
string stateName, GrainId grainId, IGrainState<T> grainState);
/// <summary>Delete / Clear data function for this storage instance.</summary>
/// <param name="stateName">Name of the state for this grain</param>
/// <param name="grainId">Grain ID</param>
/// <param name="grainState">Copy of last-known state data object for this grain.</param>
/// <typeparam name="T">The grain state type.</typeparam>
/// <returns>Completion promise for the Delete operation on the specified grain.</returns>
Task ClearStateAsync<T>(
string stateName, GrainId grainId, IGrainState<T> grainState);
}
/// <summary>
/// Interface to be implemented for a storage able to read and write Orleans grain state data.
/// </summary>
public interface IGrainStorage
{
/// <summary>Read data function for this storage instance.</summary>
/// <param name="grainType">Type of this grain [fully qualified class name]</param>
/// <param name="grainReference">Grain reference object for this grain.</param>
/// <param name="grainState">State data object to be populated for this grain.</param>
/// <returns>Completion promise for the Read operation on the specified grain.</returns>
Task ReadStateAsync(
string grainType, GrainReference grainReference, IGrainState grainState);
/// <summary>Write data function for this storage instance.</summary>
/// <param name="grainType">Type of this grain [fully qualified class name]</param>
/// <param name="grainReference">Grain reference object for this grain.</param>
/// <param name="grainState">State data object to be written for this grain.</param>
/// <returns>Completion promise for the Write operation on the specified grain.</returns>
Task WriteStateAsync(
string grainType, GrainReference grainReference, IGrainState grainState);
/// <summary>Delete / Clear data function for this storage instance.</summary>
/// <param name="grainType">Type of this grain [fully qualified class name]</param>
/// <param name="grainReference">Grain reference object for this grain.</param>
/// <param name="grainState">Copy of last-known state data object for this grain.</param>
/// <returns>Completion promise for the Delete operation on the specified grain.</returns>
Task ClearStateAsync(
string grainType, GrainReference grainReference, IGrainState grainState);
}
Cree un proveedor de almacenamiento personalizado implementando esta interfaz y registrando esa implementación. Para obtener un ejemplo de una implementación del proveedor de almacenamiento existente, consulte AzureBlobGrainStorage.
Semántica del proveedor de almacenamiento
Un proveedor de almacenamiento Etag establecer un valor opaco específico del proveedor string () como parte de los metadatos del estado de 'grain' rellenados cuando se leyó el estado. Algunos proveedores pueden optar por dejar esto como null si no usaran Etag.
Cualquier intento de realizar una operación de escritura cuando el proveedor de almacenamiento detecte una Etag infracción de restricción debería resultar en un fallo de escritura con un error transitorio Task y encapsular la excepción de almacenamiento subyacente.
public class InconsistentStateException : OrleansException
{
public InconsistentStateException(
string message,
string storedEtag,
string currentEtag,
Exception storageException)
: base(message, storageException)
{
StoredEtag = storedEtag;
CurrentEtag = currentEtag;
}
public InconsistentStateException(
string storedEtag,
string currentEtag,
Exception storageException)
: this(storageException.Message, storedEtag, currentEtag, storageException)
{
}
/// <summary>The Etag value currently held in persistent storage.</summary>
public string StoredEtag { get; }
/// <summary>The Etag value currently held in memory, and attempting to be updated.</summary>
public string CurrentEtag { get; }
}
Cualquier otra condición de error de una operación de almacenamiento debe provocar que el resultado Task se interrumpa por una excepción que indique el problema de almacenamiento subyacente. En muchos casos, esta excepción se podría devolver al autor de la llamada que desencadenó la operación de almacenamiento al llamar a un método en el componente. Es importante tener en cuenta si el autor de la llamada puede deserializar esta excepción. Por ejemplo, es posible que el cliente no haya cargado la biblioteca de persistencia específica que contiene el tipo de excepción. Por este motivo, es aconsejable convertir excepciones en excepciones que se puedan propagar de nuevo al autor de la llamada.
Mapeo de datos
Los proveedores de almacenamiento individuales deben decidir cómo almacenar mejor el estado de grano: blob (varios formatos o formularios serializados) o las opciones obvias de columna por campo.
Registro de un proveedor de almacenamiento
El Orleans tiempo de ejecución resuelve un proveedor de almacenamiento del proveedor de servicios (IServiceProvider) cuando se crea un grano. El tiempo de ejecución resuelve una instancia de IGrainStorage. Si el proveedor de almacenamiento tiene un nombre (por ejemplo, mediante el atributo [PersistentState(stateName, storageName)]), se resuelve una instancia nombrada de IGrainStorage.
Para registrar una instancia nombrada de IGrainStorage, use el método de extensión AddSingletonNamedService siguiendo aquí el ejemplo del proveedor AzureTableGrainStorage.
Persistencia de grano de Redis
Redis es un almacén de datos en memoria popular que se puede usar para la persistencia de granularidad. Microsoft .Orleans. El paquete Persistence.Redis proporciona un proveedor de almacenamiento específico respaldado por Redis.
Configuración del almacenamiento de granos de Redis
Configure el almacenamiento de granos de Redis mediante el método de extensión AddRedisGrainStorage.
var builder = Host.CreateApplicationBuilder();
builder.UseOrleans(siloBuilder =>
{
siloBuilder.AddRedisGrainStorage(
name: "redis",
configureOptions: options =>
{
options.ConfigurationOptions = new ConfigurationOptions
{
EndPoints = { "localhost:6379" },
AbortOnConnectFail = false
};
});
});
using var host = builder.Build();
Para configurar Redis como proveedor de almacenamiento de grano predeterminado, use AddRedisGrainStorageAsDefault:
siloBuilder.AddRedisGrainStorageAsDefault(options =>
{
options.ConfigurationOptions = new ConfigurationOptions
{
EndPoints = { "localhost:6379" }
};
});
Opciones de almacenamiento de Redis
La RedisStorageOptions clase proporciona las siguientes opciones de configuración:
| Propiedad | Tipo | Description |
|---|---|---|
ConfigurationOptions |
ConfigurationOptions |
Configuración del cliente StackExchange.Redis. Obligatorio. |
DeleteStateOnClear |
bool |
Indica si se eliminará el estado de Redis cuando se llama a ClearStateAsync. El valor predeterminado es false. |
EntryExpiry |
TimeSpan? |
Hora de expiración opcional para las entradas. Establezca esto solo para entornos efímeros como pruebas, ya que puede provocar activaciones duplicadas. El valor predeterminado es null. |
GrainStorageSerializer |
IGrainStorageSerializer |
Serializador a utilizar para el estado granular. Por defecto, se utiliza el Orleans serializador. |
CreateMultiplexer |
Func<RedisStorageOptions, Task<IConnectionMultiplexer>> |
Fábrica personalizada para crear el multiplexor de conexiones de Redis. |
GetStorageKey |
Func<string, GrainId, RedisKey> |
Función personalizada para generar la clave de Redis para un grano. El formato predeterminado es {ServiceId}/state/{grainId}/{grainType}. |
Integración de .NET Aspire
Al usar .NET Aspire, puede integrar el almacenamiento de 'grain' de Redis con el recurso de Redis administrado por Aspire.
// In your AppHost project
var redis = builder.AddRedis("orleans-redis");
var orleans = builder.AddOrleans("cluster")
.WithGrainStorage("Default", redis);
builder.AddProject<Projects.OrleansServer>("silo")
.WithReference(orleans)
.WaitFor(redis);
// Register the Redis client with keyed services.
// Orleans providers look up resources by their keyed service name.
// builder.AddKeyedRedisClient("orleans-redis");
builder.UseOrleans(siloBuilder =>
{
siloBuilder.AddRedisGrainStorage(
name: "redis",
configureOptions: options =>
{
// Use the Aspire-provided connection string
var connectionString = builder.Configuration.GetConnectionString("orleans-redis");
options.ConfigurationOptions = ConfigurationOptions.Parse(connectionString!);
});
});
Para escenarios más avanzados, puede insertar directamente IConnectionMultiplexer mediante el CreateMultiplexer delegado:
// Register the Redis client with keyed services.
// Orleans providers look up resources by their keyed service name.
// builder.AddKeyedRedisClient("orleans-redis");
siloBuilder.AddRedisGrainStorage("redis");
siloBuilder.Services.AddOptions<Orleans.Persistence.RedisStorageOptions>("redis")
.Configure<IServiceProvider>((options, sp) =>
{
options.CreateMultiplexer = _ =>
{
// Resolve the IConnectionMultiplexer from DI (provided by Aspire)
return Task.FromResult(sp.GetRequiredService<IConnectionMultiplexer>());
};
});
Persistencia específica de Azure Cosmos DB
Azure Cosmos DB es una base de datos NoSQL y relacional totalmente administrada para el desarrollo de aplicaciones modernas. El Microsoft.Orleans.Persistence.Cosmos paquete proporciona un proveedor de almacenamiento de granos respaldado por Cosmos DB.
Configurar almacenamiento de granos de Cosmos DB
Instale el paquete NuGet Microsoft.Orleans.Persistence.Cosmos
dotnet add package Microsoft.Orleans.Persistence.Cosmos
Configurar el almacenamiento de granos de Cosmos DB utilizando el método de extensión AddCosmosGrainStorage
var builder = Host.CreateApplicationBuilder();
builder.UseOrleans(siloBuilder =>
{
siloBuilder.AddCosmosGrainStorage(
name: "cosmos",
configureOptions: options =>
{
options.ConfigureCosmosClient(
"https://myaccount.documents.azure.com:443/",
new DefaultAzureCredential());
options.DatabaseName = "Orleans";
options.ContainerName = "OrleansStorage";
options.IsResourceCreationEnabled = true;
});
});
Para configurar Cosmos DB como proveedor de almacenamiento predeterminado, use AddCosmosGrainStorageAsDefault.
siloBuilder.AddCosmosGrainStorageAsDefault(options =>
{
options.ConfigureCosmosClient(
"https://myaccount.documents.azure.com:443/",
new DefaultAzureCredential());
options.IsResourceCreationEnabled = true;
});
Opciones de almacenamiento de Cosmos DB
La CosmosGrainStorageOptions clase proporciona las siguientes opciones de configuración:
| Propiedad | Tipo | Predeterminado | Description |
|---|---|---|---|
DatabaseName |
string |
"Orleans" |
Nombre de la base de datos de Cosmos DB. |
ContainerName |
string |
"OrleansStorage" |
Nombre del contenedor para los datos de estado granular. |
IsResourceCreationEnabled |
bool |
false |
Cuando true, crea automáticamente la base de datos y el contenedor si no existen. |
DeleteStateOnClear |
bool |
false |
Indica si se va a eliminar el estado de Cosmos DB cuando se llama a ClearStateAsync. |
InitStage |
int |
ServiceLifecycleStage.ApplicationServices |
Fase del ciclo de vida del silo cuando se inicializa el almacenamiento. |
StateFieldsToIndex |
List<string> |
Vacío | Rutas de acceso JSON de propiedades de estado que se van a incluir en el índice de Cosmos DB. |
PartitionKeyPath |
string |
"/PartitionKey" |
La ruta de acceso JSON para la clave de partición en el contenedor. |
DatabaseThroughput |
int? |
null |
El rendimiento aprovisionado de la base de datos. Si null, usa el modo sin servidor. |
ContainerThroughputProperties |
ThroughputProperties? |
null |
Propiedades de rendimiento del contenedor. |
ClientOptions |
CosmosClientOptions |
new() |
Las opciones que se pasan al cliente de Cosmos DB. |
Proveedor de claves de partición personalizado
De forma predeterminada, Orleans usa el identificador de grano como clave de partición. En escenarios avanzados, puede implementar un proveedor de claves de partición personalizado:
public class MyPartitionKeyProvider : IPartitionKeyProvider
{
public ValueTask<string> GetPartitionKey(string grainType, GrainId grainId)
{
// Custom logic to determine partition key
return new ValueTask<string>(grainId.Key.ToString()!);
}
}
Registre el proveedor de claves de partición personalizado:
// Register with custom partition key provider
siloBuilder.AddCosmosGrainStorage<MyPartitionKeyProvider>(
name: "cosmos",
configureOptions: options =>
{
options.ConfigureCosmosClient("https://myaccount.documents.azure.com:443/", new DefaultAzureCredential());
});