Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

BigQuery Lensで、BigQueryコスト最適化を「イージーモード」に

By Matan BordoDec 14, 202210 min read

このページはEnglishDeutschEspañolFrançaisItalianoPortuguêsでもご覧いただけます。

BigQuery cost optimization

BigQueryコスト最適化のベストプラクティスを追い続けるのは大変。やるべきことを_教えてくれる_ツールがあったら?

BigQueryのコストが上がってきた——さて、どうしますか?

もちろん、監査ログを掘り下げて手がかりを探したり、Google CloudのBigQuery Best Practicesを読み込んで、何が最適化_できそうか_を把握することもできます。

しかし、他のプロジェクトのバックログや火消し対応に追われるなかで、あなたやチームに本当にその時間を割く余裕があるでしょうか。私たちの経験上、ほとんどの場合、答えは明確に「No」です。

私たちが支援している企業の多くは、優先度の高いプロダクト関連タスクが山積みで、BigQueryのコスト最適化に割けるエンジニアリングリソースが限られています。その結果、BigQuery上のデータ基盤を場当たり的に構築してしまい、後になってその判断のツケを払うことになるのです。

では、もし「やるべきこと」を_教えてくれる_ツールがあったらどうでしょう?

そんな思いから生まれたのがBigQuery Lensです。BigQueryのベストプラクティスと、何千ものお客様のBigQuery利用最適化を支援してきた私たち自身の経験を基に、お客様ごとに最適化された推奨事項をお届けします。

それでは、BigQueryのベストプラクティスをいくつか取り上げ、BigQuery Lensでどのように実践できるかを見ていきましょう。

big query performance

「BigQuery Lensのレコメンデーションのおかげで、主要テーブルのパーティショニングに時間を投じることができ、月々のBigQuery費用を25%削減できました。」

  • Daniel Rimon, Head of Data Engineering, Resident

BigQuery Lensがコスト最適化をどう支援するのか

BigQuery LensはBigQueryのジョブとテーブルメタデータを分析し、すぐ実行に移せる最適化レコメンデーションを提示するとともに、チームの利用状況を細かくドリルダウンできる機能を備えています。

もちろん、Cloud Monitoringで自前のダッシュボードを構築したり、INFORMATION_SCHEMA.JOBSにクエリを投げたりして、監査ログやクエリを地道に掘り下げていくこともできます。しかし、そこから得られるのは概要レベルのメトリクスにとどまり、何をすべきかは結局自分で判断しなければなりません。

BigQuery Lensを使えば、ベストプラクティスの実践がぐっとシンプルになります。

具体的には、次のような最適化を支援します。

  • テーブルのクラスタリングやパーティショニングによるスキャンデータ量の削減
  • スケジュール済みジョブのコスト削減
  • 適したケースでの定額料金プランの活用
  • 未使用テーブルの削除によるストレージコスト削減
  • クエリでのパーティションフィールド利用の徹底
  • 定期実行ジョブの再配置によるスロット購入数の削減

bigquery performance tuning

テーブルのクラスタリングとパーティショニングで処理バイト数を削減

オンデマンド料金または定額料金のいずれであっても、クエリで処理するバイト数を減らせば、コストとパフォーマンスの両面でメリットがあります。オンデマンド料金のプロジェクトでは、分析コストを直接削減できます。一方、定額料金は購入したスロット数に応じて固定されますが、処理バイト数を減らせば平均スロット使用量が下がるため、間接的にコスト削減につながります。結果として、購入が必要なスロット数も減らせます(詳しくは後述)。

まず手をつけるべきは、テーブルのクラスタリングやパーティショニングです。

テーブルのクラスタリング(効果を最大化するコツ)

クラスタリングは、指定したカラムに基づいてテーブルをデータブロック単位で並び替えることで、クエリパフォーマンスを向上させます。クエリを正しく組み立てれば、BigQueryは関連するデータブロックだけを効率的にスキャンできるようになります。

bigquery cost optimization

ただし、クラスタリングで得られる効果は、どのカラムをどの順序でクラスタリングするか、そしてクラスタリング済みテーブルへのクエリをどう組み立てるかによって変わります。

クラスタリングは、頻繁にクエリされるカラム——特に異なる値が多く含まれるカラム——に対して行うのが効果的です。こうすることで、テーブルに設定したクラスタリング戦略によるカラム順序が活き、BigQueryのクエリ実行効率が高まります。

bigquery-data-storage-cost

下図のとおり、選択したクラスタリングフィールドの順序に沿ってクエリを組み立てる(つまり、クラスタリング順にフィールドをフィルタリングする)ことも重要です。これにより、テーブルに設定したクラスタリング戦略をBigQueryジョブで最大限に活かせます。

