DatahubにRedshiftのメタデータ取り込み・削除を試してみた

2021.12.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どーもsutoです。

LinkedIn製のOSSデータカタログ「DataHub」について、今回はRedshiftのメタデータの取り込みと、メタデータの削除を検証していきたいと思います。

Datahubの概要や過去の記事については下記をご参照ください。

前提条件

各々の環境でDatahubの構築が完了している状態とします。詳細は公式ドキュメントを、AWS上で構築する場合は過去に記事にしていますので、ぜひ下記リンクもご参照いただければと思います。

OSSデータカタログ「Datahub」をAWS EKSで簡単に構築できます

今回はAWS上に構築したDatahubを使用するので、事前にメタデータ取り込みに利用するGMSのエンドポイント(ポート8080構成ELBのURL)を控えておきましょう。

また、作業PCでDatahub CLIを使用しますので以下モジュールのインストールが完了しておくこと。

# Python 3.6以降であることが条件です。
python3 -m pip install --upgrade pip wheel setuptools
python3 -m pip install --upgrade acryl-datahub
datahub version
# もし "command not found" とメッセージが出たら ”python3 -m datahub version” で実行してみてください。

Datahub CLIのインストールが完了したら、 datahub init を実行して、DatahubのコマンドによるAPI送信先となるサーバを設定します。

% datahub init
Configure which datahub instance to connect to
Enter your DataHub host [http://localhost:8080]:http://<<先ほど控えたGMSのURL>>:8080
Enter your DataHub access token (Supports env vars via `{VAR_NAME}` syntax) []: # 空欄でOK
Written to <<カレントディレクトリ>>/.datahubenv

Redshiftメタデータの取り込み

検証で使用するRedshiftは、すでに作業PCからネットワーク的にReachableな状態であることを確認します。

今回は、自身が作成したテストスキーマ(cm_suto_takeshi)の中にRedshiftサンプルデータであるtikitなどのサンプルテーブルを登録している状態にしています。(参考)

cmdb=> \dt cm_suto_takeshi.*
                   List of relations
     schema      |   name    | type  |      owner
-----------------+-----------+-------+-----------------
 cm_suto_takeshi | category  | table | cm_suto_takeshi
 cm_suto_takeshi | customer  | table | cm_suto_takeshi
 cm_suto_takeshi | date      | table | cm_suto_takeshi
 cm_suto_takeshi | dwdate    | table | cm_suto_takeshi
 cm_suto_takeshi | event     | table | cm_suto_takeshi
 cm_suto_takeshi | lineorder | table | cm_suto_takeshi
 cm_suto_takeshi | listing   | table | cm_suto_takeshi
 cm_suto_takeshi | part      | table | cm_suto_takeshi
 cm_suto_takeshi | sales     | table | cm_suto_takeshi
 cm_suto_takeshi | supplier  | table | cm_suto_takeshi
 cm_suto_takeshi | users     | table | cm_suto_takeshi
 cm_suto_takeshi | venue     | table | cm_suto_takeshi
(12 rows)

Datahub CLIのプラグインをインストールし、Redshift取り込みを有効にします。

pip install 'acryl-datahub[redshift]'

以下のような、Redshift用のレシピをYamlファイルで作成します。

source:
  type: redshift
  config:
    # Coordinates
    host_port: <<Redshiftのエンドポイント>>:5439
    database: <<Redshiftデータベース名>>
    database_alias: testinstance

    # Credentials
    username: <<Redshiftユーザ名>>
    password: <<Redshiftパスワード>>

    schema_pattern:
      allow: 
        - '^cm_suto*'

    include_views: True # ビューを取り込むかどうか選択可能、defaultはTrue
    include_tables: True # テーブルを取り込むか選択可能、defaultsはTrue
sink:
  type: "datahub-rest"
  config:
    server: "http://<<GMSサーバのエンドポイント>>:8080"

# 以下は任意で設定可能
transformers:
  - type: "simple_add_dataset_tags"
    config:
      tag_urns:
        - "urn:li:tag:<<タグ名1>>"
        - "urn:li:tag:<<タグ名2>>"

上記ファイルのconfigパラメータについて解説します。

  • host_port: 対象のRedshiftインスタンスを指定【必須】
  • database: 取り込む対象のデータベース名を指定
  • database_alias: ここに設定した任意の文字列がエイリアス名となる
    • Datahub上のパスは「Dataset/環境変数(prod or dev)/redshift/エイリアス名/スキーマ名」となる
    • テーブル情報は「エイリアス名.スキーマ名.テーブル名」という名前で取り込まれます
    • このパラメータを使わない(コメントアウト)場合、エイリアスはデータベース名がデフォルトとなる
  • username: Redshiftのログインユーザ名
  • password: Redshiftのログインパスワード
  • schema_pattern: スキーマ名を正規表現でフィルタリングする(全てのスキーマを取得するならここはコメントアウトでよい)
    • 他に「table_pattern」「view_pattern」でもフィルタが可能
  • include_views: データベース内の”ビュー”を取り込み対象とするか選択可能 デフォルト値はTrue
  • include_tables: データベース内の”テーブル”を取り込み対象とするか選択可能 デフォルト値はTrue

transformersという要素で様々なアクションをオプションとして追加することができる。

例えば、上記のように「simple_add_dataset_tags」を使って取り込むスキーマに対して一括でタグを付与することができる

また、「set_dataset_browse_path」というパラメータは、「database_alias」を使わなくとも、リソースのエイリアス(ブラウザパス)を自由に定義することが可能です。

transformers:
  - type: "set_dataset_browse_path"
    config:
      path_templates:
        - /test2/redshift1/domain/schema1

このように様々なアカウントや環境のデータベース等からメタデータを取り込んだ際に、どこの環境から取り込んだものかを識別できるようにしておくのに役立つと思います。

レシピの作成が完了したら以下コマンドのようにメタデータの取り込みを実行します。

datahub ingest -c ./redshift.yml

Pipeline finished successfullyというメッセージが出たら取り込み成功です。

実際に画面を見てみると以下のようになります。

メタデータの削除

取り込んだメタデータを削除するための方法を試してみます。

コマンドは datahub delete となりますが、基本的に取り込んだメタデータのリソースネームにあたる"urn"を指定する必要があります。

urnを調べるには、まず以下コマンドでメタデータ取り込み実行プロセスの一覧を表示します。

 % datahub ingest list-runs
+-----------------------------------------------+--------+---------------------+
| runId                                         |   rows | created at          |
+===============================================+========+=====================+
| no-run-id-provided                            |     51 | 2021-12-17 06:04:10 |
+-----------------------------------------------+--------+---------------------+
| datahub-business-glossary-2021_12_17-14_58_52 |     61 | 2021-12-17 05:58:52 |
+-----------------------------------------------+--------+---------------------+
| redshift-2021_12_17-14_56_55                  |     49 | 2021-12-17 05:57:19 |
+-----------------------------------------------+--------+---------------------+
| file-2021_12_01-09_53_40                      |    250 | 2021-12-01 00:53:40 |
+-----------------------------------------------+--------+---------------------+

表示された一覧から対象のrunId(今回はRedshift)を控えます。

次に以下のコマンドを使って、runIdの詳細情報を表示します。引数には先ほど控えたrunIdを入力します。

すると以下のように取り込んだメタデータのurnやアスペクト名、生成日時がわかります。

% datahub ingest show --run-id redshift-2021_12_17-14_56_55
this run created 12 new entities and updated 49 aspects
rolling back will delete the entities created and revert the updated aspects

showing first 49 of 49 aspects touched by this run
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
| urn                                                                                       | aspect name          | created at          |
+===========================================================================================+======================+=====================+
| urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.category,PROD)  | schemaMetadata       | 2021-12-17 05:57:19 |
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
| urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.category,PROD)  | datasetKey           | 2021-12-17 05:57:19 |
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
| urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.category,PROD)  | browsePaths          | 2021-12-17 05:57:19 |
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
| urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.category,PROD)  | dataPlatformInstance | 2021-12-17 05:57:19 |
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
| urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.customer,PROD)  | datasetProperties    | 2021-12-17 05:57:19 |
+-------------------------------------------------------------------------------------------+----------------------+---------------------+
・
・
・以下省略

