状態管理について知る
グレインを使用してデータを保持する
グレインを使用する場合は、アプリケーションの再起動間、グレインの非アクティブ化間、その他の状況間でデータの安全を確保するために、状態の保持が必要となることがよくあります。 Orleans は、耐久性のあるフォールト トレラントなクラウドネイティブ アプリケーション向けに設計されています。
グレインでは、任意のストレージ プロバイダーで状態を保持するための名前付きデータ オブジェクトを定義できます。 ストレージ プロバイダーの例としては、従来の SQL データベース、各種の Azure サービス (Blob Storage など)、その他のクラウド リソース (Amazon DynamoDb など) があります。 これらのプロバイダーは、さまざまな NuGet パッケージを通じて提供されます。 Orleans には、独自のストレージ プロバイダーを追加するための拡張ポイントも用意されています。
グレイン状態 API
グレインでは、IPersistentState<TState> インターフェイス (TState
は格納するオブジェクトの種類) を使用して永続的状態が実装されます。 一般的なストレージ プロバイダーはユーザーに代わってこの実装を処理するため、このインターフェイスを直接実装する必要はほとんどありません。 ただし、基盤となるコントラクトを理解しておくと役に立ちます。これには次のメンバーが含まれます。
public interface IPersistentState<TState> where TState : new()
{
TState State { get; set; }
string Etag { get; }
Task ClearStateAsync();
Task WriteStateAsync();
Task ReadStateAsync();
}
このインターフェイスの 3 つのメソッドは、TState
オブジェクトの管理に役立ちます。
- ClearStateAsync: このメソッドは、ストレージでグレインの状態オブジェクトをクリアします。 ストレージ プロバイダーの性質によって動作が変わる場合があります。
- WriteStateAsync: このメソッドは、状態オブジェクトに加えられた変更を保持するために使用します。 状態オブジェクトのプロパティやデータに加えられた変更は、
WriteStateAsync
が呼び出されるまで自動的に保存されません。 - ReadStateAsync: このメソッドは、状態の値を他のコンポーネントに公開するために、グレインがアクティブ化されると自動的に呼び出されます。 ただし、最新のグレイン状態を再度読み取るために、このメソッドを明示的に呼び出すこともできます。
グレイン状態を操作する
状態を保持するオブジェクトを定義するには、オブジェクトをグレインのコンストラクターで宣言し、PersistentStateAttribute で修飾します。 この属性で修飾されたオブジェクトは、前述した API メソッドにアクセスできます。
PersistentStateAttribute
には 2 つのパラメーターを指定できます。
- Name: 状態オブジェクトの名前を定義します。
- StorageName: オブジェクトを保存するストレージ プロバイダーを定義します。
次の例では、UrlShortenerGrain
クラスでグレイン状態に KeyValuePair
オブジェクトを格納する方法を示します。 KeyValuePair
には、短縮されたエイリアスがキーとして格納され、元の完全な URL が値として格納されます。 このセットアップにより、両方の項目を必要とされるときにいつでも状態に格納でき、エイリアスを使用して簡単に取得できます。
public class UrlShortenerGrain : Grain, IUrlShortenerGrain
{
private readonly IPersistentState<KeyValuePair<string, string>> _cache;
public UrlShortenerGrain(
[PersistentState(
stateName: "url",
storageName: "urls")]
IPersistentState<KeyValuePair<string, string>> state)
{
_cache = state;
}
}
グレイン状態を構成する
グレイン状態オブジェクトをストレージに保持するには、まずサイロ ストレージ プロバイダーを構成する必要があります。 基本的な構成は UseOrleans
メソッド内の ISiloBuilder
で処理されます。 次の例では Azure Blob Storage にグレインを永続的に格納していますが、他にも多数のプロバイダーを使用できます。 ストレージ プロバイダーの name
プロパティが、グレインに挿入された状態オブジェクトの storageName
パラメーターと一致している必要があることに注意してください。
builder.Host.UseOrleans(siloBuilder =>
{
siloBuilder.UseLocalhostClustering();
siloBuilder.AddAzureBlobGrainStorage("urls",
// Recommended: Connect to Blob Storage using DefaultAzureCredential
options =>
{
options.ConfigureBlobServiceClient(
new Uri("https://<your-account-name>.blob.core.windows.net"),
new DefaultAzureCredential());
});
// Connect to Blob Storage using Connection strings
// options => options.ConfigureBlobServiceClient(connectionString));
});
Note
DefaultAzureCredential は、構成を Azure サービスに接続する方法として推奨されていて、可能な限り使用する必要があります。 このアプローチがセキュリティと管理の面でもたらす強力なメリットについては、マネージド ID の概要に関する記事で確認できます。 ただし、接続文字列を使用してサービスに接続するように Orleans を構成することもできます。 上の例では両方のアプローチを示しています。
1 つのグレインで複数のストレージ プロバイダーに状態オブジェクトを格納することができます。 たとえば、1 つの状態オブジェクトをメモリ内に格納し、もう 1 つの状態オブジェクトを Azure Table Storage や SQL Server に格納できます。