Confidential & Proprietary
Google Cloud ベストプラクティス
Google BigQueryBest Practices and Performance Optimization /
Cost Optimization
Google Cloud カスタマーエンジニア
Confidential & Proprietary
Agenda
● Best Practices and Performance
Optimization
● Cost Optimization
Google Cloud ベストプラクティス Google BigQuery
※このスライドは 2017 年 12 月時点の情報に基づき作成しています。最新情報は Google Cloud Platform のドキュメントをご参照ください。
 https://cloud.google.com/docs/
Confidential & Proprietary
Google Cloud ベストプラクティス Google BigQuery
Best Practices
and Performance Optimization
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
※ 分割テーブル
※ キャッシュの利用
パフォーマンス最適化 ベスト・プラクティス
● データ ウェアハウス使用者向け BigQuery を読む
● 必要なデータのみをクエリする
○ 必要なカラムのみ
○ テーブルを日次/月次等に分割し、必要なテーブルのみをクエリ対象とする
● 非正規化/事前に Join するほうが効率が良い
● キャッシュを利用
● テールレイテンシーへの対応 (リトライ)
● データセット単位で共有することが可能
● 中間テーブルを活用する
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
id name cost date
SELECT id, cost FROM table
SELECT GKGRECORDID FROM
`gdelt-bq.hathitrustbooks.1800`
SELECT * FROM
`gdelt-bq.hathitrustbooks.1800`
必要なカラムのみクエリする
● BigQuery はカラム指向ストレージ
● 指定されたカラムは上から下までフルスキャンされる
● パフォーマンス、コストの観点から必要なカラムのみクエリをする
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
※ 分割テーブル
#standardSQL
SELECT
*
FROM
mydataset.partitioned_table
WHERE
_PARTITIONTIME BETWEEN
TIMESTAMP_TRUNC(TIMESTAMP_SUB(CURRENT_TIMES
TAMP(), INTERVAL 7 * 24 HOUR),DAY)
AND
TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY);
#Caluculate the cost for today
#standardSQL
SELECT service.description, SUM(cost)
FROM
`yutah-playground.billing_dashboard.gcp_billi
ng_export_v1_00AFE2_6C3561_890001`
WHERE
_PARTITIONTIME = TIMESTAMP("2017-10-13")
GROUP BY service.id, service.description
LIMIT
1000
分割テーブル (partitioned table)
● テーブルを パーティション に分割する
● 2017年10月 現在, データが挿入された日付で分割がされる 日付分割 のみ対応
● 最新のデータ(7日間)のみ取得するビューを作るなど、スキャン対象データを絞れる
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
非正規化スキーマを使用した場合と、
SELF JOINを使用した場合のパフォーマンスの比較
データの非正規化
● スタースキーマは避ける
● BigQuery は JOIN をサポートするが、
JOIN を実行するのは、小規模なディメ
ンション テーブルを処理する場合に限
定するほうが良い
非正規化のガイド
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
キャッシュの利用
● クエリには通常キャッシュが有効
● キャッシュにヒットするとクエリが 無料|高速
● キャッシュ無効になる一例 :
○ Streaming Insert のバッファが残っている
○ CURRENT_TIMESTAMP() や NOW() を利用
○ ワイルドカードを利用し複数テーブルを参照
○ キャッシュが切れている (一般的に 24時間)
○ 明示的にキャッシュを無効化している
キャッシュされたクエリ 参照
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
中間テーブルの作成 :
● JOIN が多い場合や、共通した処理を行う場合は中間テーブルを作成することが有効
● BigQuery のクエリ結果はすべて内部でテーブルとして保管される
○ SQL を書いて、非常に高速に新規テーブルが生成できる
テーブルとして書き込む を参照
BigQuery
Storage
中間テーブルの作成とビュー
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
$bq query --destination_table=’mydataset.happyhalloween’
“SELECT id FROM `bigquery-public-data.hacker_news.comments`
LIMIT 1000”
OR
中間テーブルの作成とビュー
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
Dataset C
Dataset B
● ビューはマテリアルビューではなく通常ビュー
○ 開くたびに裏ではクエリが走る
○ 中間テーブルと使い分けることが重要
○ (最後のユーザが見る部分のみ Viewを利用し、その他
は中間テーブルを利用する、等 )
● Authorized view を利用して、権限分離にも利用できる
参考: ビューの使用
BigQuery で承認済みビューを作成する
Dataset A
View
View
必要な Column のみ
SELECT,
必要な raw のみ WHERE し
VIEW にアクセス権を付与
Analyst
Group B
Analyst
Group C
中間テーブルの作成とビュー
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
12
中間テーブルの作成とビュー
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
中間テーブルの作成とビュー
● 参考: テーブルの生成依存関係を管理する
● Google Cloud Platform - Big Data & Machine
Learning Blog: How to aggregate data for
BigQuery using Apache Airflow
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
14
Google BigQuery 注意事項
● responseTooLarge 応答結果が大きすぎる
○ 圧縮後128MBまで -> 別テーブルに出力する
● resourcesExceeded リソースが足りな
○ GROUP EACH BY, EACH JOIN … ON
● quotaExceeded クォータを超過してい
○ クォータに注意
● billingTierLimitExceeded HighCompute クエリを実行しようとしている
○ maximumBillingTier を指定する
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
15
...
resourcesExceeded エラー
Worker ノードのリソースが足りなくなった場合に発生
● データ量とワーカーの数のミスマッチ
● 巨大なデータ量を処理するために、割り当てられたワーカーの数が不足してしまう
● もしくは、ワーカーのリソース (メモリ)が不足するする
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
16
resourcesExceeded が発生しやすいケース
● 単一の実行ノード内でメモリを大量に要求するもの
大量の個別グループを生成する Group By
● 入力値の数に比例するメモリを要求する集計関数
COUNT, SUM, MIN といった一般的な集計関数の出力は、入力される値の数には影
響されないが、 GROUP_CONCAT や NEST といった集計関数は入力のサイズに比
例
● 入力よりも多くの出力を生成する JOIN
JOIN があるとそのキーのユニークな値ごとに、その値のキーを持つ左右のテーブルの
行数の積が出力される
● データが偏っている
データが 1 つの値に過度に偏っているような場合
(null を持つ値が大量に存在する等)
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
resourcesExceeded 対処方法
● データ中の偏った値を、 WHERE 句などのフィルタリングにより除外
例:WHERE key IS NOT NULL
● データを分割することで、一度に処理する量を削減する
例:WHERE ABS(HASH(key)) % 5 == 0 を追加し、5 分の 1 の量に shard
● クエリの見直し
例:一時的に中間テーブルを作成する、など
● 事前にデータを処理
例:Dataflow / Dataproc 等を利用し、 BigQuery に格納する前にデータを事前処理する
● FLAT rate の利用
Slot が確保できる
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
すべての結果が必要なわけではない場合
● ORDER BY
解決策 : LIMIT を追加する。ORDER BY with LIMIT
が速い!
shard が過負荷になる場合
● JOIN の偏り
解決策 : クエリを分割する
resourcesExceeded 対処方法
大きすぎるデータをうっかり生成させた場合
● ARRAY_AGG / STRING_AGG
● PARTITION BY なしの分析関数
● CROSS JOIN
解決策 : クエリを修正する
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
19
billingTierLimitExceeded エラー
High Compute クエリを実行しようとしているという警告
● billingTierLimit (default = 1) を超えるクエリを実行すると発生
● billingTier を指定することで実行が可能となる
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
20
High Compute クエリとは
CPU バウンドが大きく resourcesExceeded エラーで実行できなかった
クエリを通常より多い料金を払うことにより実行可能にした機能
● UDF や FULL OUTER JOIN などのサポートにより CPU バウンドな処理を多く行いたいニーズに応える
ため実装
● 2015 年 8 月にリリース (UDF とほぼ同時)
● リリース後、 billingTier に応じた通常より多いクエリ実行料金が設定された
● billingTier とは、HighCompute クエリを実行する際の料金の係数 (1 以上の整数)
● クエリのスキャン容量 × billingTier が全体の料金となる
● billingTier のデフォルトは 1
暫定措置として、このクエリに対する課金は 2017 年 3 月より施行
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
21
CPU バウンドしやすい処理
High Compute クエリとなりやすい例
● 大量の JOIN または CROSS JOIN 句
● 複雑なユーザー定義関数 (UDF) を含む
● JSON 関数
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
22
BillingTier に関するよくある質問
High Compute クエリの料金を料金発生前に確認する方法は ?
● クエリを実行してみると、 High Compute クエリである旨表示され実行されない
● High Compute クエリの対象の場合 , 明示的に指定するまで料金は発生しない
○ エラーの際は料金はかからず、必要な billingTier が表示されるのみ
○ billingTier から料金が計算できる
○ 必要な maximum_billing_tier を指定し再度実行することで始めて実行可能
● エラー例:
Query exceeded resource limits for tier 1. Tier 2 or higher required.
● Project のデフォルトが変更されていると確認が走らないため注意
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
23
BillingTier に関するよくある質問
BillingTier を上げても resourcesExceeded エラーが発生するのは何故 ?
● High Compute クエリは割当 CPU シェアを大きくするだけ
● resourcesExceeded が 1 Worker のメモリに乗り切る限界を超えている可能性
● resourcesExceeded の対処方法を参照
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
24
データ処理容量
[ $5 / TB ]
BillingTier
[ 明示的に指定しないと 1 ]×
BillingTier に関するよくある質問
2017 年 3 月より BigQuery の料金は何が変わったのか
● 既存クエリ に対する特例措置の終了
● 2016 年 1 月 1 日よりも前に作成されたプロジェクトでは、追加料金なしで High
Compute クエリが使用できたが、 2017 年 1 月 1 日よりこの特例措置がなくなる
○ 参考 : High-Compute クエリ のタイミング
○ 特例措置が適用されている場合、プロジェクトオーナーに通知
● その他、基本料金にかかる変更は無い
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
25
ところで: スロットって何?
● スケジューリングの単位
● 論理的には 1 つの並列 “作業単位”
● パフォーマンスではなく、スループットが指標
● リソース サイズ(RAM や CPU の量)に対応
● 遅い / 失敗した場合はリスタート可能
● 不要になったらキャンセル可能
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
26
Project A
Project B
Query A-1
Query A-2
Query B-1
Total: 900
Demand: 1500, Allocate: 200
Demand: 100, Allocate: 100
Demand: 1000, Allocate: 300
Project C
Query C-1
Query C-2
Demand: 500, Allocate: 100
Demand: 500, Allocate: 100
Query C-3 Demand: 500, Allocate: 100
ある一瞬におけるスロットの
スケジューリング例
(通常スロットはクエリの中でも瞬間的に上下するた
め、この状態が続くわけではない)
300
allocated
300
allocated
300
allocated
スロットのスケジューリング
● デフォルトのスロット割り当て : プロジェクトあたり 2,000
● プロジェクト内のクエリ間でフェアスケジューリング
● プロジェクト間でフェアスケジューリング
● スロットはクエリのステージごとにスケジューリングされる
● スロットの利用度はデータの内部表現と転送状況に依存
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
27
クエリプランの説明
クエリプランを利用してクエリを解析
Web UI もしくは API の jobs.get の内容でクエリプランを確認可能。
クエリプランを解析することでクエリを解析、チューニングできる。
ドキュメントによくある遅い原因とそのパターンの記載有り。
Confidential & Proprietary
Google Cloud ベストプラクティス Google BigQuery
Cost Optimization
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
29
● 1 TB / 月間 無償
● $5 / TB
● 必要なカラムのみ全量
処理されれる
● HighCompute クエリ
は別途 Billing Tier に
よる乗算
● Flat Rate ならスロット
数に応じて一定
● $0.02 / GB / 月間
(90 日間更新の無い
テーブルは$0.01)
● ストリーミング:  $0.01
/ 200MB
● バッチロード: 無償
クエリ課金 ストレージ データ投入
BigQuery のコストを知る
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
コストコントロール
● 制限を設ける
● Flat-Rate の活用
利用料金の節約
● クエリ チューニング
● テーブル設計
● データ取り込み方式の変更
● ストレージの選択
30
コスト最適化のベスト・プラクティス
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
● Billing Alert を設定
● BigQueryの Custom Quota を設定
● Project 毎, User 毎にクエリのスキャンサイズで設定
○ フォームより申請
31
コストコントロール - 制限を設ける
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
ユーザの統制が難しい場合には Flat-Rate (定額料金)での利用を検討
● クエリを実行する計算リソース (Slot) を購入する料金体系
● クエリ実行による思わぬ料金増加のリスクヘッジ
● 現在の Slot 数は Stackdriver より確認可能
32
コストコントロール - Flat Rate の活用
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
● クエリキャッシュの利用 (デフォルト有効)
● SELECT するカラムの選択
● ORDER BY の削減
● JOIN 前のデータを削減
● テーブルデコレータ の利用 (Legacy SQL のみ)
33
コストコントロール - クエリ チューニング
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
● 分割テーブル
○ データを日付で分割
● JOIN を含むクエリを使う場合、先に非正規化して格納する
○ 計算量が削減される
● 複数の集計で使われる同じ処理を中間テーブルとして集約
○ 共通処理をまとめて計算量を削減
34
利用料金の節約 - テーブル設計
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
Streaming Insert (0.05 per GB) 対象データの見直し
● リアルタイムである必要のないデータ、増えないデータは通常のロードに切り替える
○ Google Cloud Storage に蓄積し bq コマンドでロード
○ Embulk などを利用したロード
● Streaming Insert は 1 行あたり 1KB を最低単位として計算するので注意
● ロードは無料
35
https://cloud.google.com/bigquery/pricing
利用料金の節約 - データ取り込み方式
Google Cloud ベストプラクティス Google BigQuery
Confidential & Proprietary
36
https://cloud.google.com/bigquery/pricing
BigQuery - Storage
[Unit: per GB per month]
GCS
[Unit: per GB per month]
BigQuery: Storage
GCS: Nealine
$0.02 $0.01
BigQuery: Long Term Storage
GCS: Coldline
$0.01 $0.007
bq extract --compression=GZIP [DATASET].[TABLE_NAME] 
gs://[BUCKET_NAME]/[FILENAME] ※料金はUSリージョン
利用料金の節約 - ストレージ
古いデータを Google Cloud Storage (GCS) へエクスポート
● GCS へのエクスポート時に gzip 圧縮を指定することも検討
Google BigQuery
Google Cloud ベストプラクティス
Thank you
1 : Introduction / BigQuery Organization / Exploring and Interacting with BigQuery
2 : Data ingestion into BigQuery / Writing Queries in BigQuery / Data extraction and exportation from BigQuery
3 : Best Practices and Performance Optimization / Cost Optimization
Google Cloud ベストプラクティス:Google BigQuery 編 - 03 : パフォーマンスとコストの最適化

