本日の Google Data Cloud & AI Summit にて BigQuery に対する超有益なアップデートが発表されました!
価格体系の変更について、有効的に活用すればコストの最適化ができるものになります。
ヘビーユーザーは当然のこと、ライトユーザーやこれから検証のために少し触ってみたいような方々に向け、
おさらいも交えながら説明をさせていただきたいと思います。
また、弊社内で実際に利用している BigQuery のデータセットに対し、今回の変更でコストがどのように最適化できるのかも紹介させていただきます。

価格体系の変更

まずは、おさらいとして BigQuery の価格体系を解説します。

BigQuery のアーキテクチャはストレージとコンピューティングに分離されています。伴って、BigQuery の料金は、Storage pricing(ストレージ料金)と呼ばれるストレージに対するコストと、Analysis pricing(分析料金)と呼ばれるコンピューティングに対するコストの合算となります。

Storage pricing は、BigQuery に格納するデータサイズに対してかかる費用です。データは過去90日以内に更新のあったテーブルを含む Active Storage(アクティブストレージ)と、90日間更新のなかった Long-term Storage(長期保存ストレージ)に自動的に分類され、それぞれの単価に応じたコストが発生します。

Analysis pricing は、クエリでスキャンするデータ数に応じて発生するオンデマンド型と、仮想 CPU にあたるスロットを予約し、対象に割り当てることで、割り当て済みのスロットで処理できる範囲で好きなだけスキャンできる Flat Rate(定額料金)型の2種類があります。

今回のアップデートでは、ストレージとコンピューティングの両方に対して変更が入ります。

ストレージに対する価格体系の変更

従来は、論理データサイズに対して料金がかかっていました。
しかし実際の BigQuery の実装では、データは圧縮されて保存されているため、論理サイズよりも少ないデータサイズになっています。これを物理サイズといいます。
今回の料金改定を受けて、論理データサイズではなく、物理データサイズで課金されるようになります。データサイズに対する単価は若干上がりますが、データの圧縮率はその割合よりも圧倒的に高いため、一般的なデータであれば、ストレージに対する料金は大幅に料金が下がると考えられます。

昨年、Preview リリースされていた機能ですが、BigQuery Editions の一部として GA となります。

この変更に伴い、これまではコストがかからなかった、Time Travel(タイムトラベル)で利用するストレージ、および Time Travel の期間終了後に一定期間保持する Fail Safe のストレージに対し、Active Storage 相当の金額がかかるようになってしまうようになります。
Time Travel とは、Window で指定した期間(デフォルト7日間)の任意の時点にロールバックできる機能です。
ただ、更新や削除がよほど多くないデータセット以外では、そこまでインパクトは大きくないです。Time Travel はその期間を指定できるため、要件次第では期間を短縮することでコスト削減も可能です。

後ほど、確認の仕方および実際の環境での見積もり結果を記述します。きっと驚いていただける結果になっています。

Physical Storage を使える Orgizaion(組織)は、2023/3/30 現在で、以下の Orgizaion に限定されます。

  • Editions のみ利用
  • Editions とOn-demand の併用
  • On-demand のみ利用

つまり、Orgization 全体で Flat Rate を未使用または Editions に移行したお客様が Physical Storage を利用できます。

なお、本変更はあくまで課金計算をどのようにするかだけの変更であり、もともとデータは圧縮して保存されています。そのため、この変更に伴って、サービスの瞬断やパフォーマンス劣化は発生しません。

コンピューティングに対する価格体系の変更

コンピューティングに対しても、オンデマンドと Flat Rate 双方に大きな価格体系の変更があります。

まず、オンデマンドが約25%の値上がりになります。機能的には変更はありません。
この点だけであればネガティブに見えてしまいますが、本題はこの後です!

Flat Rate は廃止され、新たに Editions というプランが誕生します。これが、今回のアップデートの目玉です。
Flat Rate はスロットと呼ばれるコンピューティングリソースを予約。

