Lookerでキャッシュを設定して不要不急のDBアクセスを減らす

不要不急のブログ執筆
2020.04.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

奈良県でリモートワーク中の玉井です。

Lookerをはじめ、多くのBIツールは、最終的にはデータ元に対してSQLクエリを実行する仕組みになっています(たぶん)。ダッシュボードを見る側は気にしないかもしれませんが、データ元(DB等)を管理している側は「大量のクエリとか来られたら死ぬ…」みたいな気持ちを抱いているかもしれません。実際、負荷が強いクエリが沢山来ると、DBのレスポンスが停滞したりして、(DBが関わる)業務全体が滞ってしまうかもしれません。

しかし、本当にダッシュボード(グラフ)を表示するたびに、必ずSQLクエリを実行する必要があるのでしょうか。データ元が更新されていなければ、取得される結果は同様のはずで、データ元は変わっていないと知りながら、毎度毎度アクセスすることは、無駄ではないでしょうか。多くのBIツールもそれはわかっているので、同様の結果はキャッシュとして持つ機能を備えています(たぶん)。そして、それはLookerも同様です。

というわけで、今回はLookerのキャッシュ機能を使ってみました。

公式情報

Lookerでキャッシュを使うということ

冒頭で述べている通り、Lookerでも、キャッシュを使うことで、不要不急のDBアクセスを減らすことができます。

キャッシュの設定方法

シンプルに言うと、2つのパラメータをLookMLで定義します。

datagroup

キャッシュポリシーを定義します。

キャッシュポリシーってのは、キャッシュのルールみたいなものです。ここで設定するのは、大まかに説明すると「キャッシュを持ち続ける期間(max_cache_age)」と「キャッシュを更新する条件(sql_trigger)」を、このパラメータ内で定義します。

modelファイルに記述します。

datagroup: 名前 {
  label: "ラベル名"
  description: "説明文"
  max_cache_age: "24 hours"
  sql_trigger: SELECT max(id) FROM my_tablename ;;
}

max_cache_age

キャッシュされる期間を定義します。上記の例だと、このポリシーが適用されているクエリは、キャッシュが発行されてから24時間はキャッシュが効きます。24時間を過ぎてから、クエリが実行された場合は、実際にDBへアクセスし、また新しいキャッシュを生成する…という感じです。

sql_trigger

キャッシュが更新される条件をSQLクエリで定義します。クエリは、1列1行の結果を返す必要があります(要するに1個のデータだけとってくるクエリ)。上記の例では、IDの最大値を取得するようになってるので、データ側で新しいIDが追加された場合、このトリガーが働いてキャッシュを更新します。データ側の更新ルールを把握した上で記述する必要がありますね

「トリガーとなっているクエリ自体が実行される間隔は設定できるのか?」という疑問があるかと思いますが、それについては下記をどうぞ。

※Connectionの設定で指定します。

persist_with

上記で設定したポリシーを適用する役目がこちら。適用する単位はExplore単位とお考え下さい(そのExploreを使ったLookやダッシュボードを表示する際に実行されるクエリに対して効く)。datagroupはmodelファイルに記述するのですが、modelファイルに定義されているExplore全てに対してデフォルト設定として適用したり、特定のExploreだけに適用したりできます。

modelファイル全体

modelファイルにドカッと書きます。

persist_with: 適用したいdatagroupの名前

特定のExplore

explore: 名前 {
  persist_with: 適用したいdatagroupの名前
}

やってみた

下記で作成したダッシュボードに対して設定します。

この記事に詳細は書いていますが、このCOVID-19ダッシュボードのデータ元は、他社が提供しているSnowflakeのデータシェアリングです。で、このデータは1日1回更新されます。時刻はわからないのですが、下記のように設定してみます。

datagroup: covid19_default_datagroup {
  sql_trigger: SELECT max(LAST_UPDATE_DATE) FROM "PUBLIC"."WHO_SITUATION_REPORTS" WHERE country = 'Japan';;
  max_cache_age: "24 hour"
}

persist_with: covid19_default_datagroup

1日1回の更新なので、クエリ保持期間は24時間としました。sql_triggerですが、データ側に更新日付のカラムがあったので、それの最大値をトリガーにしています。また、このExploreを使用しているダッシュボードは、日本のデータのみを可視化しているので、あくまで「Japanのデータの最終更新日付が変わったらキャッシュも更新」という風にしています。

これで、24時間はキャッシュを参照&データ側が更新された場合はDBにクエリを実行して最新データを表示…という形にすることができました(体感スピードですが、Snowflake側がそもそもそんなに遅くないので、正直ようわからんかった…が、キャッシュが効いてるはず)。

おわりに

今回はキャッシュについてだけ書いたのですが、実はこの設定に関連する、もう一つの重要要素に「派生テーブルの永続化」があります。また永続派生テーブルについても、ブログにしたいと思います。