見出し画像

SnowflakeでFinalizerTask試してみた

分析屋の中田(ナカタ)です。
SnowflakeのFinalizer Taskを使ってみました。




Finalizer Taskとは

Finalizer Task | Snowflake Documentation

そもそも前提として、処理(SQL文やストアドプロシージャ等)を「タスク」として定義できて
複数のタスクを実行順に繋いだ全体を「DAG」と言います。
DAGを実行して、途中のタスクでエラーが発生した場合は
後続のタスクが実行されずDAGは停止します。

Finalizer Taskは、DAGの途中でエラーが発生したかどうかに関わらず
必ず最後に実行されるタスクのことです。
Pythonのエラーハンドリングで出てくるtry~except文のfinallyと同じイメージです。


今回やること

簡単なDAGを組んで、FinalizerTaskを使う場合と使わない場合の比較をします。
DAGの内容は以下の通りです。
Task1:INSERT文の実行
Task2:SELECT文の実行(ここでエラーを発生させます)
Task3:TRUNCATE文の実行(ここをFinalizerTaskにします)


環境

Snowflakeのエディション:エンタープライズ版
クラウド:AWS(東京リージョン)
※以降のクエリではデータベース名・スキーマ名を省略します。


事前準備

適当なテーブルを作っておきます。

CREATE OR REPLACE TABLE SAMPLE_LOG (
    COL1 INTEGER
);

SAMPLE_LOGテーブルを作りました。
整数型のCOL1という1列のみです。


①DAGの作成

作りたいタスクをおさらいします。
Task1:INSERT文の実行
Task2:SELECT文の実行(ここでエラーを発生させます)
Task3:TRUNCATE文の実行(ここをFinalizerTaskにします)

まずはFimalizerTaskを使わないパターンを試します。
以下のクエリを実行すると作成できます。

CREATE OR REPLACE TASK TASK1
  WAREHOUSE = COMPUTE_WH
  SCHEDULE = '1 MINUTE'
AS
INSERT INTO SAMPLE_LOG VALUES(1)
;

CREATE OR REPLACE TASK TASK2
  WAREHOUSE = COMPUTE_WH
  AFTER TASK1
AS
SELECT 1/0
;

CREATE OR REPLACE TASK TASK3
  WAREHOUSE = COMPUTE_WH
  AFTER TASK2
AS
TRUNCATE TABLE SAMPLE_LOG
;

TASK1は、1分おきにSAMPLE_LOGに1をINSERTするだけです。
後続のTASK2は、1/0をSELECTしますが、ここでゼロ除算エラーが発生します。
さらに後続のTASK3は、SAMPLE_LOGをTRUNCATEします。


②DAGの実行

以下のクエリを実行すると、タスクを実行可能な状態にします。

ALTER TASK TASK3 RESUME;
ALTER TASK TASK2 RESUME;
ALTER TASK TASK1 RESUME;

これで一番最初のタスク(ルートタスク)が1分おきにスケジュール実行されます。

数分間放置します...が、決して寝落ちすることのないよう。
ウェアハウスの課金がひたすら続いています。

適当なところで状況を確認してみます。
まずは手っ取り早くSAMPLE_LOGテーブルの中身を見てみます。

SELECT * FROM SAMPLE_LOG;

想定通りです!
TASK1で1行INSERTされ
TASK2でゼロ除算エラーが発生して、TASK3のTRUNCATEが働かなかったということが分かります。

TASKレベルでの履歴も見てみます。

SELECT
    NAME
    ,STATE
    ,ERROR_MESSAGE
FROM
    TABLE(INFORMATION_SCHEMA.TASK_HISTORY())
;

こちらも想定通りです。
TASK1とTASK2だけがひたすら繰り返されています。

いったん以下のクエリでDAGを停止します。

ALTER TASK TASK1 SUSPEND;
ALTER TASK TASK2 SUSPEND;
ALTER TASK TASK3 SUSPEND;


③Finalizer Taskの実装

続きまして、先程作ったタスクを元にFinalizerTaskを作ります。
変更はTASK3のみで、以下の通りです。

CREATE OR REPLACE TASK TASK3
  WAREHOUSE = COMPUTE_WH
  FINALIZE = TASK1
AS
TRUNCATE TABLE SAMPLE_LOG
;

AFTER TASK2 の部分を削除し、
FINALIZE = TASK1 に置き換えただけです。

上記のようにFinalizerTaskのCREATE文で、
FINALIZE = ルートタスク という書き方をします。


④再度、DAGの実行

改めて各タスクを有効にし、しばらく放置してみます。

ALTER TASK TASK3 RESUME;
ALTER TASK TASK2 RESUME;
ALTER TASK TASK1 RESUME;

数分後、テーブルの中身を確認してみます。

SELECT * FROM SAMPLE_LOG;

実行タイミング次第で、以下のいずれかになります。

想定通りの結果になりました。
TASK1で1がINSERTされ
TASK2でゼロ除算エラーが発生し
TASK3がFinalizerTaskとして実行されてTRUNCATEが働いています。

タスクの履歴も見てみます。

SELECT
    NAME
    ,STATE
    ,ERROR_MESSAGE
FROM
    TABLE(INFORMATION_SCHEMA.TASK_HISTORY())
;

TASK2は失敗しているものの、FinalizerTaskとしてTASK3が実行されています。

この間もタスクは毎分実行されっぱなしなので
きちんと停止させておきましょう。

ALTER TASK TASK1 SUSPEND;
ALTER TASK TASK2 SUSPEND;
ALTER TASK TASK3 SUSPEND;

各タスクの状況は以下のクエリで確認できます。

SHOW TASKS;


最後に

Finalizer Tasksという言葉はJava向けのビルドツール「Gradle」で出てきます。
ここが由来なのかどうかは不明ですが、こちらも同様の仕組みです。

Finalizer Taskでは例えば、処理の成否にかかわらず
テーブルの後始末を必ずさせたい場合などで使えそうです。




ここまでお読みいただき、ありがとうございました!
この記事が少しでも参考になりましたら「スキ」を押していただけると幸いです!

これまでの記事はこちら!


株式会社分析屋について

弊社が作成を行いました分析レポートを、鎌倉市観光協会様HPに掲載いただきました。

ホームページはこちら。

noteでの会社紹介記事はこちら。

【データ分析で日本を豊かに】
分析屋はシステム分野・ライフサイエンス分野・マーケティング分野の知見を生かし、多種多様な分野の企業様のデータ分析のご支援をさせていただいております。 「あなたの問題解決をする」をモットーに、お客様の抱える課題にあわせた解析・分析手法を用いて、問題解決へのお手伝いをいたします!

【マーケティング】
マーケティング戦略上の目的に向けて、各種のデータ統合及び加工ならびにPDCAサイクル運用全般を支援や高度なデータ分析技術により複雑な課題解決に向けての分析サービスを提供いたします。

【システム】
アプリケーション開発やデータベース構築、WEBサイト構築、運用保守業務などお客様の問題やご要望に沿ってご支援いたします。

【ライフサイエンス】
機械学習や各種アルゴリズムなどの解析アルゴリズム開発サービスを提供いたします。過去には医療系のバイタルデータを扱った解析が主でしたが、今後はそれらで培った経験・技術を工業など他の分野の企業様の問題解決にも役立てていく方針です。

【SES】
SESサービスも行っております。


この記事が参加している募集

#やってみた

36,993件

#企業のnote

with note pro

12,529件