データパイプライン・ETL

データパイプライン・ETLとは

データパイプラインは、複数のシステムに散らばったデータを収集・加工・格納する一連の流れです。中でも古典的な型が ETL(Extract抽出 → Transform変換 → Load格納)です。

Extract: 各サービスのDBやAPIからデータを取得
Transform: 形式をそろえ、不要な列を除き、集計しやすい形に変換
Load: 分析用のデータベース(データウェアハウス)へ格納

初学者向けポイント

  • 業務システムの [[リレーショナルデータベース]] は「今の状態」を正確に保つのが得意ですが、「過去数年分の傾向を分析する」ような重い集計には不向きなことが多い。そこで分析専用の場所にデータを集約する発想が生まれた
  • ETL と似た言葉に ELT(Extract → Load → Transform)がある。先に生データをそのまま格納し、変換は格納後に行うスタイルで、クラウドの分析基盤の性能向上とともに主流になりつつある
  • バッチ処理(1日1回など定期実行)とストリーム処理(データが来るたびにリアルタイム処理)の2つの実行スタイルがある

1本のパイプラインを分解する

「昨日の売上を店舗別に集計する」日次パイプラインを例に、中で何が起きているかを見てみます。

01:00 Extract   注文DBから前日分の注文レコードを抜き出す
01:20 Transform 返品済みを除き、通貨を円にそろえ、店舗IDごとに合計する
01:40 Load      集計結果を分析用テーブルへ書き込む
02:00          ダッシュボードに前日の数字が並ぶ

初学者が意外に思うのは、難しいのは Transform ではなく Extract の範囲決めだという点です。「前日分」と言っても、注文が発生した日時で切るのか、システムに取り込まれた日時で切るのかで中身は変わります。深夜0時直前の注文が遅れて届いたとき、前者なら前日分、後者なら当日分に入ります。どちらが業務の定義に合うかを最初に決め、後から静かに変えないことが大切です。

取り込み方にも2つのやり方があります。

  • 全件洗い替え — 毎回すべてを取り直して置き換える。単純で壊れにくいが、データが増えるほど時間がかかる
  • 増分取り込み — 前回以降に増えた分だけを取る。速いが「前回どこまで取ったか」を正しく記録し続ける必要がある

小さいうちは全件洗い替えで始め、処理時間が業務時間に食い込みそうになってから増分へ移すのが安全です。処理が予定時刻に終わらず翌朝へずれ込む事故は [[バッチ処理]] で「突き抜け」と呼ばれ、そもそもの定期実行の仕組みは [[ジョブスケジューリング(cron)]] が担います。

データウェアハウスとデータレイク

用語内容
データウェアハウス整形済みデータを構造化して格納。分析・集計向け(BigQuery、Snowflakeなど)
データレイク生データを形式を問わず格納。後から目的に応じて加工(S3、GCSなど)
[[NoSQL]]ログのような大量・非構造データの一時的な受け皿としても使われる

止まったとき・作り直すときに効く設計

パイプラインは必ず止まります。ネットワークが切れ、外部APIが応答せず、想定していない値が流れてきます。ですから「止まらない作り」より、止まった後に安全にやり直せる作りを優先します。

  • 同じ日付で何度実行しても結果が同じになるようにする — 追記だけで書くと、再実行のたびに同じ行が積み上がります。「対象日の行をいったん消してから入れ直す」形にすれば、何度動かしても結果は1つです。この性質が [[冪等性]] で、外部呼び出しの再試行と合わせて設計します([[エラーハンドリングとリトライ設計]])
  • 段ごとに途中結果を残す — 抽出した生データを捨てずに置いておくと、変換ロジックを直したときに抽出からやり直さずに済みます。ELT が好まれる理由の一つでもあります
  • 「成功」の定義を件数で持つ — エラーで止まることより厄介なのが、0件のまま成功扱いで終わることです。処理件数が普段の水準から大きく外れたら失敗とみなす判定を入れておきます([[監視とアラート]])

