Reliable Actors の状態管理
Reliable Actors は、ロジックと状態の両方をカプセル化できるシングル スレッド オブジェクトです。 アクターは Reliable Services 上で実行されるため、同じ永続化およびレプリケーション メカニズムを使用して、状態を確実に保持することができます。 このため、エラー後やガベージ コレクションに続く再アクティベーション時、リソース分散またはアップグレードのためにクラスター内のノード間を移動されたときでも、アクターは状態を失いません。
状態の永続性とレプリケーション
各アクター インスタンスは一意の ID にマッピングされるため、すべての Reliable Actors は、 ステートフル であると見なされます。 つまり、同じアクター ID を繰り返し呼び出すと、同じアクター インスタンスにルーティングされます。 一方ステートレス システムでは、クライアント呼び出しが常に同じサーバーにルーティングされるとは限りません。 このため、アクター サービスは常にステートフルなサービスです。
アクターをステートフルと見なすことができても、状態を確実に格納しているとは限りません。 アクターは、データ ストレージの要件に基づいて、次のような状態の永続性とレプリケーションのレベルを選択できます。
- 永続化状態:状態はディスクに永続化され、3 つ以上のレプリカにレプリケートされます。 永続化状態は、完全なクラスター停止があっても状態を永続化できる、最も持続性のある状態ストレージ オプションです。
- 揮発状態:状態は 3 つ以上のレプリカにレプリケートされ、メモリだけに保持されます。 揮発状態により、ノード障害時、アクター障害時、およびアップグレードとリソース分散中の回復力が得られます。 ただし、状態はディスクに保持されません。 従って、すべてのレプリカが同時に失われると状態も失われます。
- 非永続化状態:状態はレプリケートされず、ディスクにも書き込まれません。状態を確実に維持する必要がないアクターにのみ使用します。
永続性の各レベルは、単にサービスの状態プロバイダーとレプリケーション構成が異なるだけです。 状態がディスクに書き込まれるかどうかは、状態プロバイダーによって決まります。これは、状態を格納する Reliable Service のコンポーネントです。 またレプリケーションは、サービスがデプロイされるレプリカ数によって決まります。 Reliable Services と同様に、状態プロバイダーもレプリカ数も手動で簡単に設定できます。 アクター フレームワークは、属性を提供します。これはアクターに使用された場合、既定の状態プロバイダーとレプリカ数の自動生成設定を自動的に選択して、上記の 3 つの永続性設定のいずれかを実現します。 StatePersistence 属性は、派生クラスによって継承されません。各 Actor 型は、独自の StatePersistence レベルを提供する必要があります。
永続化状態
[StatePersistence(StatePersistence.Persisted)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
class MyActorImpl extends FabricActor implements MyActor
{
}
この設定は、ディスクにデータを格納する状態プロバイダーを使用し、自動的にサービス レプリカ数を 3 に設定します。
揮発状態
[StatePersistence(StatePersistence.Volatile)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.Volatile)
class MyActorImpl extends FabricActor implements MyActor
{
}
この設定は、メモリ内のみの状態プロバイダーを使用し、レプリカ数を 3 に設定します。
非永続化状態
[StatePersistence(StatePersistence.None)]
class MyActor : Actor, IMyActor
{
}
@StatePersistenceAttribute(statePersistence = StatePersistence.None)
class MyActorImpl extends FabricActor implements MyActor
{
}
この設定は、メモリ内のみの状態プロバイダーを使用し、レプリカ数を 1 に設定します。
既定値と生成される設定
StatePersistence
属性を使用する場合、状態プロバイダーはアクター サービスが開始される際に、ランタイムで自動的に選択されます。 ただし、レプリカ数は、コンパイル時に Visual Studio アクター ビルド ツールによって設定されます。 ビルド ツールは自動的にアクター サービスの既定のサービスを ApplicationManifest.xml 内に生成します。 最小レプリカ セット サイズとターゲット レプリカ セット サイズのために、パラメーターが作成されます。
これらのパラメーターは手動で変更できます。 ただしStatePersistence
属性が変更されるたびに、選択されたStatePersistence
属性の既定のレプリカ セット サイズ値にパラメーターは設定され、前の値はオーバーライドされます。 つまり、StatePersistence
属性の値を変更すると、ServiceManifest.xml に設定した値がビルド時のみにオーバーライドされます。
<ApplicationManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="Application12Type" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="MyActorService_PartitionCount" DefaultValue="10" />
<Parameter Name="MyActorService_MinReplicaSetSize" DefaultValue="3" />
<Parameter Name="MyActorService_TargetReplicaSetSize" DefaultValue="3" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyActorPkg" ServiceManifestVersion="1.0.0" />
</ServiceManifestImport>
<DefaultServices>
<Service Name="MyActorService" GeneratedIdRef="77d965dc-85fb-488c-bd06-c6c1fe29d593|Persisted">
<StatefulService ServiceTypeName="MyActorServiceType" TargetReplicaSetSize="[MyActorService_TargetReplicaSetSize]" MinReplicaSetSize="[MyActorService_MinReplicaSetSize]">
<UniformInt64Partition PartitionCount="[MyActorService_PartitionCount]" LowKey="-9223372036854775808" HighKey="9223372036854775807" />
</StatefulService>
</Service>
</DefaultServices>
</ApplicationManifest>
状態マネージャー
各アクター インスタンスは、独自の状態マネージャーを持ちます。これは、辞書のようなデータ構造で、キーと値のペアを確実に保持します。 状態マネージャーは、状態プロバイダーのラッパーです。 永続化設定の使用に関係なくデータの格納に使用できます。 データ保持中のローリング アップグレードを通じて、実行中のアクター サービスを揮発 (メモリ内のみ) 状態設定から永続化状態設定に変更できることは保証されません。 ただし、実行中のサービスのレプリカ数を変更することはできます。
状態マネージャー キーは、文字列でなければなりません。 値はジェネリックでカスタム型を含む任意のタイプです。 状態マネージャーに格納される値は、データ コントラクト シリアル化可能である必要があります。アクター状態の永続性設定によっては、これらの値がレプリケーション中にネットワーク経由で他のノードに送信されたり、ディスクに書き込まれたりする可能性があるためです。
状態マネージャーは、Reliable Dictionary に含まれているものと同様、状態管理のための一般的な辞書メソッドを公開します。
アクター状態の管理例については、「Reliable Actors 状態のアクセス、保存、および削除」を参照してください。
ベスト プラクティス
アクター状態の管理について推奨されるプラクティスとトラブルシューティングのヒントを次に示します。
アクターの状態はできるだけ詳細に定める
これは、アプリケーションのパフォーマンスとリソース使用率を高めるうえで非常に重要です。 アクターの "名前付き状態" に対する書き込み/更新があった場合は、その "名前付き状態" に対応する値全体がシリアル化され、ネットワーク経由でセカンダリ レプリカに送信されます。 セカンダリは、それをローカル ディスクに書き込み、プライマリ レプリカに返答します。 プライマリは、セカンダリ レプリカのクォーラムからの確認を受け取ると、状態をローカル ディスクに書き込みます。 たとえば、メンバーが 20 個、サイズが 1 MB のクラスの場合、 サイズが 1 KB のクラス メンバーを 1 つ変更しただけでも、1 MB 全体のシリアル化とネットワーク、およびディスク書き込みのコストを支払うことになります。 同様に、値がコレクション (リスト、配列、ディクショナリなど) の場合は、メンバーのいずれか 1 つを変更しただけでも、コレクション全体のコストを支払うことになります。 アクター クラスの StateManager インターフェイスは、ディクショナリのようなものです。 アクターの状態を表すデータ構造は、常にこのディクショナリの上にモデル化する必要があります。
アクターのライフ サイクルを正しく管理する
アクター サービスの各パーティションでの状態のサイズ管理については、明確なポリシーを定めるようにしてください。 アクター サービスでは、固定数のアクターを使用し、それらをできるだけ再利用するようにしてください。 新しいアクターを継続的に作成する場合は、それらを使い終わった後に、それらを削除する必要があります。 アクター フレームワークでは、存在する各アクターについてのメタデータが格納されます。 アクターのすべての状態を削除しても、そのアクターに関するメタデータが削除されることはありません。 アクターを削除 (「アクターとその状態を削除する」を参照) し、そのアクターに関するすべての情報をシステムから削除する必要があります。 追加のチェックとして、アクター サービスを定期的に照会 (「アクターの列挙」を参照) し、アクターの数が想定の範囲内であることを確認するようにしてください。
アクター サービスのデータベース ファイルのサイズが必要以上に大きくなっている場合は、前述のガイドラインに従っていることを確認してください。 これらのガイドラインに従ってもデータベース ファイル サイズの問題が解消されない場合は、サポート チケットを開いて製品チームに支援を要請してください。
次のステップ
Reliable Actors に格納される状態は、ディスクに書き込まれて、高可用性のためにレプリケートされる前に、シリアル化される必要があります。 Actor 型のシリアル化についてさらに学習してください。
次に、アクターの診断とパフォーマンスの監視についてさらに学習してください。