よって削除したいurnを引数に、以下の例のようなコマンドでメタデータの削除ができます。

datahub delete --urn urn:li:dataset:(urn:li:dataPlatform:redshift,testinstance.cm_suto_takeshi.category,PROD)

またdeleteコマンドは「ソフト削除」がデフォルトとなります。

ソフト削除とは、メタデータのステータスを”Removed”に変え、アスペクトがUIに返されないようにする(表示されないようにする)ことで、メタデータストアから物理的に削除したわけではありません。

物理的なに削除する場合は --hard オプションをつけてハード削除を実行します。

datahub delete --urn <<メタデータのurn id>> --hard

その他のオプションとして、 --env--entity_type--platform など環境変数やエンティティタイプやプラットフォーム名を指定した一括削除を行うこともできます。

コマンド例は公式ドキュメントをご参照ください。

また、取り込みプロセスをロールバックすることによる削除の方法もあります。

先ほどのように対象のrunIdを引数として取り込みプロセスをロールバックし、データを元の状態に戻す処理なので、誤って取り込んでしまったデータを取り消す際にも活用できます。

# runIdを一覧表示
datahub ingest list-runs
# 対象のrunIdで処理したメタデータを確認
datahub ingest show --run-id <<run-id>>
# メタデータ取り込みをロールバック
datahub ingest rollback --run-id <<run-id>>

まとめ

今回はRedshiftを例にDatahubにおけるメタデータ取り込み・削除の手順についてご紹介しました。

次回はGlossary Termの取り込みについて記事にしたいと思います。