更新ポリシーの概要
更新ポリシーは、新しいデータがテーブルに書き込まれるときにトリガーされる自動化メカニズムです。 取り込まれたデータを変換し、結果を変換先テーブルに保存するクエリを実行することで、特別なオーケストレーションが不要になります。 1 つのテーブルに複数の更新ポリシーを定義できるため、異なる変換を行い、データを複数のテーブルに同時に保存できます。 ターゲット テーブルには、ソース テーブルとは異なるスキーマ、アイテム保持ポリシー、およびその他のポリシーを含めることができます。
たとえば、高速トレース ソース テーブルには、フリーテキスト列として形式設定されたデータを含めることができます。 ターゲット テーブルには、parse 演算子を使用してソース テーブルのフリーテキスト データの変換から生成され、適切に構造化されたスキーマに従って、特定のトレース行を含めることができます。 詳細については、 common シナリオ。
次の図は、更新ポリシーの概要を示しています。 2 番目のソース テーブルにデータが追加されたときにトリガーされる 2 つの更新ポリシーが表示されます。 トリガーされると、変換されたデータが 2 つのターゲット テーブルに追加されます。
更新ポリシーには、通常のインジェストと同じ制限とベスト プラクティスが適用されます。 ポリシーはクラスターのサイズに応じてスケールアウトされ、一括インジェストを処理する場合に効率が向上します。
更新ポリシーには、通常のインジェストと同じ制限とベスト プラクティスが適用されます。 このポリシーは Eventhouse のサイズに応じてスケールアウトされ、一括インジェストを処理する場合の効率が向上します。
Note
- ソースとターゲット テーブルは、同じデータベース内にある必要があります。
- 更新ポリシー関数スキーマとターゲット テーブル スキーマは、列名、型、順序で一致している必要があります。
- 更新ポリシー関数は、他のデータベースのテーブルを参照できます。 これを行うには、更新ポリシーを
ManagedIdentity
プロパティで定義する必要があり、マネージド ID は参照先データベースにviewer
role する必要があります。 形式設定されたデータを取り込む際は、パフォーマンスが向上します。CSV が推奨されます。これは形式が適切に定義されているためです。 ただし、データの形式を制御できない場合や、データベース内の静的ディメンション テーブルとレコードを結合するなどして、取り込まれたデータを強化したい場合があります。
更新ポリシーのクエリ
更新ポリシーがターゲット テーブルで定義されている場合、ソース テーブルに取り込まれているデータに対して複数のクエリを実行できます。 複数の更新ポリシーがある場合、実行順序は必ずしもわかっていません。
クエリの制限事項
- ポリシー関連のクエリでは、ストアド関数を呼び出すことができますが、次のことができます。
- クラスター間クエリを実行することはできません。
- 外部データや外部テーブルにはアクセスできません。
- (プラグインを使用して) 吹き出しを作成することはできません。
- クエリには、 RestrictedViewAccess ポリシーが有効になっているテーブル に対する読み取りアクセス権がありません。
- ストリーミング インジェストにおける更新ポリシーの制限については、ストリーミング インジェストの制限事項に関するセクションを参照してください。
- ポリシー関連のクエリでは、ストアド関数を呼び出すことができますが、次のことができます。
- クロスイベントハウス クエリを実行することはできません。
- 外部データや外部テーブルにはアクセスできません。
- (プラグインを使用して) 吹き出しを作成することはできません。
- クエリには、 RestrictedViewAccess ポリシーが有効になっているテーブル に対する読み取りアクセス権がありません。
- 既定では、Eventhouse 内のすべてのテーブルに対して、ストリーミング インジェスト ポリシー が有効になっています。 更新ポリシーで
join
オペレーターと共に関数を使用するには、ストリーミング インジェスト ポリシーを無効にする必要があります。.alter
table
TableNamepolicy
streamingingestion
PolicyObject コマンドを使用して無効にします。
警告
クエリが正しくないと、ソース テーブルへのデータ インジェストが妨げる可能性があります。 クエリ結果とソース テーブルと変換先テーブルのスキーマの互換性だけでなく、制限により、ソース テーブルへのデータ インジェストを防ぐクエリが正しくない可能性があることに注意してください。
これらの制限は、ポリシーの作成と実行中に検証されますが、クエリが参照する可能性のある任意のストアド関数が更新される場合は検証されません。 そのため、更新ポリシーがそのまま残るように注意して変更を加える必要があります。
ポリシーの Source
部分、または Query
部分によって参照されている関数内で Query
テーブルを参照する場合:
- テーブルの修飾名を使用しないでください。 代わりに
TableName
を使用してください。 -
database("<DatabaseName>").TableName
もcluster("<ClusterName>").database("<DatabaseName>").TableName
も使用しないでください。
- テーブルの修飾名を使用しないでください。 代わりに
TableName
を使用してください。 -
database("<DatabaseName>").TableName
もcluster("<EventhouseName>").database("<DatabaseName>").TableName
も使用しないでください。
更新ポリシー オブジェクト
テーブルには、0 個以上の更新ポリシー オブジェクトを関連付けることができます。 そうした各オブジェクトは、次のプロパティが定義された JSON プロパティ バッグとして表されます。
プロパティ | タイプ | 説明 |
---|---|---|
IsEnabled | bool |
更新ポリシーが有効 (true) か、無効 (false) かを示す状態 |
ソース | string |
更新ポリシーの呼び出しをトリガーするテーブルの名前 |
クエリ | string |
更新用のデータを生成するために使用されるクエリ |
IsTransactional | bool |
更新ポリシーがトランザクションであるかどうかを示します。既定値は false です。 ポリシーがトランザクションであり、更新ポリシーが失敗した場合、ソース テーブルは更新されません。 |
PropagateIngestionProperties | bool |
ソース テーブルへのインジェスト中に指定されたプロパティ ( 拡張タグ 作成時刻など) がターゲット テーブルに適用される場合の状態。 |
ManagedIdentity | string |
更新ポリシーが実行されるマネージド ID。 マネージド ID には、オブジェクト ID または system 予約語を指定できます。 更新ポリシーは、クエリが有効な 行レベルのセキュリティ ポリシーを持つ他のデータベースまたはテーブル内のテーブルを参照する場合に、マネージド ID で構成する必要があります。 詳細については、「 マネージド ID を使用して更新ポリシーを実行するを参照してください。 |
Note
実稼働システムでは、一時的な障害により、ターゲット テーブルでデータが失われないようにするために、IsTransactional
true を設定します。
Note
テーブル A からテーブル B へ、テーブル C へなどのカスケード更新は許可されます。ただし、更新ポリシーが循環的な方法で定義されている場合は、実行時にこれが検出され、更新のチェーンが切断されます。 データは、チェーン内の各テーブルに 1 回だけ取り込まれます。
管理コマンド
更新ポリシー管理コマンドは次のとおりです。
-
.show table *TableName* policy update
では、テーブルの現在の更新ポリシーが表示されます。 -
.alter table *TableName* policy update
では、テーブルの現在の更新ポリシーが定義されます。 -
.alter-merge table *TableName* policy update
では、テーブルの現在の更新ポリシーの定義が追加されます。 -
.delete table *TableName* policy update
では、テーブルの現在の更新ポリシーが削除されます。
更新ポリシーはインジェスト後に開始される
更新ポリシーは、データが取り込まれたりソース テーブルに移動されたり、ソース テーブルにエクステントが作成されたりしたときに有効になります。 これらのアクションは、次のいずれかのコマンドを使用して実行できます。
- .ingest (プル)
- .ingest (インライン)
- .set | .append | .set-or-append | .set-or-replace
- .move extents
-
.replace extents
-
PropagateIngestionProperties
コマンドは、インジェスト操作の場合にのみ有効になります。.move extents
または.replace extents
コマンドの一環として更新ポリシーがトリガーされた場合、このオプションは無効です。
-
警告
.set-or-replace
コマンドの一環として更新ポリシーが呼び出された場合、既定では、派生テーブルのデータはソース テーブルと同じ方法で置き換えられます。
replace
コマンドが呼び出された場合、更新ポリシーのリレーションシップが設定されているすべてのテーブルでデータが失われる可能性があります。
代わりに .set-or-append
を使用することを検討してください。
ソース テーブルからデータを削除する
ターゲット テーブルにデータを取り込んだ後は、必要に応じてソース テーブルからデータを削除できます。 ソース テーブルの0sec
で論理的な削除期間を 00:00:00
(または ) に、さらに更新ポリシーをトランザクションとして設定します。 次の条件が適用されます。
- ソース テーブルからソース データに対してクエリを実行することはできません
- インジェスト操作の一環としてソース データが永続ストレージに保持されることはありません
- 操作パフォーマンスが向上します。 ソース テーブルのエクステントに対するバックグラウンド グルーミング操作のために、インジェスト後のリソースが削減されます。
Note
ソース テーブルの論理的な削除期間が 0sec
(または 00:00:00
) の場合、このテーブルを参照するすべての更新ポリシーはトランザクションである必要があります。
パフォーマンスへの影響
更新ポリシーはパフォーマンスに影響を与える可能性があり、データ エクステントのインジェストにはターゲット テーブルの数が乗算されます。 ポリシー関連のクエリを最適化することが重要です。 更新ポリシーのパフォーマンスへの影響をテストするには、ポリシーを作成または変更する前に既に存在するエクステントに対して、またはクエリで使用される関数に対してポリシーを呼び出します。
リソースの使用状況を評価する
.show queries
と次のパラメーターを使用して、リソースの使用状況 (CPU、メモリなど) を評価します。
-
Source
プロパティ (ソース テーブル名) をMySourceTable
として設定します -
Query
という名前の関数を呼び出すようにMyFunction()
プロパティを設定します
// '_extentId' is the ID of a recently created extent, that likely hasn't been merged yet.
let _extentId = toscalar(
MySourceTable
| project ExtentId = extent_id(), IngestionTime = ingestion_time()
| where IngestionTime > ago(10m)
| top 1 by IngestionTime desc
| project ExtentId
);
// This scopes the source table to the single recent extent.
let MySourceTable =
MySourceTable
| where ingestion_time() > ago(10m) and extent_id() == _extentId;
// This invokes the function in the update policy (that internally references `MySourceTable`).
MyFunction
トランザクション設定
更新ポリシー IsTransactional
設定では、更新ポリシーがトランザクションであり、ポリシー更新の動作に影響を与える可能性があるかどうかを次のように定義します。
-
IsTransactional:false
: 値が既定値 ( false に設定されている場合、更新ポリシーでは、ソース テーブルとターゲット テーブル内のデータの整合性は保証されません。 更新ポリシーが失敗した場合、データはソース テーブルにのみ取り込まれますが、ターゲット テーブルには取り込まれません。 このシナリオでは、インジェスト操作は成功します。 -
IsTransactional:true
: 値が true に設定されている場合、この設定により、ソース テーブルとターゲット テーブル内のデータの一貫性が保証されます。 更新ポリシーが失敗した場合、データはソース テーブルまたはターゲット テーブルに取り込まれません。 このシナリオでは、インジェスト操作は失敗します。
エラー処理
ポリシーの更新が失敗した場合、 IsTransactional
の設定が true
か false
かに基づいて処理が異なります。 更新ポリシーの失敗の一般的な理由は次のとおりです。
- クエリ出力スキーマとターゲット テーブルが一致していません。
- クエリ エラー。
.show ingestion failures
コマンドを使用してポリシー更新エラーを表示できます。それ以外の場合は、手動でインジェストを再試行できます。
.show ingestion failures
| where FailedOn > ago(1hr) and OriginatesFromUpdatePolicy == true
抽出、変換、読み込みの例
更新ポリシー設定を使用して、抽出、変換、読み込み (ETL) を実行できます。
この例では、単純な関数で更新ポリシーを使用して ETL を実行します。 まず、2 つのテーブルを作成します。
- ソース テーブル - データを取り込む 1 つの文字列型の列が含まれています。
- ターゲット テーブル - 目的のスキーマが含まれています。 このテーブルには更新ポリシーが定義されています。
ソース テーブルを作成しましょう。
.create table MySourceTable (OriginalRecord:string)
次に、ターゲット テーブルを作成します。
.create table MyTargetTable (Timestamp:datetime, ThreadId:int, ProcessId:int, TimeSinceStartup:timespan, Message:string)
その後、データを抽出する関数を作成します。
.create function with (docstring = 'Parses raw records into strongly-typed columns', folder = 'UpdatePolicyFunctions') ExtractMyLogs() { MySourceTable | parse OriginalRecord with "[" Timestamp:datetime "] [ThreadId:" ThreadId:int "] [ProcessId:" ProcessId:int "] TimeSinceStartup: " TimeSinceStartup:timespan " Message: " Message:string | project-away OriginalRecord }
ここで、作成した関数を呼び出すように更新ポリシーを設定します。
.alter table MyTargetTable policy update @'[{ "IsEnabled": true, "Source": "MySourceTable", "Query": "ExtractMyLogs()", "IsTransactional": true, "PropagateIngestionProperties": false}]'
データがターゲット テーブルに取り込まれた後にソース テーブルを空にするために、ソース テーブルにアイテム保持ポリシーを定義して、その
SoftDeletePeriod
として 0s を設定します。.alter-merge table MySourceTable policy retention softdelete = 0s