DatahubのUIベースによるメタデータ取り込み機能でRedshiftのメタデータを取り込んでみた
どーも データアナリティクス事業本部のsutoです。
LinkedIn製のOSSデータカタログ「DataHub」は、メタデータ取り込みの際は、レシピというConfigパラメータをyamlで記述し、Datahub CLIによるコマンドベースで取り込みを実施します。
ですが、アップデートによりv0.8.25
以降はUI画面上でメタデータ取り込みができるようになったとのことで検証していきたいと思います。
Datahub実行環境は以前の記事に紹介したAWS EKSサービス上にDatahubをデプロイする記事を参考に検証環境を構築します。
上記記事を参考に作業環境のインストールが完了したらEKSクラスターを作成していきましょう。
EKSクラスター作成
eksctlコマンドを使用してクラスターを作成します。今回は以下のパラメータで作成します。
- VPC:CIDRを指定して新規作成(10.1.0.0/16)
- クラスター名:datahub-test
- リージョン:ap-northeast-1
- インスタンスタイプ:m5.large
- ノード数:3
※Datahubのストレージレイヤを含むすべてのコンポーネントをEKSクラスター内のpodでデプロイさせるには少なくともm5.large以上が3ノード必要となります。
eksctl create cluster \ --vpc-cidr 10.1.0.0/16 \ --name datahub-test \ --region ap-northeast-1 \ --with-oidc \ --node-type m5.large \ --nodes 3
実行するとCloudformationスタックが実行され、完了後にkubectl get nodes
を実行することで以下例のように3ノードが表示されます。
% kubectl get nodes NAME STATUS ROLES AGE VERSION ip-10-1-12-57.ap-northeast-1.compute.internal Ready <none> 17m v1.20.11-eks-f17b81 ip-10-1-60-101.ap-northeast-1.compute.internal Ready <none> 17m v1.20.11-eks-f17b81 ip-10-1-72-207.ap-northeast-1.compute.internal Ready <none> 16m v1.20.11-eks-f17b81
UIベース取り込みのためのIAMポリシー作成
UIベース取り込みの機能はacryl-datahub-actions
というPodを実装するので、そのPodにアタッチするIAMロールを作成します。
まず、必要なデータソースにアクセスできるためのIAMポリシーを作成します。今回はとりあえずRedshiftにアクセスできるようなポリシー(arn:aws:iam::<アカウントID>:policy/datahub-ingection-policy)を用意します。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "redshift-data:*", "redshift:*" ], "Resource": "*" } ] }
次に、以下のコマンドでポリシーが添付されたサービスアカウントを作成します。
eksctl create iamserviceaccount \ --name acryl-datahub-actions \ --namespace datahub \ --cluster datahub-test \ --attach-policy-arn arn:aws:iam::<<account-id>>:policy/atahub-ingection-policy \ --approve \ --override-existing-serviceaccounts
Helmを使用してEKSクラスターにDataHubをセットアップ
- DatahubのリポジトリをHelmに追加します。
helm repo add datahub https://helm.datahubproject.io/
- クラスター上にデプロイするMySQLデータベースとNeo4jのパスワードを格納したkubernetesシークレットを作成します。
kubectl create secret generic mysql-secrets --from-literal=mysql-root-password=datahub kubectl create secret generic neo4j-secrets --from-literal=neo4j-password=datahub
- 以下を実行してDatahubのストレージレイヤ部分を先にデプロイします
% helm install prerequisites datahub/datahub-prerequisites NAME: prerequisites LAST DEPLOYED: Wed Dec 1 01:31:18 2021 NAMESPACE: default STATUS: deployed REVISION: 1
kubectl get pods
を実行して、以下のように依存関係のすべてのポッドが実行されているかどうかを確認します。
% kubectl get pods NAME READY STATUS RESTARTS AGE elasticsearch-master-0 1/1 Running 0 2m6s elasticsearch-master-1 0/1 Running 0 2m6s elasticsearch-master-2 1/1 Running 0 2m6s prerequisites-cp-schema-registry-cf79bfccf-hxw5g 2/2 Running 0 2m6s prerequisites-kafka-0 1/1 Running 0 2m6s prerequisites-mysql-0 1/1 Running 0 2m6s prerequisites-neo4j-community-0 1/1 Running 0 2m6s prerequisites-zookeeper-0 1/1 Running 0 2m6s
- Helmチャートのvalues.yamlを作成します。acryl-datahub-actionsに先ほど作成したserviceAccountの名前を追記します。
- ※本記事では、2022年5月10日時点の最新バージョン
v0.8.34
で作成しています。 - 【参考】デフォルト構成はこちら
datahub-gms: enabled: true image: repository: linkedin/datahub-gms tag: "v0.8.34" datahub-frontend: enabled: true image: repository: linkedin/datahub-frontend-react tag: "v0.8.34" # Set up ingress to expose react front-end ingress: enabled: false acryl-datahub-actions: enabled: true image: repository: public.ecr.aws/datahub/acryl-datahub-actions tag: "v0.0.1-beta.13" resources: limits: memory: 512Mi requests: cpu: 300m memory: 256Mi serviceAccount: name: acryl-datahub-actions datahub-mae-consumer: image: repository: linkedin/datahub-mae-consumer tag: "v0.8.34" datahub-mce-consumer: image: repository: linkedin/datahub-mce-consumer tag: "v0.8.34" datahub-ingestion-cron: enabled: false image: repository: acryldata/datahub-ingestion tag: "v0.8.34" elasticsearchSetupJob: enabled: true image: repository: linkedin/datahub-elasticsearch-setup tag: "v0.8.34" podSecurityContext: fsGroup: 1000 securityContext: runAsUser: 1000 kafkaSetupJob: enabled: true image: repository: linkedin/datahub-kafka-setup tag: "v0.8.34" podSecurityContext: fsGroup: 1000 securityContext: runAsUser: 1000 mysqlSetupJob: enabled: true image: repository: acryldata/datahub-mysql-setup tag: "v0.8.34" podSecurityContext: fsGroup: 1000 securityContext: runAsUser: 1000 postgresqlSetupJob: enabled: false image: repository: acryldata/datahub-postgres-setup tag: "v0.8.34" podSecurityContext: fsGroup: 1000 securityContext: runAsUser: 1000 datahubUpgrade: enabled: true image: repository: acryldata/datahub-upgrade tag: "v0.8.34" noCodeDataMigration: sqlDbType: "MYSQL" podSecurityContext: {} # fsGroup: 1000 securityContext: {} # runAsUser: 1000 global: graph_service_impl: neo4j datahub_analytics_enabled: true datahub_standalone_consumers_enabled: false elasticsearch: host: "elasticsearch-master" port: "9200" kafka: bootstrap: server: "prerequisites-kafka:9092" zookeeper: server: "prerequisites-zookeeper:2181" ## For AWS MSK set this to a number larger than 1 # partitions: 3 # replicationFactor: 3 schemaregistry: url: "http://prerequisites-cp-schema-registry:8081" # type: AWS_GLUE # glue: # region: us-east-1 # registry: datahub neo4j: host: "prerequisites-neo4j-community:7474" uri: "bolt://prerequisites-neo4j-community" username: "neo4j" password: secretRef: neo4j-secrets secretKey: neo4j-password sql: datasource: host: "prerequisites-mysql:3306" hostForMysqlClient: "prerequisites-mysql" port: "3306" url: "jdbc:mysql://prerequisites-mysql:3306/datahub?verifyServerCertificate=false&useSSL=true&useUnicode=yes&characterEncoding=UTF-8&enabledTLSProtocols=TLSv1.2" driver: "com.mysql.cj.jdbc.Driver" username: "root" password: secretRef: mysql-secrets secretKey: mysql-root-password datahub: gms: port: "8080" nodePort: "30001" mae_consumer: port: "9091" nodePort: "30002" appVersion: "1.0" encryptionKey: secretRef: "datahub-encryption-secrets" secretKey: "encryption_key_secret" # Set to false if you'd like to provide your own secret. provisionSecret: true managed_ingestion: enabled: true defaultCliVersion: "0.8.34.1" metadata_service_authentication: enabled: false systemClientId: "__datahub_system" systemClientSecret: secretRef: "datahub-auth-secrets" secretKey: "token_service_signing_key" tokenService: signingKey: secretRef: "datahub-auth-secrets" secretKey: "token_service_signing_key" # Set to false if you'd like to provide your own auth secrets provisionSecrets: true
- 以下のコマンドを実行してDatahubをデプロイします。
helm upgrade --install datahub datahub/datahub --values <yamlファイルを保存したフォルダパス>/values.yaml
- デプロイ完了後、podの一覧が以下のようになるはずです。
% kubectl get pods NAME READY STATUS RESTARTS AGE datahub-acryl-datahub-actions-f87bbf4cb-j2vh4 1/1 Running 0 2m49s datahub-datahub-frontend-5f57bc485b-967vw 1/1 Running 0 2m49s datahub-datahub-gms-7dbcd8d77d-rv2hx 1/1 Running 0 2m49s datahub-datahub-upgrade-job--1-ggzcb 0/1 Error 0 2m49s datahub-datahub-upgrade-job--1-s7td2 0/1 Completed 0 104s datahub-elasticsearch-setup-job--1-9wqk2 0/1 Completed 0 3m52s datahub-kafka-setup-job--1-5vcbs 0/1 Completed 0 3m50s datahub-mysql-setup-job--1-6wn2l 0/1 Completed 0 2m52s elasticsearch-master-0 1/1 Running 0 24m elasticsearch-master-1 1/1 Running 0 24m elasticsearch-master-2 1/1 Running 0 24m prerequisites-cp-schema-registry-cf79bfccf-5q5kf 2/2 Running 1 (23m ago) 24m prerequisites-kafka-0 1/1 Running 1 (23m ago) 24m prerequisites-mysql-0 1/1 Running 0 24m prerequisites-neo4j-community-0 1/1 Running 0 24m prerequisites-zookeeper-0 1/1 Running 0 24m
- Frontend用ELB(http://xxxxxxxx.ap-northeast-1.elb.amazonaws.com:9002)にブラウザでアクセスしてみると以下のようにログイン画面が表示されます。
実際にUI上からメタデータ取り込みをやってみた
- 今回はRedshiftを例にデータ取り込みを実施します。Redshift内のデータは以下ブログで使用したサンプルと同じです。
- デフォルトユーザとパスワード(datahub:datahub)でログインし、右上の「Ingection」をクリックします。
-
まずはRedshiftに接続するユーザー名とパスワードをUI上のシークレットに登録します。「Secrets」タブをクリックして「Create new secret」をクリックします。
- Name:REDSHIFT_USERNAME、Value:「Redshiftのユーザー名」を入力してOKをクリックします
- 画面を更新すると一覧にシークレットが表示されます。同様に、Name:REDSHIFT_PASSWORD、Value:「Redshiftのパスワード」も作成します。
- 次に「Sources」タブをクリックし、「Create new source」をクリックして取り込みジョブを作成していきます。
-
ソースタイプはRedshiftを選択します。
- 次の画面でレシピを記入して「次へ」。(書き方は従来のDatahub CLIと同様です。)
-
ログインユーザーとパスワードは先ほど作成したシークレットのNameを以下のように記入します。
※例では、「schema_pattern」で取り込むスキーマを指定するためのフィルタリングをしていますが、この部分はオプション設定となります。
source: type: redshift config: # Coordinates host_port: <<Redshiftのエンドポイント>>:5439 database: <<Redshiftデータベース名>> # Credentials username: '${REDSHIFT_USERNAME}' password: '${REDSHIFT_PASSWORD}' schema_pattern: allow: - '^cm_suto*' include_views: True # ビューを取り込むかどうか選択可能、defaultはTrue include_tables: True # テーブルを取り込むか選択可能、defaultsはTrue sink: type: "datahub-rest" config: server: "http://<<GMSサーバのエンドポイント>>:<<GMSサーバのポート番号>>"
- 次の画面ではcronによるスケジュール設定ができます。ここはオプションなので今回は設定しません、よって「Skip」で次へ進みます。
- 最後にワークフローの名前を付けます
- Executor idは今回はデフォルト設定とするので空欄にしています
- CLI VersionはデプロイしたDatahubサーバのバージョンと合わせるように設定してください。今回はサーバ、CLIどちらも最新バージョンで検証しているので空欄(自動的に最新バージョンに設定)でいきます。
- 最後に「Done」をクリックして設定完了です。
- すると一覧に表示されますので「EXECUTE」をクリックして取り込みジョブを実行してみます。
- ステータスは「Succeeded」になったら成功です。(画面ではレシピの記入ミスで何度かFailedになっていますが)
- 実際にメタデータの取り込みも問題なくできていました。
以上、Datahub CLIを作業端末にインストールすることなくUI画面上でメタデータの取り込みができました。
まとめ
UIベースの取り込み機能を実装しているフリーのOSSソフトは少ないので、Datahubはかなり開発が進んでいて多くのユーザーが扱いやすくなっている印象があります。
また、cronベースのスケジューリング機能も追加されていて、簡易なジョブワークフローならばDatahub画面上で管理できるようになったのもとても良いアップデートがされていると思います。
【2022年5月15日時点】この後、ストレージ部分をAWSサービス(RDS,MSK,Opensearch等)にした構成でこのUIベース取り込みを検証してみましたが、実行時に「acryl-datahub-actions」のPodがクラッシュしてしまい、ジョブが実行されないエラーが発生していて現在調査中です。