データウェアハウスやデータマートのviewが壊れていないかvalidationする

データ基盤の小ネタです。

データ基盤におけるview

データ基盤でデータスキャンがそれほど大きくない場合、積極的にviewを使っています(BigQueryを利用しています)。日時のバッチでテーブルとして掃き出してもよいですが、バッチを回さずにクエリをガシガシ変更できるのがviewの魅力です。

BigQueryのviewは、新規保存や編集時にクエリがinvalidになっている場合は保存できないようになっています。しかし、保存後にviewが壊れてしまう場合が多々ありえます。例えば、参照していたテーブル / カラムがrename / 削除された、などです。

そんなに簡単には壊れないだろうと高を括っていると、痛い目に合います。仕事で管理しているデータ基盤のview、雑に作ったものを含めると数十個が壊れていることが分かりました...*1。データ基盤をBigQuery上で展開し始めてから半年でこれなので、何もせずに運用して数年後経った場合を考えると恐しいですね。

viewが壊れると...

viewが壊れてしまうと、当然チームに不都合が起きます。

  • 日頃見ていたダッシュボードが見れなくなる
    • 短期的に怖い
  • 既存のダッシュボードが壊れるのを恐れるために、viewのリファクタリングをせず似たようなクエリが乱発される
    • 中期的に怖い
    • ソフトウェアエンジニアとしてはviewもリファクタリングしてよりよいものにしていきたい
  • 壊れたviewが平気で転がっていると、割れ窓的に壊れたviewが増殖し始め、データ基盤が信頼できないものになる。その結果、データ基盤が使われなくなったり、データ分析が信頼されないものになる
    • 長期的に怖い

viewが壊れていないか監視する

様々なタイムスパンにおいて、viewが壊れるとよくないということが分かりました。では、viewが壊れないようにするにはどうすればよいでしょうか。壊さないためには基本的に触らない作戦が一番よいとは思いますが、viewをどんどんよいものにするためにも積極的に触るようにはしたいです。代わりに、触った結果viewが壊れていたら検知できるようにします。

bqのqueryサブコマンドには--dry_runというオプションがあり、invalidなクエリを投げると失敗してくれます。これを利用して、データウェアハウスやデータマートのviewが壊れていないかvalidateするスクリプトを用意しました。

#!/bin/bash
set -u

CWD=$(cd $(dirname $0); pwd)
PROJECT=my-project

DATASETS=("${PROJECT}:warehouse__dataset" "${PROJECT}:mart__dataset")

for dataset in ${DATASETS[@]}; do
  for view in $(bq ls --max_results=1000 --format=prettyjson $dataset | jq -r '.[] | select(.type == "VIEW") | .id'); do
    bq show --format json --view ${view} | jq -r .view.query | bq query --use_legacy_sql=false --dry_run --format=json > /dev/null
    if [ $? -ne 0 ]; then
      echo "${view} seems broken..."
      exit 1
    fi
  done
done

あとは毎日のバッチmkr wrapなどを使って、viewが壊れたら監視サービスですぐに分かるという状況を作っておきます。こうすることで、修正した後に悪影響があればすぐに分かるので、修正も怖くありません。

最近だったらgithub actionsとかに組み込んでも面白いかもしれませんね。「うちではこうやってvalidationしてるよ!」という例があったらどんどん教えて欲しい!

*1:スタートダッシュでどういうことができるかを含めてどんどん作っていこう!という方針で最初はやっていたので、想定内と言えば想定内。最初から完璧を目指しすぎて、全然使われない状況よりはよっぽどよいと思う