bigquery table suffix

BigQuery Lensはクラスタリングすべきテーブルを特定し、どのカラムをどの順序でクラスタリングすべきかを示します。あとはレコメンデーション画面でテーブル名をクリックしてGoogle Cloud Consoleで開き、テーブルをクラスタリングするだけです。

該当テーブルでクラスタリング前に実行していたクエリと、クラスタリング後に動かしているジョブをベンチマーク比較してみるのもおすすめです。そのテーブル上で実行されるジョブのコストと実行時間が、いずれも改善している可能性が非常に高いはずです。

bigquery performance

テーブルのパーティショニング(なぜ必要か)

テーブルのパーティショニングは、大きなテーブルを小さな単位に分割することでコストを抑えるのに役立ちます。特に、パーティションプルーニング(クエリで特定のパーティションに絞り込み、テーブル全体のスキャンを避ける手法)と組み合わせると、パーティショニングは真価を発揮します。

また、データをより細かい粒度で管理できるようにもなります。BigQueryテーブルでパーティションを活用すれば、特定のパーティションに有効期限を設定したり、新規入力データをより効率的に管理したりできます。

bigquery create table

クラスタリング済みテーブルへのクエリと同様に、パーティション分割テーブルの恩恵を受けるには、クエリでパーティションカラムの値に対する適切なフィルタを使う必要があります。

注:BigQuery Lensは、パーティション分割テーブルへのクエリのうち、適切なフィルタを使えるはずなのに使っていないものも検出します(後述の「クエリでパーティションフィールドの利用を徹底する」を参照)。

クラスタリングのレコメンデーションと同様に、BigQuery Lensはどのテーブルをどのフィールドでパーティショニングすべきかも示します。これは一般的にも有効ですが、特にBigQuery上でBI連携のダッシュボードを動かしている場合、パーティショニングの実装によってダッシュボードを高速化し、クエリコストも抑えられます。

bigquery partition

クラスタリングとパーティショニングを併用すべきケース

状況によっては、BigQueryテーブルでパーティショニングとクラスタリングを_両方_組み合わせる戦略が有効です。

この戦略は、テーブル内できめ細かなソートを行いたい場合(下図参照)に特に効果的で、同時にBigQueryのパーティションプルーニング機能のおかげで、クエリ実行前にコスト見通しも立てやすくなります。

ただし、2つの戦略を組み合わせるとテーブルで管理するメタデータが増える点、また毎回共通のフィールドでクエリされないテーブルではクラスタリングの効果が出にくい点には注意が必要です。後者の場合、BigQueryテーブル設計におけるこの戦略のメリットは相殺されてしまいます。

google bigquery performance

定額料金への切り替え

BigQueryの利用やデータ量が増えていくと、オンデマンド料金モデルから定額料金に切り替えた方がコスト削減できる節目がやってきます。

BigQuery Lensは、切り替えによってコスト削減の余地があると判断すると、スロットコミットメントの推奨を表示します。下記の例では、平均日次スロット使用量の最大値が169スロットであることを示し、購入は100スロット単位で行う必要があるため200スロットの予約を推奨しています。一方、ピーク時のスロット使用量は2,238スロットとはるかに高い水準にあることもわかります。

bigquery lens

注:BigQueryのリザベーションとオンデマンド料金モデルは排他的なものではありません。 BigQuery Reservations を使って両者を切り替えたり、Flex Slotsを組み合わせたりすることもできます。

スロットは最低1か月のコミットメントが必要なため、BigQueryのクエリ動向、急激なバースト、季節変動などに不確実性がある場合は、購入時に特に慎重になるべきです。そこで便利なのがFlex Slotsです。Flex Slotsを使えば、最短60秒からという短い単位でスロットを購入できます。

たとえば、すべてのロード/レポートジョブを午前3時に実行している場合、Cloud ComposerでFlex Slotsのプロビジョニングとデプロビジョニングをスケジュールすれば、簡単にスケールアップ/ダウンできます。あるお客様は、需要がスロット可用量を超えるのを防ぐため、Cloud Functionsで5分ごとにスロット使用量がコミットメントの90%を超えていないかチェックし、超えそうなときにはFlex Slotsを自動的にプロビジョニングする仕組みを採用しています。

bigquery table

スケジュール済みジョブやその他の定期ジョブの実行頻度を下げる

現状ほど頻繁に実行する必要のない、あるいはまったく実行する必要のないスケジュール済みジョブが動いているかもしれません。BigQuery Lensは頻繁に実行されているジョブを可視化し、クエリの実行頻度を10〜50%減らした場合の節約見込みを表示します。

このレコメンデーションは、チーム内でのコスト管理に関する議論を後押しし、コストの高いジョブを必要なときだけ実行する運用を実現します。

