はじめに
生成AIの動向ばかりに目を奪われがちな昨今ですが、そろそろAIはAI以外の各種技術領域との連動にシフトし始めている頃合いかなと思います
そこで改めてModern Data Stack周りの技術動向調査をしている際にOpenLineageという単語を見かけました
どうやらベンダー製品にも取り込まれはじめている技術のようで気になったので調べてみて実際に動かしてみましたというメモレベルでまとめたみた系の記事となります
OpenLineageとは?
Data Lineageの収集・分析において標準化を目的にしたものだそうです
公式サイトはこちら
OpenLineage is an open platform for collection and analysis of data lineage. It tracks metadata about datasets, jobs, and runs, giving users the information required to identify the root cause of complex issues and understand the impact of changes. OpenLineage contains an open standard for lineage data collection, a metadata repository reference implementation (Marquez), libraries for common languages, and integrations with data pipeline tools.
そもそもデータリネージというのはデータの発生からどのような加工を経てエンドユーザーがそのデータを利活用できるようになっているかということを明示した情報のことでメタデータの一種です
業務ユーザーViewではデータ分析に使うデータに対して、そもそもこのデータどこから来たの?信頼できるの?どこかで計算間違ってない?といった問いに答える上で役に立ち、システムViewではETL/Data Pipelineの保守などで影響分析などに役に立つ情報です
こうしたデータリネージをシステム的に収集・可視化していくためには、従来はETLツールとCatalogツールがセットでサポートしている必要がありました。ただそうなると様々なベンダー製品を複合的に組み合わせたようなシステムではどうしてもデータリネージを全て捉えるきるのに限界があったのではないかと考えられます
OpenLineageはデータリネージの収集と分析を標準化することを目指したオープンなフレームワークと謳っており、この技術が普及していくことでツールに依存しない一貫したデータリネージの収集が可能になっていくと思われます
そんなOpenLineage、実体を一言でいうとAPI仕様です
API DocやOpenAPI yamlも公開されています
そしてこの仕様を実装しているのがMarquezというSoftwareでOpenLinage公式のTutorialでも登場します
ローカルで動かしてみた
実際に動かして感触を掴んでみます
純粋にOpenLineageだけをAPIで試してみるなら公式のGetting Startedがいいと思います
ただ今回は実践的なイメージを持ちたかったのでdbtとの組み合わせで試してみました
OpenLineageの公式にもdbtでのTutorialがあります
最初はこのガイドを参考に進めようかと思いましたが、BigQueryを使うサンプルのようです
ローカルで完結させたかったので、代わりに目に入った3NFからDimensional Modelへの変換のtutorialをベースに進めます
1. dbtの準備
とりあえず前提でターゲットのDBが必要なのでPostgresをdocker-composeでサクッと上げましょう
$ cat docker-compose.yaml
services:
db:
image: postgres:17
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
$ docker-compose up -d
$ docker compose exec db createdb -U postgres adventureworks
上記でDBのできあがりです
あとはこちらのガイドに沿っていけば特段難しいところはないでしょう1
$ cat adventureworks/packages.yml
packages:
- package: dbt-labs/dbt_utils
version: ["1.3.0"]
2. Marquezの準備
Marquezをローカルで上げていきます。こちらもdocker対応しているので非常に簡単です
git clone https://github.com/MarquezProject/marquez
# dbtのターゲットのPostgresとportが競合するため変更しています
sh ./docker/up.sh --db-port 5433
3. OpenLineage連携
いよいよdbtからMarquezにOpenLinageで連携です
dbtのwrapperでdbt-olというツールがあるのでこれを使えば簡単にできます2
実行してみると以下のようなログが出ますeventが18個emitされたと出てますね
$ pip install openlineage-dbt
$ export OPENLINEAGE_URL=http://localhost:5000
$ dbt-ol run
Running OpenLineage dbt wrapper version 1.27.0
This wrapper will send OpenLineage events at the end of dbt execution.
06:02:56 Running with dbt=1.9.1
06:02:56 Registered adapter: postgres=1.9.0
06:02:57 Found 8 models, 15 seeds, 42 data tests, 548 macros
06:02:57
06:02:57 Concurrency: 12 threads (target='postgres')
06:02:57
06:02:58 1 of 8 START sql table model marts.dim_address ................................. [RUN]
06:02:58 2 of 8 START sql table model marts.dim_credit_card ............................. [RUN]
06:02:58 3 of 8 START sql table model marts.dim_customer ................................ [RUN]
06:02:58 4 of 8 START sql table model marts.dim_date .................................... [RUN]
06:02:58 5 of 8 START sql table model marts.dim_order_status ............................ [RUN]
06:02:58 6 of 8 START sql table model marts.dim_product ................................. [RUN]
06:02:58 7 of 8 START sql table model marts.fct_sales ................................... [RUN]
06:02:59 5 of 8 OK created sql table model marts.dim_order_status ....................... [SELECT 1 in 0.76s]
06:02:59 4 of 8 OK created sql table model marts.dim_date ............................... [SELECT 731 in 0.81s]
06:02:59 6 of 8 OK created sql table model marts.dim_product ............................ [SELECT 504 in 0.81s]
06:02:59 2 of 8 OK created sql table model marts.dim_credit_card ........................ [SELECT 1316 in 0.82s]
06:02:59 1 of 8 OK created sql table model marts.dim_address ............................ [SELECT 1675 in 0.82s]
06:02:59 3 of 8 OK created sql table model marts.dim_customer ........................... [SELECT 19820 in 0.86s]
06:02:59 7 of 8 OK created sql table model marts.fct_sales .............................. [SELECT 5675 in 0.87s]
06:02:59 8 of 8 START sql table model marts.obt_sales ................................... [RUN]
06:03:01 8 of 8 OK created sql table model marts.obt_sales .............................. [SELECT 5675 in 2.68s]
06:03:01
06:03:01 Finished running 8 table models in 0 hours 0 minutes and 4.23 seconds (4.23s).
06:03:02
06:03:02 Completed successfully
06:03:02
06:03:02 Done. PASS=8 WARN=0 ERROR=0 SKIP=0 TOTAL=8
Emitting OpenLineage events: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████| 18/18 [00:07<00:00, 2.38it/s]
Emitted 18 OpenLineage events
Marquezのログも見てみましょう。以下のようにPOSTが走っています
marquez-api | INFO [2025-01-31 06:02:52,804] marquez.logging.LoggingMdcFilter: status: 201
marquez-api | 172.22.0.1 - - [31/Jan/2025:06:02:52 +0000] "POST /api/v1/lineage HTTP/1.1" 201 0 "-" "python-requests/2.32.3" 2508
marquez-api | INFO [2025-01-31 06:03:04,141] marquez.logging.LoggingMdcFilter: status: 201
marquez-api | 172.22.0.1 - - [31/Jan/2025:06:03:04 +0000] "POST /api/v1/lineage HTTP/1.1" 201 0 "-" "python-requests/2.32.3" 662
marquez-api | INFO [2025-01-31 06:03:04,555] marquez.logging.LoggingMdcFilter: status: 201
marquez-api | 172.22.0.1 - - [31/Jan/2025:06:03:04 +0000] "POST /api/v1/lineage HTTP/1.1" 201 0 "-" "python-requests/2.32.3" 393
marquez-api | INFO [2025-01-31 06:03:04,892] marquez.logging.LoggingMdcFilter: status: 201
...
無事リクエストを受け取れたようなので、最後にLineageの画面を見てみましょう
localhost:3000にアクセスしてみます
はい、こんな感じで可視化されたものがでてくるかと思います
UIはかなり綺麗でモダンな感じですね
最後に
ひとまずOpenLineageをサクッと試して感触を掴むことができました
こうした標準化された技術というのは、他のOSSのツールなどでもスキルの使い回しがききそうですし、エンジニアとしては今後の発展にも期待したいですね
今後は更にベンダー製品での適用例やAIからのデータ利活用のユースケースなども試していきたいnと思
-
dbtのversionが低かったようなのでpackages.ymlだけ以下のように変更しました ↩
-
Macユーザーの方はlocalhost:5000はAirPlayという機能がリザーブしていて、Marquezにリクエストが届きませんのでポート番号変えたりAirPlayをoffにしたりしましょう。簡単とか言いながらここでちょっと詰まりました。。 ↩