Feedforce Developer Blog

フィードフォース開発者ブログ

LookML Validation を 20 秒から 11 秒に高速化出来た

こんにちは、id:masutaka26 です。

Looker を使い始めて 3 年目に突入しました。変わらず Feedmatic という広告運用コンサルティングのデータ整備をする毎日です。

今回はここ 1 年の懸案だった LookML Validation の堪え難い遅さを改善出来たので、共有します。

2 年間でコード量が肥大化した

2 年前と比べて Feedmatic プロジェクトの .lkml ファイルがものすごく増え、440 個、23,217 行1にもなりました。Explore は 62 個、テスト用も含めると 150 個もあります。相変わらずボッチ LookML 開発者ではあるのですが。💦

さて、Looker の JumpStart で教えて頂いた「モデル編成のベストプラクティス」のうちの 1 つにこちらがありました。

ユーザーが必要とする答えに簡単にアクセスできる、可能な限り少ない数の explore を使用する。

しかし、広告運用の文脈だと、クライアントごとに独自実装が必要なケースが多く、このコード量になってしまいました。💦

LookML Validation が堪え難いほど遅くなった

そんな LookML 開発に使用する Looker IDE には LookML Validator が付属しており、git commit 前に強制する設定をしています。

docs.looker.com

以前は一瞬で完了していましたが、最近は 20 秒以上かかります。ちょっとコメントを書き換えただけでこれだけ待たされるのは、なかなかの苦行です。

試作した別プロジェクト(41 ファイル、1999 行)はそんなにかからないため、単純にコード量に比例していると思いました。

念のため Looker のサポートに質問したところ、やはりコード量(プロジェクトのサイズ)が影響しているそう。そして Looker インスタンスの CPU やメモリ使用量に問題はないとのこと。

さらに、こちらの記事を紹介して頂きました。🙏

community.looker.com

My LookML Validator is slow!

長い記事ではないので、ざっと翻訳します。

TL;DR

プロジェクトが大きければ大きいほど、検証には時間がかかります。

Quick wins

  1. 戦略的に "includes" する
    1. 常に他のすべてのビューをインクルードすることは開発上簡単かもしれないが、命名規則を使って必要なファイルだけを戦略的にインクルードすることで、パフォーマンスを向上させることができる
  2. 使用しない explore(および join、field など)をコメントアウトまたは削除する
  3. プロジェクトを複数のプロジェクトに分割することを検討する

LookML のベストプラクティスについては、こちらの記事をご覧ください。

Long answer

LookML のプロジェクトサイズ(総行数)と不要な include の両方が LookML Validator の性能に影響を及ぼします。

Validation は 2 段階のプロセスで行われます。

1) 1 回目の検証では、プロジェクト内のすべてのファイルを読み込み、どこにも参照されていないファイルも含めて、メモリに読み込み、ソースコードを 1 モデルずつ完全に翻訳して、「コンパイル」エラーを探します。

2) 2 回目の検証は、各モデルで開始し、そのモデルから参照されるファイルのみを解析します。そして、そのモデルに基づいてクエリーを構築し、クエリーエラーや「実行時」エラーを探します。また、これらのパスは、すべての検証で行われることも重要です。

結論として、1 回目の検証は LookML プロジェクトのサイズに、2 回目の検証は不要な include 文に影響されます。したがって、LookML プロジェクトのサイズを適切に保つと同時に、より選択的かつ戦略的な include を推奨するのが良いでしょう。

Bonus note

Explore ごとのフィールド数は、検証時間という点で非常に重要です。これはしばしばモデルのパースよりも時間がかかります。

include を最適化したら半分弱の時間になった

今回は「戦略的に "includes" する」をやってみました。

具体的には 56 個の .explore.lkml ファイルを以下のように変更しました。ワイルドカード付きの include を出来るだけ減らしました。

# 変更前
include: "/views/**/*.view"

↓

# 変更後
include: "/views/view1.view"
include: "/views/view2.view"
include: "/views/view3.view"
include: "/views/view4.view"
include: "/views/view5.view"

結果がこちら。たったこれだけで、20 秒かかっていた LookML validation が 12 秒弱にまで縮まりました。期待以上です!👏😂🎉

変更前(秒) 変更後(秒)
1 20.46 12.39
2 20.44 11.89
3 20.05 11.69
3 20.61 11.65
5 20.48 11.95
平均 20.41 11.91

ついでに、事情があって隠している Explore 10 個2の削除を確認してみたら、さらに速くなり、9 秒程度まで縮まりました。なるほど。

まとめ

ここ 1 年の懸案だった LookML Validation のパフォーマンスを改善しました。

include を最適化するだけで、ここまで速くなるとは驚きでした。おまけに LookML Validation のプロセスも理解することもできました。

💭 コンパイラ側で良しなにするのは難しいのかな、LAMS で警告してくれれば良いのかな。

引き続き、LookML 開発を妨げる課題があれば、解決していきます。💪

余談

Validate LookML をクリックすると、すぐ Validate LookML に戻ることがあるのですが、なんででしょう...?ファイル保存直後だとほぼ発生します。

looker

Validation が終わる時間くらいまで待つと 2 回クリックしなくて良いみたいです。🙄

looker2

追記: LAMS を使って wildcard include を禁止する

LookML の Linter として LAMS というものがあります。

developer.feedforce.jp

このカスタムルールを定義することで、今回のようなワイルドカード付きの include を禁止することが出来ます。

manifest.lkml にこのように書くだけです。

# LAMS
# rule: NO_WINC {
#  description: "Prohibit wildcard include to avoid increasing LookML verification time"
#  match: "$.files.*.include.*"
#  expr_rule: ($let file_path ($get ::project files ::path:2 $file_path))
#             ($if ($match "\\*" ::match)
#                 ($concat "Found wildcard include '" ::match "' in " ::file_path "")
#               true) ;;
# }

Customizing LAMS にさらりと書いてありますが、指摘されたファイル名を出す方法が分からなかったので、Issue #95 で質問したら分かりました。これは分からない。💦


  1. コメントと空行を除く

  2. .explore.lkml 10 個、.view.lkml 10 個、.layer.lkml 31 個