OpenMetadataでRedshiftのクエリログからリネージュを作成する

2023.10.16

OpenMetadataではデータリネージュ(データの流れ)を可視化できます。 Redshiftではクエリのログを読み込むことでそこから自動的にリネージュ情報を作ることができます。 その流れをやっていこうと思います。

Redshiftのユーザについて

OpenMetadataを利用する際はスーパーユーザではないユーザを利用するべきです。 OpenMetadataはデータカタログなので原則Redshift内の実データ書き換えは発生しません。 発生してしまったらかなり怖いです。 よってスーパーユーザの権限はそもそも必要なく、 また、もしも想定外に書き換えがあった時にはきちんと禁止されるように一般のリードオンリーユーザを作成して行います。

また別の理由として、スーパーユーザでは全てのデータにアクセスができてしまい、 Redshift Spectrumを利用するテーブルに対してもクエリをかけることができてしまいます。 今回は無関係なのですが、 OpenMetadataではデータのプロファイル情報を得るためにテーブルの全件を取得するような設定が可能です。 普通のDBであればこれは特に問題はないのですが、 Spectrumのようにデータスキャン量に応じて課金が発生する場合、 課金額が想定外に膨れる可能性もあります。

Redshiftのユーザ準備

新しいユーザcatalog_userを作成します。 publicスキーマと、その中にあるテーブル全てにselectの権限を付与します。

CREATE USER catalog_user WITH PASSWORD 'Passw0rd';
grant usage on schema public to catalog_user;
grant select on all tables in schema public to catalog_user;

ユーザが作られました。 pg_userでユーザ情報を確認してみます。 usesuperがfalseになっているので、このユーザはsuperユーザではないです。

このユーザを使ってOpenMetadataからRedshiftに接続します。 具体的に接続する方法は以前の記事を参照してください。

catalog_userで接続しようとすると、 接続テストでいくつか警告が出ます。

SVV_TABLE_INFOpg_catalog.svv_table_info pg_catalog.stl_queryが見れる必要があると言っています。 裏を返せば、この辺のテーブルを見てメタデータの情報を取得していることがわかります。

これらを実際にRedshiftで見れるのか確認してみると、やはり見ることができません。

ERROR: permission denied for relation svv_table_info

これらのテーブルをcatalog_userでも見れるように権限を追加します。

grant select on svv_table_info to catalog_user;
grant select on pg_catalog.svv_table_info to catalog_user;
grant select on pg_catalog.stl_query to catalog_user;

これでテストを全てパスしました!

OpenMetadataのLineageIngestion

次にLineage情報の取得をしていきます。 LineageIngestionを追加してそのジョブを動かせば取得ができるはずです。 とは言っても、DBとの接続を作ったら最初はMetadataの取得をしなければ他のIngestionは追加できませんので、 はMetadataの取得は完了している前提です。

ではLineageIngestionを作っていきます。 「Add Lineage Ingestion」をクリックします。

各種設定です。 「Query Log Duration」の項目はよく理解して設定しましょう。 画面右に解説が出てきますが、これは何日前以降のクエリ履歴を参照するかを指定します。 本番環境を見る場合は日次でETLジョブが流れるようなケースが多いので1が良いと思いますが、 今回のような検証用途ですと日次での定期的なクエリ実行などは行われていないことが多いですので、ここは大きめな値にしておきましょう。 今回は30にしました。

Enable Debug Logは有効にしておいた方が問題が起きた時にログが見れるので有効にした方が良さそうです。

「Next」で進み、今後の実行頻度を設定したらLineageIngestionの作成は完了です。 作成できたらLineageIngestionを一回動かしておきます。

追加でやらないといけないこと

これでLineageの情報は見れたでしょうか? おそらくこの設定だとLineageとして得たい情報は得られないのではないかと思います。

LineageIngestionのログを見てみると、ジョブはほとんど何もしないで終了しているように見えます。

Total processed records: 0

と書かれているので、何も処理していないように見えます。 処理時間も開始から10秒ほどで完了しています。

Ingestionで取得するための条件としては以下のように表示されており、

  • svv_table_infoが見れる(こちらはLineageとは直接関係ない前提条件)
  • stl_queryが見れる

が条件になっているようです。

一応確認してみても、STL_QUERYテーブルは確かに見ることができます。

条件を満たしているように見えますが、なぜ取得ができないのでしょうか? なかなか原因がわからなかったのですが、この理由はRedshiftのドキュメントをちゃんと見るとわかりました。

スーパーユーザー特権を持っているユーザーのみが、スーパーユーザーが表示可能なカテゴリのテーブルのデータを表示できます。通常のユーザーは、ユーザーが表示可能なテーブルのデータを表示できます。

システムテーブルとビューのリファレンス

とのことで、STL_QUERYでは自分が実行したクエリしか見ることができないようです。 確かに上の画像でも、クエリ履歴として1件しか表示されていないので、ここですぐに気づくべきでしたね。 ということで、他人のクエリ履歴も見れるように設定を変更します。

ALTER USER catalog_user SYSLOG ACCESS UNRESTRICTED;

これで権限が付与できます。 もう一度LineageIngestionを実行してみると、 今度は何かしらの処理をしていることが伺えると思います。

リネージュを見てみる

取得できたリネージュの情報を見てみます。 適当なテーブルを開いて、「Lineage」タブから見ることができます

親子の深さはデフォルトでは1階層分しか表示されないので、 歯車アイコンから3階層まで表示できるように変更できます。

テーブル単位での依存関係

あるテーブルを選択すると、それの親子になっているテーブルとのつながりが色付けされます。

カラム単位での依存関係

あるカラムを選択すると、親子テーブルのどのカラムの計算に使われているかが色付けされます。

テーブル間を繋ぐSQLを確認

テーブルを繋ぐ線をクリックすると、右側に該当するSQLが表示されます。 実際にどのようなクエリでテーブルが結びついているのかも簡単に確認ができます。

使いやすいUIでカラム単位でのデータの由来などを調べることができ、 全体像の把握に役立ちそうです!

まとめ

OpenMetadataを使ってRedshiftのクエリ履歴からデータリネージュのグラフを書いてみました。 クエリ履歴の再取得も定期的に行ってくれるので、クエリが変わった時にも自動的に追従してくれるはずです。 ただしその場合はQuery Log Durationの設定を適切にしないと 変更前後両方の情報が出てきてしまうかと思いますので、その辺は注意が必要そうです。

以上、誰かの参考になれば幸いです。