Editions には、Standard, Enterprise, Enterprise Plus の3種類から選択することができます。
従来のFlat Rate は、月単位のコミットメントの場合、最小購入単位が100スロット、東京リージョンでは月間$2,400と、ある程度利用されている環境でないとコスト的に見合わないものでした。Flex Slots という最小限のコミットメントでも、200スロットの1時間単位から($20)であることに加え、適切に使いこなすには、予約と割り当てに対するオペレーションが必要でした。
Editions のStandard の場合であれば、後述する Slots Autoscaling の登場により、東京リージョンで1スロット時間あたり$0.051と、小規模な用途でも十分検討可能なものになりました。
また、Enterprise 以上においては1年間または3年間のコミットプランもあり、より安く利用することも可能です。

Editions の活用によるコスト最適化の凄まじさも後ほど実例で示します。

各オプションに付与される特典などの詳細は公式サイトでの案内を待つとして、本ブログでは BigQuery AutoScaler というオートスケーリング機能について紹介をさせていただきます。BigQuery AutoScaler は Standard エディションから利用可能になります。

BigQuery AutoScaler

こちらも Pre-GA の Slots Autoscaling に該当します。
前述のとおり従来の Flat Rate は、使用するスロットを予約購入することでスキャンし放題になるプランでした。利用用途によっては非常にコストを効率化できるものですが、例えば、月初のバッチ処理で大量のクエリを流しているようなケースの場合、月の平均値を元に購入するスロットを決めてしまうと、処理時間がオンデマンドと比べて大幅に遅くなることもあります。

BigQuery AutoScaler はこの弱点をカバーする機能です。
文字どおり、動的にスロットが割り振られるので、利用状況にバラツキがある場合も、性能を維持しつつ、利用していない期間のコストを下げることができます。

例えば、上記グラフの青い折れ線グラフのような利用状況があったとします。
AutoScaler は利用状況に合わせて、自動的にスロットをスケールしてくれます。100スロットという小さな単位で細かく適用されるところが特徴になります。

スケールにはウォームアップのタイムラグがあります。これをカバーするための機能として、Baseline があります。Baseline を指定しておくことで、最低限の性能を常時確保することが可能です。上記グラフの緑の破線のように基本的に利用されているラインで Baseline を確保しておいた方がよさそうです。
一方、1日の特定の時間しか使っていない環境では、Baseline をゼロにするといった戦略も有効です。

Max Number Slots も非常に強力な機能です。誤ったスキャンをかけてしまい、BigQuery の料金が跳ねてしまったという声を何度か聞いたことがあります。Max Number Slots を設定しておくことで、Max Number Slots 以上のスケールはしないため、スキャンの実行時間は長くなりますが、このような事故を減らすことができます。上記グラフのオレンジの破線あたりが候補となります。

コスト見積もり

それでは、手元にある実際の環境を元に、今回の改訂によりコストにどのような影響がでるのかを確認してみます。

Storageのコスト

まずは、Storage コストについてです。
ストレージの使用量は、INFORMATION_SCHEMA.TABLE_STORAGE_BY_* から得ることができます。
以下は、実際に使ったクエリとその実行結果になります。ご参考にいただく場合は、リージョンに合わせて単価などを適宜修正してご利用ください。英語側ではすでに物理データサイズでの単価も公開されています。
なお、Time Travel に使用されたバイト数も active_physical_bytes に包含されているため、考慮済みの金額になります。Fail Safeについての情報は見つけることができなかったため、別途加算される可能性はありますが、Time Travel で使用するバイト数相当と予想されます。

DECLARE active_logical_pricing, longterm_logical_pricing, active_physical_pricing, longterm_physical_pricing numeric;
SET active_logical_pricing = 0.023;
SET longterm_logical_pricing = 0.016;
SET active_physical_pricing = 0.052;
SET longterm_physical_pricing = 0.026;


SELECT
 ROUND(SUM(total_logical_bytes/POW(1024, 3)), 2) as total_logical_gigabytes,
 ROUND(SUM(total_physical_bytes/POW(1024, 3)), 2) as total_physical_gigabytes,
 ROUND(SUM(total_logical_bytes)/SUM(total_physical_bytes), 2) as compression_ratio,
 ROUND(SUM((active_logical_bytes/POW(1024, 3)) * active_logical_pricing), 2) as total_logical_prices,
 ROUND(SUM((active_physical_bytes/POW(1024, 3)) * active_physical_pricing), 2) as total_physical_prices,