Google Cloud ベストプラクティス:Google BigQuery 編 - 03 : パフォーマンスとコストの最適化

  • 1.
    Confidential & Proprietary GoogleCloud ベストプラクティス Google BigQueryBest Practices and Performance Optimization / Cost Optimization Google Cloud カスタマーエンジニア
  • 2.
    Confidential & Proprietary Agenda ●Best Practices and Performance Optimization ● Cost Optimization Google Cloud ベストプラクティス Google BigQuery ※このスライドは 2017 年 12 月時点の情報に基づき作成しています。最新情報は Google Cloud Platform のドキュメントをご参照ください。  https://cloud.google.com/docs/
  • 3.
    Confidential & Proprietary GoogleCloud ベストプラクティス Google BigQuery Best Practices and Performance Optimization
  • 4.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ※ 分割テーブル ※ キャッシュの利用 パフォーマンス最適化 ベスト・プラクティス ● データ ウェアハウス使用者向け BigQuery を読む ● 必要なデータのみをクエリする ○ 必要なカラムのみ ○ テーブルを日次/月次等に分割し、必要なテーブルのみをクエリ対象とする ● 非正規化/事前に Join するほうが効率が良い ● キャッシュを利用 ● テールレイテンシーへの対応 (リトライ) ● データセット単位で共有することが可能 ● 中間テーブルを活用する
  • 5.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary id name cost date SELECT id, cost FROM table SELECT GKGRECORDID FROM `gdelt-bq.hathitrustbooks.1800` SELECT * FROM `gdelt-bq.hathitrustbooks.1800` 必要なカラムのみクエリする ● BigQuery はカラム指向ストレージ ● 指定されたカラムは上から下までフルスキャンされる ● パフォーマンス、コストの観点から必要なカラムのみクエリをする
  • 6.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ※ 分割テーブル #standardSQL SELECT * FROM mydataset.partitioned_table WHERE _PARTITIONTIME BETWEEN TIMESTAMP_TRUNC(TIMESTAMP_SUB(CURRENT_TIMES TAMP(), INTERVAL 7 * 24 HOUR),DAY) AND TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(),DAY); #Caluculate the cost for today #standardSQL SELECT service.description, SUM(cost) FROM `yutah-playground.billing_dashboard.gcp_billi ng_export_v1_00AFE2_6C3561_890001` WHERE _PARTITIONTIME = TIMESTAMP("2017-10-13") GROUP BY service.id, service.description LIMIT 1000 分割テーブル (partitioned table) ● テーブルを パーティション に分割する ● 2017年10月 現在, データが挿入された日付で分割がされる 日付分割 のみ対応 ● 最新のデータ(7日間)のみ取得するビューを作るなど、スキャン対象データを絞れる
  • 7.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 非正規化スキーマを使用した場合と、 SELF JOINを使用した場合のパフォーマンスの比較 データの非正規化 ● スタースキーマは避ける ● BigQuery は JOIN をサポートするが、 JOIN を実行するのは、小規模なディメ ンション テーブルを処理する場合に限 定するほうが良い 非正規化のガイド
  • 8.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary キャッシュの利用 ● クエリには通常キャッシュが有効 ● キャッシュにヒットするとクエリが 無料|高速 ● キャッシュ無効になる一例 : ○ Streaming Insert のバッファが残っている ○ CURRENT_TIMESTAMP() や NOW() を利用 ○ ワイルドカードを利用し複数テーブルを参照 ○ キャッシュが切れている (一般的に 24時間) ○ 明示的にキャッシュを無効化している キャッシュされたクエリ 参照
  • 9.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 中間テーブルの作成 : ● JOIN が多い場合や、共通した処理を行う場合は中間テーブルを作成することが有効 ● BigQuery のクエリ結果はすべて内部でテーブルとして保管される ○ SQL を書いて、非常に高速に新規テーブルが生成できる テーブルとして書き込む を参照 BigQuery Storage 中間テーブルの作成とビュー
  • 10.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary $bq query --destination_table=’mydataset.happyhalloween’ “SELECT id FROM `bigquery-public-data.hacker_news.comments` LIMIT 1000” OR 中間テーブルの作成とビュー
  • 11.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary Dataset C Dataset B ● ビューはマテリアルビューではなく通常ビュー ○ 開くたびに裏ではクエリが走る ○ 中間テーブルと使い分けることが重要 ○ (最後のユーザが見る部分のみ Viewを利用し、その他 は中間テーブルを利用する、等 ) ● Authorized view を利用して、権限分離にも利用できる 参考: ビューの使用 BigQuery で承認済みビューを作成する Dataset A View View 必要な Column のみ SELECT, 必要な raw のみ WHERE し VIEW にアクセス権を付与 Analyst Group B Analyst Group C 中間テーブルの作成とビュー
  • 12.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 12 中間テーブルの作成とビュー
  • 13.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 中間テーブルの作成とビュー ● 参考: テーブルの生成依存関係を管理する ● Google Cloud Platform - Big Data & Machine Learning Blog: How to aggregate data for BigQuery using Apache Airflow
  • 14.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 14 Google BigQuery 注意事項 ● responseTooLarge 応答結果が大きすぎる ○ 圧縮後128MBまで -> 別テーブルに出力する ● resourcesExceeded リソースが足りな ○ GROUP EACH BY, EACH JOIN … ON ● quotaExceeded クォータを超過してい ○ クォータに注意 ● billingTierLimitExceeded HighCompute クエリを実行しようとしている ○ maximumBillingTier を指定する
  • 15.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 15 ... resourcesExceeded エラー Worker ノードのリソースが足りなくなった場合に発生 ● データ量とワーカーの数のミスマッチ ● 巨大なデータ量を処理するために、割り当てられたワーカーの数が不足してしまう ● もしくは、ワーカーのリソース (メモリ)が不足するする
  • 16.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 16 resourcesExceeded が発生しやすいケース ● 単一の実行ノード内でメモリを大量に要求するもの 大量の個別グループを生成する Group By ● 入力値の数に比例するメモリを要求する集計関数 COUNT, SUM, MIN といった一般的な集計関数の出力は、入力される値の数には影 響されないが、 GROUP_CONCAT や NEST といった集計関数は入力のサイズに比 例 ● 入力よりも多くの出力を生成する JOIN JOIN があるとそのキーのユニークな値ごとに、その値のキーを持つ左右のテーブルの 行数の積が出力される ● データが偏っている データが 1 つの値に過度に偏っているような場合 (null を持つ値が大量に存在する等)
  • 17.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary resourcesExceeded 対処方法 ● データ中の偏った値を、 WHERE 句などのフィルタリングにより除外 例:WHERE key IS NOT NULL ● データを分割することで、一度に処理する量を削減する 例:WHERE ABS(HASH(key)) % 5 == 0 を追加し、5 分の 1 の量に shard ● クエリの見直し 例:一時的に中間テーブルを作成する、など ● 事前にデータを処理 例:Dataflow / Dataproc 等を利用し、 BigQuery に格納する前にデータを事前処理する ● FLAT rate の利用 Slot が確保できる
  • 18.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary すべての結果が必要なわけではない場合 ● ORDER BY 解決策 : LIMIT を追加する。ORDER BY with LIMIT が速い! shard が過負荷になる場合 ● JOIN の偏り 解決策 : クエリを分割する resourcesExceeded 対処方法 大きすぎるデータをうっかり生成させた場合 ● ARRAY_AGG / STRING_AGG ● PARTITION BY なしの分析関数 ● CROSS JOIN 解決策 : クエリを修正する
  • 19.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 19 billingTierLimitExceeded エラー High Compute クエリを実行しようとしているという警告 ● billingTierLimit (default = 1) を超えるクエリを実行すると発生 ● billingTier を指定することで実行が可能となる
  • 20.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 20 High Compute クエリとは CPU バウンドが大きく resourcesExceeded エラーで実行できなかった クエリを通常より多い料金を払うことにより実行可能にした機能 ● UDF や FULL OUTER JOIN などのサポートにより CPU バウンドな処理を多く行いたいニーズに応える ため実装 ● 2015 年 8 月にリリース (UDF とほぼ同時) ● リリース後、 billingTier に応じた通常より多いクエリ実行料金が設定された ● billingTier とは、HighCompute クエリを実行する際の料金の係数 (1 以上の整数) ● クエリのスキャン容量 × billingTier が全体の料金となる ● billingTier のデフォルトは 1 暫定措置として、このクエリに対する課金は 2017 年 3 月より施行
  • 21.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 21 CPU バウンドしやすい処理 High Compute クエリとなりやすい例 ● 大量の JOIN または CROSS JOIN 句 ● 複雑なユーザー定義関数 (UDF) を含む ● JSON 関数
  • 22.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 22 BillingTier に関するよくある質問 High Compute クエリの料金を料金発生前に確認する方法は ? ● クエリを実行してみると、 High Compute クエリである旨表示され実行されない ● High Compute クエリの対象の場合 , 明示的に指定するまで料金は発生しない ○ エラーの際は料金はかからず、必要な billingTier が表示されるのみ ○ billingTier から料金が計算できる ○ 必要な maximum_billing_tier を指定し再度実行することで始めて実行可能 ● エラー例: Query exceeded resource limits for tier 1. Tier 2 or higher required. ● Project のデフォルトが変更されていると確認が走らないため注意
  • 23.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 23 BillingTier に関するよくある質問 BillingTier を上げても resourcesExceeded エラーが発生するのは何故 ? ● High Compute クエリは割当 CPU シェアを大きくするだけ ● resourcesExceeded が 1 Worker のメモリに乗り切る限界を超えている可能性 ● resourcesExceeded の対処方法を参照
  • 24.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 24 データ処理容量 [ $5 / TB ] BillingTier [ 明示的に指定しないと 1 ]× BillingTier に関するよくある質問 2017 年 3 月より BigQuery の料金は何が変わったのか ● 既存クエリ に対する特例措置の終了 ● 2016 年 1 月 1 日よりも前に作成されたプロジェクトでは、追加料金なしで High Compute クエリが使用できたが、 2017 年 1 月 1 日よりこの特例措置がなくなる ○ 参考 : High-Compute クエリ のタイミング ○ 特例措置が適用されている場合、プロジェクトオーナーに通知 ● その他、基本料金にかかる変更は無い
  • 25.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 25 ところで: スロットって何? ● スケジューリングの単位 ● 論理的には 1 つの並列 “作業単位” ● パフォーマンスではなく、スループットが指標 ● リソース サイズ(RAM や CPU の量)に対応 ● 遅い / 失敗した場合はリスタート可能 ● 不要になったらキャンセル可能
  • 26.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 26 Project A Project B Query A-1 Query A-2 Query B-1 Total: 900 Demand: 1500, Allocate: 200 Demand: 100, Allocate: 100 Demand: 1000, Allocate: 300 Project C Query C-1 Query C-2 Demand: 500, Allocate: 100 Demand: 500, Allocate: 100 Query C-3 Demand: 500, Allocate: 100 ある一瞬におけるスロットの スケジューリング例 (通常スロットはクエリの中でも瞬間的に上下するた め、この状態が続くわけではない) 300 allocated 300 allocated 300 allocated スロットのスケジューリング ● デフォルトのスロット割り当て : プロジェクトあたり 2,000 ● プロジェクト内のクエリ間でフェアスケジューリング ● プロジェクト間でフェアスケジューリング ● スロットはクエリのステージごとにスケジューリングされる ● スロットの利用度はデータの内部表現と転送状況に依存
  • 27.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 27 クエリプランの説明 クエリプランを利用してクエリを解析 Web UI もしくは API の jobs.get の内容でクエリプランを確認可能。 クエリプランを解析することでクエリを解析、チューニングできる。 ドキュメントによくある遅い原因とそのパターンの記載有り。
  • 28.
    Confidential & Proprietary GoogleCloud ベストプラクティス Google BigQuery Cost Optimization
  • 29.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 29 ● 1 TB / 月間 無償 ● $5 / TB ● 必要なカラムのみ全量 処理されれる ● HighCompute クエリ は別途 Billing Tier に よる乗算 ● Flat Rate ならスロット 数に応じて一定 ● $0.02 / GB / 月間 (90 日間更新の無い テーブルは$0.01) ● ストリーミング:  $0.01 / 200MB ● バッチロード: 無償 クエリ課金 ストレージ データ投入 BigQuery のコストを知る
  • 30.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary コストコントロール ● 制限を設ける ● Flat-Rate の活用 利用料金の節約 ● クエリ チューニング ● テーブル設計 ● データ取り込み方式の変更 ● ストレージの選択 30 コスト最適化のベスト・プラクティス
  • 31.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ● Billing Alert を設定 ● BigQueryの Custom Quota を設定 ● Project 毎, User 毎にクエリのスキャンサイズで設定 ○ フォームより申請 31 コストコントロール - 制限を設ける
  • 32.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ユーザの統制が難しい場合には Flat-Rate (定額料金)での利用を検討 ● クエリを実行する計算リソース (Slot) を購入する料金体系 ● クエリ実行による思わぬ料金増加のリスクヘッジ ● 現在の Slot 数は Stackdriver より確認可能 32 コストコントロール - Flat Rate の活用
  • 33.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ● クエリキャッシュの利用 (デフォルト有効) ● SELECT するカラムの選択 ● ORDER BY の削減 ● JOIN 前のデータを削減 ● テーブルデコレータ の利用 (Legacy SQL のみ) 33 コストコントロール - クエリ チューニング
  • 34.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary ● 分割テーブル ○ データを日付で分割 ● JOIN を含むクエリを使う場合、先に非正規化して格納する ○ 計算量が削減される ● 複数の集計で使われる同じ処理を中間テーブルとして集約 ○ 共通処理をまとめて計算量を削減 34 利用料金の節約 - テーブル設計
  • 35.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary Streaming Insert (0.05 per GB) 対象データの見直し ● リアルタイムである必要のないデータ、増えないデータは通常のロードに切り替える ○ Google Cloud Storage に蓄積し bq コマンドでロード ○ Embulk などを利用したロード ● Streaming Insert は 1 行あたり 1KB を最低単位として計算するので注意 ● ロードは無料 35 https://cloud.google.com/bigquery/pricing 利用料金の節約 - データ取り込み方式
  • 36.
    Google Cloud ベストプラクティスGoogle BigQuery Confidential & Proprietary 36 https://cloud.google.com/bigquery/pricing BigQuery - Storage [Unit: per GB per month] GCS [Unit: per GB per month] BigQuery: Storage GCS: Nealine $0.02 $0.01 BigQuery: Long Term Storage GCS: Coldline $0.01 $0.007 bq extract --compression=GZIP [DATASET].[TABLE_NAME] gs://[BUCKET_NAME]/[FILENAME] ※料金はUSリージョン 利用料金の節約 - ストレージ 古いデータを Google Cloud Storage (GCS) へエクスポート ● GCS へのエクスポート時に gzip 圧縮を指定することも検討
  • 37.
    Google BigQuery Google Cloudベストプラクティス Thank you 1 : Introduction / BigQuery Organization / Exploring and Interacting with BigQuery 2 : Data ingestion into BigQuery / Writing Queries in BigQuery / Data extraction and exportation from BigQuery 3 : Best Practices and Performance Optimization / Cost Optimization