Durable Functions でのデータの永続化とシリアル化 (Azure Functions)
Durable Functions ランタイムは、信頼性の高い実行を提供するために、関数のパラメーター、戻り値、およびその他の状態を タスク ハブ に自動的に永続化します。 ただし、永続的なストレージに永続化されるデータの量と頻度は、アプリケーションのパフォーマンスとストレージ トランザクションのコストに影響を与える可能性があります。 アプリケーションで格納されるデータの種類によっては、データ保有とプライバシー ポリシーも考慮する必要があります。
タスク ハブの内容
タスク ハブには、インスタンスの現在の状態と保留中のメッセージが格納されます。
- インスタンスの状態 には、インスタンスの現在の状態と履歴が格納されます。 オーケストレーション インスタンスの場合、この状態にはランタイム状態、オーケストレーションの履歴、入力、出力、カスタム状態が含まれます。 エンティティ インスタンスの場合、エンティティの状態が含まれます。
- "メッセージ" には、関数の入力または出力、イベント ペイロード、ルーティングやエンド ツー エンドの関連付けなどの内部目的で使用するメタデータが格納されます。
メッセージは処理後に削除されますが、インスタンスの状態は、アプリケーションまたはオペレーターによって明示的に削除されない限り保持されます。 特に、オーケストレーションの完了後も、オーケストレーションの履歴はストレージに残ります。
状態とメッセージがオーケストレーションの進行状況を表す方法の例については、 タスク ハブの実行例を参照してください。
ストレージ内の状態とメッセージを表す場所と方法は、 ストレージ プロバイダーによって異なります。 Durable Functions の既定のプロバイダーは、指定した Azure Storage アカウントのキュー、テーブル、BLOB にデータが永続化される Azure Storage です。
シリアル化および永続化されるデータの種類
次の一覧に、Durable Functions の機能の使用時にシリアル化および永続化されるさまざまな種類のデータを示します。
- すべての ID とハンドルされない例外を含む、オーケストレーター、アクティビティ、およびエンティティ関数のすべての入力と出力
- オーケストレーター、アクティビティ、およびエンティティ関数の名前
- 外部イベントの名前とペイロード
- カスタム オーケストレーションの状態ペイロード
- オーケストレーションの終了メッセージ
- 持続的タイマー ペイロード
- 持続的な HTTP 要求と応答の URL、ヘッダー、およびペイロード
- エンティティの呼び出しとシグナル ペイロード
- エンティティ状態ペイロード
機密性の高いデータの使用
Azure Storage プロバイダーの使用中は、すべてのデータが保存時に自動的に暗号化されます。 ただし、ストレージ アカウントへのアクセス権を持つユーザーは、暗号化されていない形式でデータを読み取ることができます。 機密データのより強力な保護が必要な場合は、事前に暗号化された形式でデータが永続化されるように、最初に独自の暗号化キーを使用してデータを暗号化することを検討してください。
また、.NET ユーザーは、自動暗号化を提供するカスタムのシリアル化プロバイダーを実装することもできます。 暗号化を使用したカスタムのシリアル化の例については、この GitHub のサンプルを参照してください。
Note
アプリケーション レベルの暗号化を実装する場合は、オーケストレーションとエンティティが無期限に存在する可能性があることに注意してください。 オーケストレーションまたはエンティティはキーのローテーション ポリシーよりも長く実行される可能性があるため、暗号化キーをローテーションするときにこれが重要になります。 キーのローテーションが行われると、データの暗号化に使用されたキーが、次にオーケストレーションまたはエンティティを実行したときに復号化できなくなる可能性があります。 このため、ユーザー暗号化は、オーケストレーションとエンティティの実行時間が比較的短い場合にのみ推奨されます。
シリアル化と逆シリアル化のカスタマイズ
既定のシリアル化のロジック
.NET 用 Durable Functions のインプロセスでは、内部で Json.NET を使用して、オーケストレーションとエンティティのデータを JSON にシリアル化します。 使用される既定の Json.NET 設定は次のとおりです。
入力、出力、および状態:
JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.None,
DateParseHandling = DateParseHandling.None,
}
例外:
JsonSerializerSettings
{
ContractResolver = new ExceptionResolver(),
TypeNameHandling = TypeNameHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}
JsonSerializerSettings
に関する詳細なドキュメントについては、こちらを参照してください。
.NET 属性を使用したシリアル化のカスタマイズ
シリアル化時に、Json.NET では、データのシリアル化と JSON からの逆シリアル化の方法を制御するクラスおよびプロパティのさまざまな属性を検索します。 Durable Functions API に渡されるデータ型のソース コードを所有している場合は、シリアル化と逆シリアル化をカスタマイズするために、これらの属性を型に追加することを検討してください。
依存関係の挿入によるシリアル化のカスタマイズ
.NET を対象とする Functions 3 ランタイムで実行される関数アプリでは、依存関係の挿入 (DI) を使用して、データと例外をシリアル化する方法をカスタマイズできます。 次のサンプル コードは、DI を使用して、IMessageSerializerSettingsFactory
および IErrorSerializerSettingsFactory
サービス インターフェイスのカスタム実装を使用して既定の Json.NET シリアル化設定をオーバーライドする方法を示しています。
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;
[assembly: FunctionsStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializerSettingsFactory>();
builder.Services.AddSingleton<IErrorSerializerSettingsFactory, CustomErrorSerializerSettingsFactory>();
}
/// <summary>
/// A factory that provides the serialization for all inputs and outputs for activities and
/// orchestrations, as well as entity state.
/// </summary>
internal class CustomMessageSerializerSettingsFactory : IMessageSerializerSettingsFactory
{
public JsonSerializerSettings CreateJsonSerializerSettings()
{
// Return your custom JsonSerializerSettings here
}
}
/// <summary>
/// A factory that provides the serialization for all exceptions thrown by activities
/// and orchestrations
/// </summary>
internal class CustomErrorSerializerSettingsFactory : IErrorSerializerSettingsFactory
{
public JsonSerializerSettings CreateJsonSerializerSettings()
{
// Return your custom JsonSerializerSettings here
}
}
}
}