FROM
 `region-asia-northeast1`.INFORMATION_SCHEMA.TABLE_STORAGE_BY_PROJECT

なんと、手元にあった環境でのストレージ費用は10分の1以下に!

Fail Safe 分が加算される可能性はありますが、そこまで大きな差は出ないと予想されます。

大きなものではなかったため、実際の金額としてはインパクトはそうではなかったですが、大規模なデータを保存している分析基盤などでは、これは大幅なコスト削減になりそうです。

コンピューティングのコスト

まずは直近1ヶ月間のオンデマンドでの使用料金を見積もってみます。

DECLARE ondemand_pricing numeric;
SET ondemand_pricing = 6;


SELECT
 ROUND(SUM(total_bytes_billed/POW(1024, 4)), 2) as total_gigabytes_billed,
 ROUND(SUM((total_bytes_billed/POW(1024, 4)) * ondemand_pricing), 2) as ondemand_price,


FROM
 `region-asia-northeast1`.INFORMATION_SCHEMA.JOBS
WHERE
 creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 31 DAY) AND CURRENT_TIMESTAMP()
 AND job_type = 'QUERY'
 AND end_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY) AND CURRENT_TIMESTAMP();

結果はこのようになりました。ストレージ費用と合わせて、大体、Billing ダッシュボードで確認できる金額と同じようなものです。

では、これを Editions に適用することでコストがどう変わるのでしょうか?

まずは、slot 利用状況の確認です。
AutoScale では100刻みで slot が追加されるため、以下のようなクエリで利用状況を確認します。分単位でオートスケールが動くものとの想定での計算です。

SELECT
 TIMESTAMP_TRUNC(jbp.period_start, MINUTE) AS usage_hour,
 CEILING(SUM(jbp.period_slot_ms) / 100) * 100 AS slot_usage
FROM
 `region-asia-northeast1`.INFORMATION_SCHEMA.JOBS_TIMELINE_BY_PROJECT jbp
WHERE
 (jbp.statement_type != "SCRIPT" OR jbp.statement_type IS NULL)  -- Avoid duplicate byte counting in parent and children jobs.
 AND jbp.period_start BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 31 DAY) AND CURRENT_TIMESTAMP()


GROUP BY
 usage_hour
ORDER BY
 usage_hour ASC

不定期に実行されているものが散見されましたが、ほとんどが、毎日4時に定期的にスキャンされているものとなり、まったく slot が使われていない時間がほとんどでした。
そのため、Baseline はゼロで見積もります。
(折れ線グラフは、サクッと可視化したかったので、分刻みの結果のゼロ埋めはしていないので参考まで)

1ヶ月間で、6,443,900/slot msecの利用がありました。
東京リージョンの Standard 価格である$0.051/slot hour で計算すると、6,443,900 / (1,000 * 60 * 60) *0.051 = $0.091 となりました。
実際には、ウォームアップの時間がかかったり、スケールダウンは処理が落ち着いてから動くため、あくまで参考値であることはご了承ください。

それでも、BigQuery Editions の適切な設定により、オンデマンド料金とは比較にならないコスト最適化が期待できます。

まとめ

Time Travel 分に若干の注意は必要なものの、基本的に何も特別な考慮なく料金が下がるストレージの価格体系の変更に加え、コンピューティングにおいても BigQuery AutoScaler を活用することで、大幅なコスト最適化を行えそうです。

手元にあったデータセットの場合、以下のような信じがたい結果が得られました。
Storage 費用: $1.82 → $0.17 の約90%ダウン
Analysis 費用: $64.94 → $0.091 の約99.9%ダウン

合計、なんと99.6%のコスト削減です!

利用状況次第で、ここまでの効果は出ないことも考えられますが、社内利用しているデータセットの中から、ある程度規模のあるものを無作為にピックアップしたものなので、さらに効果が出るものもあると思います。
オンデマンドが最適なケースもあるため、一概には言えないですが、是非、Editions の活用を検討いただけたらと思います。

今回は BigQuery を取り上げましたが、Google Cloud のサービスは日々アップデートが行われていますので、情報をキャッチアップし、皆様の環境に合わせたコスト最適化をしていきましょう!

参考
Google Data Cloud & AI Summit
BigQuery の仕組み
BigQuery の料金
ストレージの請求を予測する