【導入事例】Snowflake 導入支援。GA4 のデータを取り込むテーブルと、ロール・ウェアハウスを標準機能だけで設計したH社の導入準備の裏側
自社のWebサイトの利用状況を GA4 で計測しているH社。分析の基盤の Snowflake に GA4 のデータを集めるため、当社は Snowflake の導入支援として、取り込みの経路を比べたうえで、テーブルの層、入れ直しの手続き、ロールと権限、ウェアハウスと費用の上限、監視と受け入れの手順までを、各製品の標準の機能だけで設計しました。構築はこれからです。
本事例は、当社が支援している実際の案件をもとに構成しています。企業名と、お客様の環境にある製品の名前は伏せ、業種・規模・時期は一般化して記載しています。設計が済み、構築はこれからの段階のため、結果ではなく、設計で決めたこととその理由を紹介します。Snowflake の導入で、データの取り込みやテーブル・ロール・ウェアハウスの設計を検討する際の参考にしていただければ幸いです。
対象:自社のWebサイトのアクセス解析のデータ(GA4)
支援の内容:Snowflake の導入支援。取り込みの経路の比較、データベースとテーブルの設計、ロールと権限、ウェアハウスと費用の上限、監視と受け入れの手順
いまの段階:設計が済み、構築はこれから
使った製品:GA4、BigQuery、Cloud Storage、Snowflake(いずれも標準の機能だけ)
GA4 のデータを Snowflake に集めたい、という相談
H社は、自社のWebサイトの利用状況を GA4 で計測し、イベントの生データを BigQuery に日次で書き出しています。分析の基盤には Snowflake を使うことにしており、GA4 のデータもそこに集めたい、というのが相談の出発点です。
当社が設計書にまとめたのは、GA4 のデータを入れる経路だけではありません。データベースとテーブルの形、ロールと権限、ウェアハウスと費用の上限、Cloud Storage とのつなぎ方、毎日の監視と受け入れの手順まで、Snowflake を使い始めるときに決めることを一通り扱っています。
設計の条件は2つありました。1つ目は、各製品の標準の機能だけで組むことです。常駐するサーバーや外部のスケジューラーを持たず、決まった時刻に動かす仕組みは BigQuery と Snowflake の中に閉じます。2つ目は、BigQuery 側で新しく増える費用を無料枠の中に収めることです。
GA4 のデータ:イベントの生データを BigQuery に日次で書き出している
Snowflake:分析の基盤として使う。GA4 のデータはまだ入っていない
条件:各製品の標準の機能だけで組む/BigQuery 側で増える費用は無料枠の中に収める
取り込みの経路を比べる
GA4 のデータを Snowflake に入れる方法は、大きく3つあります。Snowflake が用意している GA4 用のコネクタ、市販のデータ連携サービス(ETL)、各製品の標準の機能をつないで組む方法です。コネクタには、イベントの生データを扱う「Raw Data」と、集計済みのレポートを扱う「Aggregate Data」の2種類があります。名前が似ているので、最初に区別しておくと話が早くなります。
GA4 のデータを Snowflake に入れる3つの経路
経路 1
Snowflake の GA4 用コネクタ
- Raw Data:イベントの生データ。GA4 から直接ではなく、BigQuery に書き出された表を読む
- Aggregate Data:GA4 のレポートの形に集計した数字
今回の判断:Aggregate Data は集計済みで、欲しい生データではない。Raw Data もアカウントにアプリとして入れて使うもので、標準の機能だけという条件から外れるため見送り
経路 2
データ連携サービス(ETL)
- サービスによって、レポートを取る型と、BigQuery の書き出しを読む型がある
今回の判断:外部のサービスの契約と利用料が要り、標準の機能だけという条件に合わない
経路 3(採用)
標準の機能で組む
- BigQuery から Cloud Storage にファイルで書き出し、Snowflake が読み込む
- 入るのはイベントの生データ
今回の判断:動かす仕組みが BigQuery と Snowflake の中に収まり、書き出しのクエリは BigQuery の無料枠の中に収まる見込み
図:構成を簡略化して描いています(画面や実際のデータではありません)。
Raw Data のコネクタも、GA4 から直接データを受け取るのではなく、BigQuery に書き出された表を読む仕組みです。どの経路でも GA4 からの書き出しが出発点になるため、H社ですでに有効になっている日次の書き出しをそのまま使います。GA4 から BigQuery に書き出したデータは、あとから出し直すことができません。BigQuery 側の表は消さずに残し、取り込みをやり直したいときの元にします。
GA4 のデータが Snowflake に届くまで
決まった時刻に動かす仕組みは、BigQuery の定期実行と Snowflake のタスクの2つだけ
図:構成を簡略化して描いています(画面や実際のデータではありません)。
データベースを2つの層に分ける
Snowflake の中は、1つのデータベースに2つのスキーマを置いて層を分けました。Cloud Storage から届いたデータをそのまま受ける「着地層」と、分析で使う形に整える「整形層」です。
層を分けたのは、GA4 のデータの形が変わっていくためです。イベントに付くパラメータの組み合わせはサイトの実装ごとに違い、計測する項目を増やせば中身も変わります。日付ごとのファイルの列の構成がそろうとは限りません。着地層では各行の中身を丸ごと半構造化データの列(VARIANT)に入れるため、読み込みの段階では列の違いを気にせずに済み、分析で使う列の定義は整形層に寄せられます。後から層を分けると作り直しになるので、最初から分けました。
Snowflake の中の層と、それぞれに置くもの
ファイル → 着地層 → 整形層の順にデータが流れる
Cloud Storage の上
外部ステージ
- 日付ごとのフォルダにある Parquet のファイルを指す
- 鍵やパスワードは持たせない
作る単位:分析するサイトごと
1段目の層
着地層(テーブル)
- 各行の中身を丸ごと VARIANT の列に入れる
- 日付・元のファイル名・取り込んだ時刻の列を足す
変えないもの:列の形。GA4 の項目が増えても直さない
2段目の層
整形層(ビュー)
- よく使う項目を列として取り出す
- パラメータの入れ子を展開し、型をそろえる
- 時刻を日本時間に直す
読む人:分析する人
図:構成を簡略化して描いています(画面や実際のデータではありません)。
整形層は、実体のあるテーブルではなくビューにしました。Snowflake の通常のビューは、参照されたときに定義のクエリを実行し、結果を保存しません。着地層は毎日入れ直すため、整形した結果をテーブルとして持つと、そのたびに作り直す処理が別に要ります。今回のデータ量ならビューで足りると見て、遅さが気になった時点で実体のあるテーブルに切り替える順番にしています。
分析するサイトが増えたときのことも考えて、オブジェクトを、サイトに共通のもの(ウェアハウス、スキーマ、ロール、Cloud Storage との連携、バケット)と、サイトごとのもの(ステージ、着地のテーブル、取り込みの手続き、タスク、ビュー)に分けて名前を付けました。サイトを足すときは、サイトごとのものを作るだけで済みます。
テーブルの設計と、入れ直しても重ならない取り込み
着地層のテーブルの列は4つです。イベントの日付、各行の中身を丸ごと入れる VARIANT の列、元のファイル名、取り込んだ時刻です。元のファイル名は、Snowflake が読み込み中のファイルの名前を返すメタデータの列から入れます。取り込んだ時刻は、内部では UTC で持ち、時刻そのものがタイムゾーンの設定に左右されない型にしました。
整形層のビューでは、パラメータの入れ子を展開して列にします。GA4 のパラメータの値は、文字列・整数・小数などの型ごとに別の欄に入ります。どのパラメータを列にし、どの欄から読むかは、実際に届いているパラメータの名前と件数を数えてから決める手順にしました。時刻は、GA4 が UTC で記録しているため、変換元が UTC であることを明示して日本時間に直します。
取り込みでいちばん気を配ったのは、同じデータを入れ直しても行が重ならないことです。Snowflake の通常のテーブルでは、主キーや一意の制約を定義しても強制されません。重なりを防ぐ仕組みは、取り込みの手順の側に持たせる必要があります。
そこで、日付を単位に「消してから入れる」形にしました。取り込みの手続き(ストアドプロシージャ)が、直近の数日分について日付ごとに行を消し、その日付のファイルを読み直します。Snowflake の読み込み(COPY)は、一度読んだファイルを既定では飛ばすため、読み直すときは飛ばさない指定を付けます。
直近の数日分を毎日やり直すのは、GA4 の日次の表が、その日のあとも数日のあいだ更新されるためです。遅れて届いたイベントを取り込めるよう、BigQuery からの書き出しの側でも、同じ数日分を日付ごとに上書きで出し直す組み方にしています。
毎日の入れ直しの流れ
遅れて届いたイベントも、次の日以降の入れ直しで反映される
図:構成を簡略化して描いています(画面や実際のデータではありません)。
毎日の取り込みは、Snowflake のタスクが決まった時刻にこの手続きを呼び出します。時刻はタイムゾーンを明示した書き方で指定します。タスクは作った時点では止まっているため、読み込みの疎通を確かめてから動かし始める手順にしました。
日付の計算にも決めごとを置きました。Snowflake のアカウントのタイムゾーンは、既定では日本時間ではありません。現在の日付を返す関数はこの設定に従うため、そのまま前日を計算すると、実行する時刻によっては日本の日付と1日ずれます。アカウントの設定を変えると、同じアカウントのほかのクエリや時刻の表示にも影響するため、設定は変えずに、手続きの中で日本時間の日付を明示して計算します。手作業でクエリを流すときは、そのセッションだけタイムゾーンを切り替えます。
ロールと権限:誰が何を使えるか
Snowflake では、権限はロールに付け、ロールをユーザーに付けます。今回の設計で新しく作るロールは、取り込み用の1つです。
土台になるもの、つまりウェアハウス、データベースとスキーマ、取り込み用のロール、Cloud Storage との連携、費用の上限は、Snowflake に最初からある管理者のロールで一度だけ作ります。Cloud Storage との連携(ストレージ統合)と費用の上限(リソースモニター)は、作れるロールが限られているものです。管理者のロールはアカウントでいちばん強い権限を持つため、使うのは最初の準備だけにし、毎日の取り込みや自動の処理には使いません。Snowflake のベストプラクティスでも、自動化のスクリプトにはこのロールを使わないよう勧めています。
どのロールが何を使えるか
権限はロールに付け、ロールをユーザーに付ける
最初の準備だけ
管理者のロール(最初からあるもの)
- ウェアハウス・データベース・スキーマを作る
- 取り込み用のロールを作り、権限を付ける
- Cloud Storage との連携と、費用の上限を作る
毎日の処理では:使わない
毎日の取り込み
取り込み用のロール
- 取り込み専用のウェアハウスを使う
- 着地層にテーブル・ステージ・手続き・タスクを作る
- 整形層にビューを作る
- 自分が持つタスクを動かす
付ける先:運用を担当する人のユーザー
分析
分析する人
- 整形層のビューを読む
- 取り込みとは別のウェアハウスで動かす
この設計では:分析する人向けのロールは新しく作らない
図:構成を簡略化して描いています(画面や実際のデータではありません)。
取り込み用のロールには、必要なものだけを付けました。取り込み専用のウェアハウスを使う権限、データベースを使う権限、着地層でテーブル・ステージ・ファイル形式・手続き・タスク・ビューを作る権限、整形層でビューを作る権限、Cloud Storage との連携を使う権限、自分が持つタスクを動かす権限です。Snowflake でクエリを実行するには、ウェアハウスを使う権限と、データベースとスキーマを使う権限が要ります。タスクを動かす権限はアカウント単位の権限で、管理者のロールから付けます。
スキーマの中のオブジェクトは、すべて取り込み用のロールで作ります。Snowflake では、オブジェクトを作ったロールがその所有者になり、所有者のロールはそのオブジェクトに対するすべての権限を持ちます。作るロールをそろえておけば、行を消して入れ直す処理からタスクの実行まで、取り込み用のロールだけで完結します。
取り込み用のロールは、運用を担当する人のユーザーに付けます。分析する人が読むのは整形層のビューで、分析する人向けのロールは、この設計では新しく作っていません。
ウェアハウス・費用の上限・Cloud Storage とのつなぎ方
ウェアハウスは、取り込み専用のものを用意しました。分析に使うウェアハウスと分けておけば、取り込みにかかったクレジットを分けて測れます。大きさはいちばん小さいサイズにし、処理が終わると短い時間で止まる設定、処理が来たら自動で動き出す設定、作った時点では止まっている設定にしました。最後の設定は、作った直後から動き出す既定の動きを避けるためです。
Snowflake のウェアハウスの料金は秒単位ですが、動き出すたびに最低60秒分がかかります。取り込みは1日1回にまとめ、動き出す回数を増やさない組み方にしています。
費用の歯止めには、リソースモニターを使います。月ごとのクレジットの上限を想定よりかなり大きく取り、途中の段階で通知を出し、上限に達したら取り込みのウェアハウスを止める設定です。止め方は、実行中の処理が終わってから止まるほうを選びました。上限はふだんの運用で当たる値ではなく、設定の誤りや想定外の繰り返しで費用が膨らんだときに止めるための歯止めです。
Snowflake が Cloud Storage のファイルを読むときは、ストレージ統合を使います。ストレージ統合を作ると、Snowflake 側で読み取り用のサービスアカウントが用意され、Cloud Storage の管理者は、そのアカウントにバケットを読む権限を付けます。鍵のファイルを発行して受け渡す必要はありません。ストレージ統合で読める場所は、GA4 のファイルを置くバケットの中のパスに絞りました。
ファイルを読む入口として外部ステージを作り、ファイル形式は Parquet を指定します。ステージの URL は「gcs://」で始めます(「gs://」ではありません)。設計書にも、間違えやすい所として書いています。
ストレージ統合は、作り直さない前提にしています。作り直すと、それを参照しているステージとのつながりが切れ、ステージごとに設定し直す必要があるためです。読める場所を変えたいときは、作り直さずに設定を変更します。
毎日の監視と、受け入れの確かめ方
毎日の運用で見るものは、次の表のとおりです。
| 見るもの | 見方と、分かること |
|---|---|
| イベントの件数 | 前の週の同じ曜日と比べる。計測タグの不具合や計測の停止、書き出しの上限に近づいたことが分かる |
| タスクの結果 | 実行の履歴で、成功以外の結果が出ていないかを見る。読み込みの失敗、権限の外れ、ステージの設定の食い違いが分かる |
| 前日分の到着 | 決まった時刻に、前日の行が入っているかを見る。書き出しの遅れや失敗が分かる |
| BigQuery の保存量 | 月に一度、推移を見る。保存の費用の増え方が分かる |
うまくいかないときの切り分けも、設計書に表で書いています。直近の数日だけ件数が少ないのは、遅れて届くイベントがあるためで、異常ではありません。特定の日が丸ごと欠けていて、BigQuery にもその日の表が無い場合は、GA4 から出し直せないため、欠けた日として記録します。タスクが失敗し続けるときは、ステージの中のファイルが Snowflake から見えるかどうかから確かめます。見えなければ、Cloud Storage 側の権限を疑います。
構築のあとは、次の4つを確かめて受け入れる手順にしました。
受け入れで確かめること
1つ目
件数が合う
- いくつかの日を選び、BigQuery の表と Snowflake の行数を比べる
合格:同じ数になる
2つ目
日付がつながる
- 入っている日付の数と、欠けた日の一覧を突き合わせる
合格:欠けた日を除いて途切れない
3つ目
重なりがない
- 同じ日の行数を、元のファイル名ごとに数える
合格:同じファイルが二重に入っていない
4つ目
入れ直しても変わらない
- 取り込みの手続きを続けて2回動かす
合格:2回目のあとも件数が変わらない
図:構成を簡略化して描いています(画面や実際のデータではありません)。
いまの段階と、これから
設計書と構築の手順はまとまっており、構築と稼働はこれからです。
構築は、Snowflake 側で先に進められるものから始める段取りです。ウェアハウス、データベースとスキーマ、ロール、着地のテーブル、ファイル形式、取り込みの手続きとタスク、費用の上限は、Cloud Storage 側の作業を待たずに作れます。バケットが決まっている必要があるのはストレージ統合から先で、ステージの確認と読み込みは、Cloud Storage 側で権限が付いてから行います。タスクを動かし始めるのは、読み込みの疎通を確かめたあとです。
段階:設計が済み、構築と稼働はこれから
設計したこと:取り込みの経路、データベースの層とテーブル、入れ直しの手続き、ロールと権限、ウェアハウスと費用の上限、Cloud Storage とのつなぎ方、監視と受け入れの手順
受け入れ:件数・日付のつながり・重なり・入れ直しの4点を確かめる
当社の Snowflake の導入支援はSnowflake 導入支援のページで、アクセス解析のデータの整備はアクセス解析・マーケティングデータ支援のページで紹介しています。GA4 から BigQuery への書き出しで気をつけることは、ブログのGA4をBigQueryに出してAIで分析する前ににまとめています。
※本事例は、当社が支援している実際の案件をもとに構成しています。設計が済み、構築はこれからの段階です。企業名と、お客様の環境にある製品の名前は伏せ、業種・規模・時期は一般化して記載しています。