エラーと条件付き実行
適用対象: Azure Data Factory Azure Synapse Analytics
ヒント
企業向けのオールインワン分析ソリューション、Microsoft Fabric の Data Factory をお試しください。 Microsoft Fabric は、データ移動からデータ サイエンス、リアルタイム分析、ビジネス インテリジェンス、レポートまで、あらゆるものをカバーしています。 無料で新しい試用版を開始する方法について説明します。
条件付きパス
Azure Data Factory と Synapse パイプラインのオーケストレーションでは、条件付きロジックが許可され、ユーザーは前のアクティビティの結果に基づいて異なる道を進むことができます。 さまざまなパスを使用すると、ユーザーは堅牢なパイプラインを構築し、ETL/ELT ロジックにエラー処理を組み込むことができるようになります。 合計で 4 つの条件付きパスが利用できます。
名前 | 説明 |
---|---|
成功時 | (デフォルトのパス) 現在のアクティビティが成功した場合は、このパスを実行します |
失敗時 | 現在のアクティビティが失敗した場合は、このパスを実行します |
完了時 | 成功したかどうかに関係なく、現在のアクティビティが完了した後にこのパスを実行します |
スキップ時 | アクティビティ自体が実行されていない場合は、このパスを実行します |
アクティビティの後に複数のブランチを追加することもできますが、1 つの例外があります。"完了時" パスは、"成功時" または "失敗時" パスと共存できません。 パイプライン実行ごとに、アクティビティの実行結果に基づいて、最大 1 つのパスがアクティブになります。
エラー処理
一般的なエラー処理メカニズム
Try Catch ブロック
このアプローチでは、お客様はビジネス ロジックを定義し、前のアクティビティのエラーをキャッチする "失敗時" パスのみを定義します。 このアプローチでは、"失敗時" パスが成功した場合に、パイプラインが成功したことを示します。
Do If Else ブロック
このアプローチでは、お客様はビジネス ロジックを定義し、"失敗時" と"成功時" の両方のパスを定義します。 このアプローチでは、"失敗時" パスが成功しても、パイプラインが失敗したことを示します。
Do If Skip Else ブロック
このアプローチでは、顧客はビジネス ロジックを定義し、"失敗時" パスと、ダミーの "スキップ時" アクティビティが接続されている "成功時" パスの両方を定義します。 このアプローチでは、"失敗時" パスが成功した場合に、パイプラインが成功したことを示します。
概要テーブル
アプローチ | 定義 | アクティビティが成功した場合のパイプライン全体としての表示 | アクティビティが失敗した場合のパイプライン全体としての表示 |
---|---|---|---|
Try-Catch | "失敗時" パスのみ | 成功 | 成功 |
Do-If-Else | "失敗時" パスと "成功時" パス | Success | 障害 |
Do-If-Skip-Else | "失敗時" パスと、(最後に "ダミーのスキップ時" が付いた) "成功時" パス | 成功 | 成功 |
パイプラインの失敗の決定方法
さまざまなエラー処理メカニズムを使用すると、パイプラインはさまざまな状態になります。一部のパイプラインが失敗する一方で、他のものは成功します。 パイプラインの成功と失敗は、次のように決定します。
- すべてのリーフ アクティビティの結果を評価します。 リーフ アクティビティがスキップされた場合は、代わりにその親アクティビティを評価します
- パイプラインの結果は、評価対象のすべてのノードが成功した場合にのみ成功します
"失敗時" アクティビティと "ダミーのスキップ時" アクティビティが成功したと仮定します。
Try-Catch アプローチの場合、
- 前のアクティビティが成功したとき: ノード "失敗時" がスキップされ、その親ノードは成功します。パイプライン全体は成功します
- 前のアクティビティが失敗したとき: ノード "失敗時" が実行されます。パイプライン全体は成功します
Do-If-Else アプローチの場合、
- 前のアクティビティが成功したとき: ノード "成功時" が成功し、ノード "失敗時" はスキップされます (その親ノードは成功します)。パイプライン全体は成功します
- 前のアクティビティが失敗したとき: ノード "成功時" がスキップされ、その親ノードは失敗します。パイプライン全体は失敗します
Do-If-Skip-Else アプローチの場合、
- 前のアクティビティが成功したとき: ノード "ダミーのスキップ時" がスキップされ、その親ノードの "成功時" は成功します。その他のノード アクティビティ "失敗時" はスキップされ、その親ノードは成功します。パイプライン全体は成功します
- 前のアクティビティが失敗したとき: ノード "失敗時" が成功し、"ダミーのスキップ時" も成功します。パイプライン全体は成功します
条件付き実行
より複雑で回復力のあるパイプラインを開発するときに、特定の条件が満たされた場合にのみ特定のアクティビティを実行するという条件付き実行をロジックに導入することが必要になる場合があります。 ユース ケースは、次のように豊富にあります。
- 前のコピー ジョブが成功した場合に、メール通知の送信などのフォローアップ アクティビティを実行する
- 前のアクティビティのいずれかが失敗した場合にエラー処理ジョブを実行する
- アクティビティ自体またはその対応するエラー処理アクティビティのいずれかが成功した場合に次の手順に進む
- その他。
ここでは、いくつかの一般的なロジックと、それらを ADF に実装する方法について説明します。
1 つのアクティビティ
1 つのアクティビティに続く一般的なパターンを以降に示します。 これらのパターンを構成要素として使用して、複雑な作業フローを構築できます。
エラー処理
パターンは、ADF で最も一般的な条件ロジックです。 エラー処理アクティビティは "失敗時" パスに対して定義され、メイン アクティビティが失敗した場合に呼び出されます。 これは、フォールバックの代替手段またはログ記録を必要とするすべてのミッション クリティカルな手順に対してベスト プラクティスとして組み込む必要があります。
ベスト エフォートの手順
情報ログなどの特定の手順は重要度が低いため、エラーによってパイプライン全体がブロックされないようにする必要があります。 このような場合は、次の手順を "完了時" パスに追加して、ワークフローのブロックを解除するベスト エフォート戦略を採用する必要があります。
および
最初に挙げた最も一般的なシナリオは条件付き "and" です。前のアクティビティが成功した場合にのみパイプラインを続行します。 たとえば、データ処理の次のステージに進む前に、まず成功する必要がある複数のコピー アクティビティがあることが考えられます。 ADF では、動作を簡単に実現できます。次の手順に対する複数の依存関係を宣言します。 グラフィカル上は、次のアクティビティを指す複数の線を意味します。 依存関係が成功したことを確認する"成功時" パスと、ベスト エフォート実行を許可する "完了時" パスのいずれかを選択できます。
こちらでは、フォローアップ待機アクティビティは、両方の Web アクティビティが成功したときにのみ実行されます。
またこちらでは、フォローアップ待機アクティビティは、"ActivitySucceeded" が成功して "ActivityFailed" が完了したときに実行されます。 "成功時" パスがある "ActivitySucceeded" は成功する必要がありますが、"完了時" パスがある "ActivityFailed" はベスト エフォートで実行されます。つまり、失敗してもかまいません。
または
2 つめの一般的なシナリオは、条件付き "or" です。依存関係のいずれかが成功または失敗した場合にアクティビティを実行します。 ここでは、"完了時" パス、If Condition アクティビティ、および式言語を使用する必要があります。
コードについて詳しく説明する前に、もう 1 つ理解しておく必要があります。 アクティビティが実行されて完了した後、"@activity('ActivityName').Status" でその状態を参照できます。 これは、"成功"" または "失敗" になります。 このプロパティを使用して、条件付き OR ロジックを構築します。
共有エラー処理のログ記録手順
場合によっては、前のアクティビティのいずれかが失敗した場合に、共有エラー処理またはログ記録の手順を呼び出すことができます。 次のようなパイプラインを構築できます。
- 複数のアクティビティを並列で実行する
- エラー処理手順を含む If Conditionを True ブランチに追加する
- "完了時" パスを使用してアクティビティを条件アクティビティに接続する
- 条件アクティビティの論理式は次のようになります
@or(equals(activity('ActivityFailed').Status, 'Failed'), equals(activity('ActivitySucceeded').Status, 'Failed'))
- 注: 2 つを超える依存関係アクティビティがある場合は、or を連結する必要があります。例:
@or(or(equals(activity('ActivityFailed').Status, 'Failed'), equals(activity('ActivitySucceeded1').Status, 'Failed')),equals(activity('ActivitySucceeded1').Status, 'Failed'))
いずれかのアクティビティが成功した場合は青信号
すべてのアクティビティがベスト エフォートであるときは、前のアクティビティのいずれかが成功した場合に、次の手順に進むことができます。 次のようなパイプラインを構築できます。
- 複数のアクティビティを並列で実行する
- 次の手順を含む If Conditionを True ブランチに追加する
- "完了時" パスを使用してアクティビティを条件アクティビティに接続する
- 条件アクティビティの論理式は次のようになります
@or(equals(activity('ActivityFailed').Status, 'Succeeded'), equals(activity('ActivitySucceeded').Status, 'Succeeded'))
- 注: グラフの外見は、前のシナリオとまったく同じです。 唯一の違いは、使用される式言語です
複雑なシナリオ
進むにはすべてのアクティビティが成功する必要がある
パターンは、条件付き処理と + エラー処理の 2 つの組み合わせです。 パイプラインは、すべての続行アクティビティが成功した場合は次の手順に進み、それ以外の場合は、共有エラー ログ手順を実行します。 次のようなパイプラインを構築できます。
- 複数のアクティビティを並列で実行する
- If Condition を追加する。 True ブランチに次の手順を追加し、False ブランチにエラー処理コードを追加します
- "完了時" パスを使用してアクティビティを条件アクティビティに接続する
- 条件アクティビティの論理式は次のようになります
@and(equals(activity('ActivityFailed').Status, 'Succeeded'), equals(activity('ActivitySucceeded').Status, 'Succeeded'))
一般的なパターン
Try-Catch-Proceed
パターンは、コーディングの Try Catch ブロックと同等です。 パイプラインでアクティビティが失敗する可能性があります。 失敗した場合、お客様はエラー処理ジョブを実行して対処する必要があります。 ただし、単一のアクティビティ エラーによってパイプライン内の次のアクティビティがブロックされることはないはずです。 たとえば、ファイルをストレージに移動して、コピー ジョブを実行しようとしています。 ただし、途中で失敗する可能性があります。 その場合は、部分的にコピーされた信頼性の低いファイルをストレージ アカウントから削除します (エラー処理手順)。 しかし、後で他の活動を進めても大丈夫です。
パターンを設定するには:
- 最初のアクティビティを追加します
- UponFailure パスにエラー処理を追加します
- 2 番目のアクティビティを追加しますが、最初のアクティビティには接続しません
- エラー処理アクティビティから 2 番目のアクティビティに UponFailure パスと UponSkip パスの両方を接続します
Note
各パス (UponSuccess、UponFailure、UponSkip) は、任意のアクティビティを指すことができます。 複数のパスが同じアクティビティを指すことができます。 たとえば、UponSuccess と UponSkip はどちらも 1 つのアクティビティを指し、UponFailure は別のアクティビティを指すことができます。
エラー処理ジョブは、最初のアクティビティが失敗した場合にのみ実行されます。 次のアクティビティは、最初のアクティビティが成功したかどうかに関係なく実行されます。
汎用エラー処理
一般的に、パイプラインで複数のアクティビティが順番に実行されます。 いずれかでエラーが発生した場合は、エラー処理ジョブを実行して状態をクリアし、エラーをログに記録する必要があります。 たとえば、パイプラインにシーケンシャル コピー アクティビティがあります。 それらのいずれかが失敗した場合は、スクリプト ジョブを実行してパイプライン エラーをログに記録する必要があります。
パターンを設定するには:
- シーケンシャル データ処理パイプラインを構築する
- パイプラインの末尾に汎用エラー処理ステップを追加する
- 最後のアクティビティからエラー処理アクティビティに UponFailure パスと UponSkip パスの両方を接続します
最後の手順である汎用エラー処理は、前のアクティビティのいずれかが失敗した場合にのみ実行されます。 すべてが成功した場合には、実行されません。
エラー処理のために複数のアクティビティを追加できます。