よくある事故はこうです。抽出だけが外部APIの一時エラーで空振りしたのに後続はそのまま動き、前日と同じ数字が何事もなくダッシュボードに並ぶ。エラー通知が出ないので数日は誰も気づきません。次の段へ進む前に、新しいデータが入ったことを確かめるのが基本の予防策です。

初学者がつまずきやすい点

  • 「集計してみたら数字が合わない」の原因の多くは変換(Transform)段階のロジックの誤りか、重複データの混入
  • パイプラインが止まった/遅れたときの検知が遅れがち。処理件数や実行時間を監視する仕組み([[オブザーバビリティ]])とセットで設計する

次に読む地図

データパイプラインは多くの技術の交差点にあります。目的別に次の一歩を並べます。

両端を知る — 設計はまず入口と出口の性質で決まります。抽出元と格納先の得意・不得意を押さえましょう。

  • [[リレーショナルデータベース]] — 抽出元の代表。「今の状態」を正確に持つ側
  • [[NoSQL]] — ログやイベントなど、形のそろわないデータの受け皿
  • [[データウェアハウス]] — 格納先の主役。列指向で集計が速くなる仕組みはこちら
  • [[OLTPとOLAP]] — そもそもなぜ別の場所へ写すのか、という前提の整理

動かし方を選ぶ — 同じ変換内容でも、定期実行か到着のたびかで作りが変わります。

  • [[バッチ処理]] — まとめて一括処理する基本形と、その設計の勘所
  • [[ジョブスケジューリング(cron)]] — 「毎晩2時に」を実現する起動役
  • [[メッセージキュー]] — データが届くたびに処理を進める、ストリーム寄りの構成で使う

書く道具を選ぶ — 変換をどこに書くかで、使う言語が変わります。

  • [[Python]] — 抽出と変換をコードで書くときの定番
  • [[SQL]] — 変換を格納先で行う ELT では、集計SQLそのものが処理の本体になる

壊さず運用する — 作った後のほうが付き合いは長く、ここが効きます。

  • [[冪等性]] / [[エラーハンドリングとリトライ設計]] — 再実行と再試行を安全にする土台
  • [[オブザーバビリティ]] / [[監視とアラート]] — 遅延・停止・0件成功に気づくための目

この先にあるもの — 整えたデータの行き先を知ると、どこまで作り込むか判断できます。

  • [[機械学習の基礎]] — 学習データの質はパイプラインの品質そのもの。前処理はここでつながる

関連技術とのつながり

  • [[リレーショナルデータベース]] — パイプラインの抽出元・格納先として頻出
  • [[NoSQL]] — 非構造データの受け皿として組み合わされる
  • [[メッセージキュー]] — 段階的な処理をつなぐ橋渡し役として使われる
  • [[クラウドコンピューティング]] — 主要なデータウェアハウス・データレイクサービスの提供元
Q: ELT が ETL と異なる点はどれ?
- [ ] 抽出を行わず、格納と変換だけを行う
- [x] 先に生データをそのまま格納し、変換は格納後に行う
- [ ] 変換を行わないため集計ができない
解説: ELT は Extract → Load → Transform の順で、生データを先に格納してから変換します。クラウド分析基盤の性能向上とともに主流になりつつあるスタイルです。

Q: 日次パイプラインを同じ日付で再実行しても結果が二重にならないようにする書き方はどれ?
- [ ] 実行のたびに集計結果を追記していく
- [x] 対象日の行をいったん消してから入れ直す
- [ ] 実行前に必ず手動でデータを確認する
解説: 追記だけだと再実行のたびに同じ行が積み上がります。対象日を消して入れ直せば何度動かしても結果は1つになり、これが冪等性のある作りです。

Q: 「0件のまま成功扱いで終わる」パイプラインの事故を防ぐ方法として本文が挙げているのはどれ?
- [x] 処理件数が普段の水準から大きく外れたら失敗とみなす判定を入れる
- [ ] 変換処理をすべて手作業に置き換える
- [ ] 抽出した生データを毎回削除する
解説: エラーが出ずに空のまま完走すると誰も気づけません。件数を「成功」の定義に含めることで、前日と同じ数字が出続ける事故を検知できます。