BigQueryを軸にした大規模データ分析基盤の設計をする前に知っておきたいこと

Google-Cloud-Platform Dec 18, 2021

この記事は BigQuery Advent Calendar 2021 のカレンダー2 12/18の記事になります。

Calendar for BigQuery | Advent Calendar 2021 - Qiita
Calendar page for BigQuery.

はじめに

自分はとある会社のサーバサイドエンジニアだったのですが、ひょんなことからBigQueryを使ったデータ基盤の開発プロジェクトの立ち上げに参画しました。
そのプロジェクトで、BigQueryを軸に大規模なデータ分析基盤を作成するにあたって

  • 要件定義
  • 全体設計
  • 環境構築
  • データパイプラインの実装
  • データ分析
  • 関連システムの開発

などを一通り行いました。

開発メンバー2人で始まったプロジェクトも4年が経過し、今や10人以上のエンジニアが参加するプロジェクトになりました。
データの規模は主にテキストデータでもうすぐ10PB(ペタバイト)になります。
また、データの連携をしているシステムは100以上になります。

そのぐらいの規模のデータ分析基盤になっても問題なく利用できるBigQueryなのですが、データ基盤を設計、開発するうえで注意すべきポイントや注意点などをまとめたいと思います。

個人的にはかなりハードにBigQueryを使い倒しているプロジェクトだと思うので、誰かの参考になればと思います。
ただし、あくまで状況によって最適解は異なるので、あくまで参考までにとどめてもらえればと思います。

テーブルは分割テーブルを採用する

BigQueryはスキャン容量に対して課金されるため、"テーブルを日付ごとに分割して取り出せるようにする"というのはBigQueryにデータを貯める上での基本になります。
その際、分割方法に日付別テーブルと分割テーブルがあります。
日付別テーブルとはテーブル名の末尾に _yyyymmddをつけたもので、
分割テーブルは一つのテーブルが日付ごとに取り出せるように分割(パーティション化)されているものになります。

小規模であってもパフォーマンスの観点で分割テーブルが望ましいですが、
自分の案件の場合、送られてくるデータの構造が頻繁に変わるため日付別テーブルを採用しました。
しかし、その結果数年経過した際にデータセット内のテーブル数が50万テーブルを超えてしまい管理テーブルが使えないデータセットが出てきてしまいました。
また、日付別テーブルをワイルドカード参照する場合にも1000テーブルまでしかサポートされていないので、3年分以上のデータを参照する場合にも注意が必要です。

解決策としては分割テーブルに直接追加していくのが望ましいです。
しかし、変更が多発するようなデータの場合は日付別テーブルで一時的に持つ形として、
最終的には分割テーブルとして保持するでも良いと思います。
また、使わないデータをArchivesクラスにしたCloud Storageに退避させることでテーブルを減らす事を検討しても良いと思います。
管理するテーブル数を減らしつつコストも削減できます。

プロジェクトは細かく分割する

BigQueryのジョブのクオータやスロットはプロジェクト単位になっいることが多いです。
なので、データ基盤を利用するシステムごとにプロジェクトを分割するのが良いと思います。
一つのプロジェクトで全てを行おうとした場合、スロット消費や並行ジョブ数などを管理しないとクオータに引っかかってクエリが失敗するようになります。
中でも気をつけないといけないのがバッチモードのクエリジョブになります。

バッチモードのクエリジョブというのは優先度が低く設定されている代わりに同時実行数の制限がゆるいモードになります。
ただし、このバッチモードのクエリの他に通常モードのインタラクティブクエリが常時実行されているようなプロジェクトの場合このバッチモードのジョブに優先度が回ってこず、最終的にテイムアウトになり失敗する場合も出てきます。
なので、バッチモードがあるからと安心して一つのプロジェクトで済まさず、用途・目的単位で分けるのが望ましいと思います。
また、BigQueryではデータセットの上位概念がプロジェクトとなっているので、プロジェクトを分けることでデータセットの管理も楽になります。

ちなみに、BigQueryでは別プロジェクトのデータセットもユーザに参照権限をがあればSQLで参照できるため分割したことでデータ分析が不便になることはあまりありません。
また、できることならフラットレートを用いて、スロットを専有してしまうのが安心だと思います。
ただし、このあたりは費用と相談になってきます。

データカタログの目星をつけておく

データをひたすら投入して行くと、いずれ管理しきれなくなります。
これはBigQueryだけでは回避できない問題だと思います。

自分の案件では、ある時調査するとテーブル数が1000万以上ありました。
※レコード数ではありません
この数になってからデータカタログを導入して対応していくのは調査にもコストがかかってしまうので、できれば小規模な段階からある程度目星をつけて構築していくのがいいかなと思います。

ちなみにテーブル数が1000万を超えてもBigQueryは全く問題なく処理できます。
スケーラブルに容量が増えていっても自動で対応できるがゆえの問題かもしれません。

使い方の教育を広く行う

BigQueryのデータ基盤を広く社員に使ってもらうというのは良いと思います。
ですが、BigQueryの従量課金について把握した上で利用しなければ費用面で危ないです。

自分の関わった案件ではスキャン領域が数TBのクエリが連発するという事がありました。
パーティション指定をSQLに強制してクエリにある程度の制限をかけることもできます。
ですが、一番は利用者のリテラシー教育やサポートを行うのが大事だと思います。

まとめ

  • テーブルは分割テーブルにして最小限にする
  • 役割ごとにプロジェクトを分割する
  • データカタログも検討する
  • クエリを流すユーザに教育とサポートを行う

総括

正直、10PB近くのデータをひたすら投入しても設定不要で格納できて、パフォーマンスも落ちないデータベースは驚異だと思います。
おかげでデータ保管や処理手法について悩まずに専念すべき問題に集中できたと思います。
ただし、なるべくベストプラクティスに沿った設計や運用をしなければ他の場所で問題が発生します。
なので、この記事が誰かの助けになることを願います。

※ただし、この記事を読んで行った結果については責任を負いません。

参考資料

Quotas and limits | BigQuery | Google Cloud
Describes the quotas and limits that apply to BigQuery jobs, queries, tables, datasets, DML, UDFs, API requests, etc.

Tags