はじめに
こんにちは、バックエンドエンジニアをしている@sakam0cchan です。
いきなりですが、日々の業務で BigQuery を使っているのですが、
その中、直近 BigQuery の課金形態 についてチームで話があがりました。
そのときは「ふんふん」と聞きながらも、
- どんなプランがあるのか
- それぞれ何が違うのか
…といったことを、実はちゃんと理解できていなかったなと気づきました。
そこで、Google Cloud の書籍や公式ドキュメントを読みつつ、
BigQuery の料金体系と、その中でよく出てくる「スロット」について
自分なりに整理してみようと思います。
同じように
「オンデマンド?エディション?スロット???」
となったことがある方の参考になれば嬉しいです。
BigQuery の料金体系(ざっくり)
BigQuery ではストレージ料金とコンピューティング料金が主な料金となります。
ストレージ料金
今回、ストレージ料金はスロットと関係がないため、詳細は省略します。
(詳細は公式ドキュメント)
コンピューティング料金
コンピューティング料金は、大きく分けて二つあります。
オンデマンド料金
- 課金:スキャンしたデータ量
- 特徴
- BigQueey のデフォルト課金モデル
- スロットは意識しなくていい
- 実行時に表示される「処理されるバイト数」がそのまま課金対象
BigQuery は列指向型 DB のため、参照したカラム分だけがスキャンされ、その量に応じて課金されます。
BigQuery エディション(スロット課金)
- 課金:スロット数 × 利用時間
- 特徴
- 一定数のスロット(計算リソース)を確保して利用
- クエリの安定性やコスト予測性を重視したい場合に向いている
そもそもスロットって何?
スロットとは、BigQuery のクエリ実行時に使われる計算リソース(CPU 枠) のことです。
クエリを実行すると、BigQuery はクエリプランを作成し、その内容に応じてスロットを割り当てます。
お馴染みの実行画面でも確認することができます。
例:
クエリが「4000 スロット × 1 秒」を要求した場合、
利用可能な最大スロットが 2000 なら「2000 スロット × 2 秒」で実行されます。
このように、要求されたスロット数を満たせなくても
処理時間を伸ばすことでクエリ自体は実行可能となっています。
これをみると、「お、つまりはスロットが多ければ早く終わるのでは?」と考える人も多いと思います。
しかし、実はそうではありません。
先ほどの例ではスロットを一定スロットでの実行で表現しましたが、実際の BigQuery では、クエリは複数のステージに分かれて実行され、ステージごとに必要なスロット数は時間とともに変化します。
そのため、スロットは空いている → でもステージの依存関係によって使われない、といったことが起こります。
つまり、スロットを増やせば必ず処理時間が短くなる、というわけではありません。
一方で、BigQuery は並列クエリ実行時に
利用可能なスロットを動的に分配・調整することで、全体の待ち時間を最小化しています。
これが、高速な実行を担保できる秘密ということですね!👀
スロットの観点でみる オンデマンド料金 と BigQuery エディション の違い
では、ここでスロットの観点で料金形態の違いについて詳しくみてみましょう。
オンデマンド料金
- プロジェクトあたりの同時実行スロット上限は 基本 2000
- 一時的なバーストは可能だが、恒常的に超えることはできない
BigQuery エディション
この課題を解決できるのが、BigQuery エディションとなります。
BigQuery エディションでは、ベースラインと最大予約サイズを設定することができます。
- ベースライン
- 常に起動しているスロット数
- 最大予約サイズ
- クエリの状況に応じて自動的にスケールできる上限
この 2 つを組み合わせることで、
プロジェクトに合わせたスロット設計が可能になります。
パターン1: ベースラインと最大予約サイズを同じにする
- メリット
- 常に一定の使用が見込まれている場合に有効
- コストを抑えることができる
パターン2: ベースライン + 最大予約数を多く設定する
- メリット
- 基本のベースラインを担保しつつ、一時的な要求スロットの増加にも対応できる
プロジェクトごとに柔軟に調整できる のが BigQuery エディションの良いところですね。
もし仮想のチームで料金形態を選ぶとしたら?
以下のようなチームを想定してみます。
- 定期バッチが平日・休日問わず稼働
- 主に直近データの集計処理
- 平日の日中は、開発・調査目的でクエリを実行
- クエリの遅延や失敗は、業務影響がそこそこある
想定される負荷の特徴
この構成を踏まえると、BigQuery の負荷には次のような特徴がありそうです。
- クエリの発生タイミングが偏る
- 日中は開発用途で同時実行が増えやすい
- バッチと人手のクエリが重なる時間帯がある
- 常に高負荷ではない
- 深夜・早朝は比較的落ち着く
- 待ち時間がゼロである必要はないが、極端な遅延は困る
それぞれの料金体型を選択した際の懸念
オンデマンド料金
- 同時実行が増えた際、2000 スロット上限に引っかかる可能性がある
- 待ちが発生しても、事前に制御しづらい
コスト面では安心ですが、実行時間のブレが業務影響につながりそうです。
BigQuery エディション
- 常に大きなベースラインを持つと無駄が出やすい
- 最大予約サイズを大きくしすぎるとコストが読みづらい
小さめベースライン + 必要な際にスケーリング
そこで、以下の構成が現実的だと感じました。
- ベースライン
- バッチが安定して動く最低限のスロット数
- 「何も考えなくても詰まらない」状態を作る
- 最大予約サイズ
- 日中の開発クエリや一時的な負荷増加に対応
- 常時ではなく「必要なときだけ」使われる前提
この構成にすることで、
- 普段は無駄なスロットを抱えず
- ピーク時も極端な待ちが発生しにくく
- スロット不足が原因かどうかを切り分けしやすい
というバランスが取れそうだと感じました。
あとは実際のコストとの比較が肝になってきそうですね。
(ここまでは考慮できていないためご了承ください 🙇♂️)
最後に
今回、BigQuery の料金形態とスロットの関係についてまとめてみました。
書籍や公式ドキュメントをベースにした内容にはなりますが、
改めてまとめることで理解に落とし込み、実際の現場を想定して考えてみることで、より具体的に捉えることができました。
特に 「Google Cloudではじめる実践データエンジニアリング入門」 は、とても丁寧に噛み砕いて解説してくださっており、理解する上で何度も助けられました。
BigQuery や Google Cloud をこれから触る方だけでなく、仕組みを改めて整理したい方にもぜひおすすめしたい一冊です!
参考資料
*1 「Google Cloudではじめる実践データエンジニアリング入門」
https://amzn.asia/d/95DnH4H
*2 「BigQuery ドキュメント」
https://docs.cloud.google.com/bigquery/docs?hl=ja