bigquery query performance

たとえばあるお客様は、実行頻度が必要以上に高いジョブをいくつか発見しました。これをチーム全体で共有して頻度の見直しを進めた結果、実行回数をわずかに減らすだけでクエリコストを10〜15%削減できると試算できました。

別のお客様は、すでに役目を終えたスケジュール済みクエリの存在に気付きました。BigQuery Lensを導入する前は、その状況を把握できていませんでした。不要なスケジュール済みクエリを停止した翌月、BigQuery - Analysisの支出は50%以上減少しました。

bigquery cost optimization on demand

最後に、こうした定期クエリがBI連携(Lookerなど)のダッシュボードから生成されているのであれば、BI Engine経由で実行することでコスト削減を狙えます。BI EngineはBigQueryのデータをメモリ上にインテリジェントにキャッシュするため、ダッシュボード向けクエリに最適で、応答も高速になります。インメモリでキャッシュされる関係上、テーブルデータを読み取るクエリステージは無料で、代わりに予約メモリ容量に対してのみ料金が発生します。なお、プロジェクトが定額料金を使っている場合、後続のステージはBigQueryリザベーションのスロットを消費します。

未使用テーブルのバックアップと削除でストレージコストを削減

節約できるのはクエリだけではありません。BigQueryではストレージにも料金が発生します。私たちの経験では、未使用テーブルはBigQuery支出を下げるうえで、まだ十分に活かされていない領域です。

BigQuery Lensは、過去30日間使われていないテーブル(およびパーティションがあればそれも)を可視化します。これらのテーブルをCloud Storageにバックアップしたうえで BigQueryから削除する(またはテーブルの有効期限設定を調整する)ことで、ストレージコストを削減できます。

最近、あるお客様はこのレコメンデーションを使って、3年以上前のクエリされていないデータを含む複数のテーブルを洗い出しました。これらをバックアップして削除した結果、BigQueryのコストは約30%削減されました。

bigquery cost

クエリでパーティションフィールドの利用を徹底する

テーブルをパーティショニングしただけでは、まだ道半ばです。パーティショニング後は、テーブルがパーティショニングされているフィールドを使って効果的にクエリされているかを確認する必要があります。これにより、テーブル全体ではなく一部だけをスキャンする運用となり、コストをよりコントロールできます。

とはいえ、データアナリストのチームを率いていると、メンバー全員がクエリにパーティションフィールドを含めているかどうかを把握するのは困難です。BigQuery Lensは、パーティション分割テーブルにクエリを投げているのにパーティションフィールドが活用されていないジョブを検出します。

bigquery jobs

定期ジョブの再配置で定額料金コストを削減

定額料金コストの最適化は、テトリスをプレイするようなものだと考えてください。目指すのは利用を安定させ、時間ごとのスロット消費を平らな「ブロック」に整えることです。

とはいえ通常、平均時間帯別スロット使用量にはピークと谷があります(下図参照)。この不安定な使用量を基にスロット購入を判断していると、必要以上の支出を生んでしまいかねません。

partition by bigquery

定額料金コストを削減するには、ピーク時間帯に発生している定期ジョブを見つけ、可能であれば平均使用量が低い時間帯に移すか、Flex Slotsをプロビジョニングして余剰負荷をさばきます。

こうしてピークを平準化すれば、より低く一貫したスロット使用パターンに整います。結果として、購入が必要なスロット数が減り、長期的に定額料金コストを下げられます。

BigQuery Lensは、定額料金プロジェクトで月30回以上実行されているクエリを、その実行時間帯と消費スロット数とともに表示します。

bigquery pricing

そこからピーク時間帯のクエリを検索し、使用量が落ち込む時間帯に移動できるかを判断します。上の図を例にとれば、午前4時または午後4時に実行されているクエリを探し、可能であれば午前7時または午後8時に移すとよいでしょう。

BigQuery Lensの導入方法

パブリッククラウドの常として、BigQueryの使い方に注意を払わないとコストはあっという間に膨らみます。BigQueryは多くの企業のデータ戦略の中核を担っており、お客様からのチケット依頼でも常に上位に入る人気テーマであるのもうなずけます。

だからこそ、コストとパフォーマンスを継続的に最適化していくことが重要です。そして同じくらい大切なのが、自社のチームがBigQueryをどう使っているかを把握すること。把握できていないものは最適化のしようがありません。BigQuery Lensは、まさにそこを支えるツールです。

DoiTのお客様でない方で、BigQuery LensやBigQueryエキスパートのサポートをご希望の方は、お問い合わせください。

すでにDoiTのお客様で、まだ有効化していない方は、ぜひBigQuery Lensを有効化してください。