信頼性: データのクエリ

このドキュメントでは、BigQuery で信頼性の高いソリューションを構築する方法と、BigQuery 環境内でデータを確実にクエリする方法について説明します。

スロットについて

BigQuery がクエリジョブを実行すると、送信された宣言型の SQL ステートメントを実行グラフに変換し、一連のクエリステージに分割します。クエリステージは、より細かい実行ステップから構成されます。BigQuery は、高度に分散された並列アーキテクチャを利用して、これらのクエリを実行します。ステージは、多くのワーカーを同時に実行できる作業単位をモデル化しています。これらのワーカーのリソースは、スロットと呼ばれます。

最も簡単に言うと、BigQuery スロットは、BigQuery が SQL クエリを実行するために使用する仮想 CPU です。スロットとその機能の詳細については、スロットについてをご覧ください。

BigQuery では、2 つのゾーンで冗長性のあるスロット容量を提供することで、クエリに 99.99% の SLA を達成できます。この分散により、ゾーン障害からお客様を保護します。

クエリの実行に使用されるコンピューティング リソースは、オンデマンド料金モデルかフラットレート料金モデルで購入されます。オンデマンド モデルでは、送信されたクエリによって処理されたバイト数に基づいてコンピューティング リソースが課金されます。フラットレート モデルでは、特定目的のクエリ処理容量の一定量を購入し、これにより安定した費用モデルが提供されます。

オンデマンド分析モデル

BigQuery のオンデマンド料金モデルでは、送信されたクエリ数に基づいて処理されたバイト数(読み取られたバイト数)だけに基づいて課金されます。BigQuery のオンデマンド料金モデルを使用するプロジェクトは、デフォルトのスロット容量にアクセスできます。通常この容量は、十分すぎるほど大きく、プロジェクトごとのスロットの割り当ての対象になります。

フラットレート スロット モデル

オンデマンド料金モデルよりもクエリの費用が安定することをご希望のお客様は、フラットレート料金モデルの検討をおすすめします。フラットレート料金にする場合は、専用のクエリ処理容量を、BigQuery のスロット単位で購入します。クエリではこの容量が使用され、処理されたバイト数に対しては請求されません。

フラットレートの体系では、お客様の契約時間の長さ(年、月、またはコミットメントなし)でスロットを購入して、スロットの予約がある特定のプロジェクトやフォルダにスロットの優先順位を付け、空いているスロットを複数の予約をまたいで共有できます。詳細については、予約の概要をご覧ください。

フラットレート モデルでは、フォルダやプロジェクトで使用可能なスロット リソースの最大数を明示的に設定します。したがって、購入スロットが少なすぎるとクエリのパフォーマンスに影響し、購入スロットが多すぎると使用されない処理容量が発生する可能性があります。その場合、リソースが十分に活用されず、不要な費用となります。

フラットレート スロットモデルに関する考慮事項

オンデマンド モデルとフラットレート モデルのどちらを選ぶかは、多くの場合、コストに関する検討によって決まりますが、この決定が信頼性を左右することもあります。たとえば、ピーク負荷時にプロジェクトあたりの使用可能なスロット数の基本水準が 2,000 になるオンデマンド料金モデルと、最大数十万のスロットを構成できるフラットレートではスケーラビリティがことなります。プロジェクトによって使用されるスロットの数は、クエリの複雑さ、スキャンされるデータの量、ユーザー定義関数(UDF)などの特別な関数の使用、送信される同時クエリの数によって異なります。とはいえ、オンデマンドのお客様が利用できる 2,000 スロットは、通常、BigQuery から始めるユーザーにとっては十分すぎる量です。BigQuery のオンデマンド モデルとフラットレート料金モデルの選択方法については、BigQuery のオンデマンド料金か、フラットレート料金かの選択をご覧ください。

BigQuery での 99.99% 可用性の SLA は、オンデマンド モデルとフラットレート モデルの両方に適用されますが、スロット リソースの数は、フラットレート モデルでのみ保証されています。オンデマンド モデルでは、共有スロット リソース プールが使用されます。なお、BigQuery では、購入してプロビジョニングするまで、予約スロットに空きがあるかどうかはまったく保証されません。このため、ビジネス クリティカルなワークロード用に、予約スロットを必要になったタイミングで取得することはおすすめしません。大きいスロット リクエストになるほど、スロット リソースのプロビジョニングに必要なリードタイムは長くなります。

また、ニーズに合わせて、組織やプロジェクト内でオンデマンド モデルとフラットレート モデルの両方を組み合わせることもできます。BigQuery における BigQuery Reservations の枠組みで可能です。たとえば、米国マルチリージョンの本番環境データセットにはフラットレート予約を使用し、別のリージョンにある小規模な開発データセットにはオンデマンドの容量を使用します。

予約

BigQuery Reservations を使用すると、組織全体にわたるスロット容量の割り当てをカスタマイズし、ワークロードに応じてリソースに優先順位を付けることができます。たとえば、本番環境ワークロード用に「prod」という名前の予約と、テスト用に「test」という名前の別の予約を作成するとします。これにより、テストジョブが本番環境ワークロードに必要なリソースと競合しなくなります。予約では、割り当てられたプロジェクト、フォルダ、または組織に対するスロット リソースの優先順位付けを指定します。リソース階層の各レベルには、オーバーライドしない限り、その上位のレベルから割り当てが継承されます。つまり、プロジェクトはその親フォルダの割り当てを継承し、フォルダは組織の割り当てを継承します。

BigQuery の予約では、デフォルトで他の予約ともアイドル スロットのリソースも共有することで、リソースの使用率が最適化されます。これにより、開発環境 / テスト環境などの優先順位が付けられていないワークロードで、本番環境の予約が完全に利用されない場合でも、クエリのパフォーマンスを向上させることができます。開発 / テスト ワークロードが本番環境の予約から未使用のスロットを消費し、本番環境の予約がすべて使用されると、BigQuery スロット スケジューラは、処理中の開発 / テストクエリからスロット リソースを適切に移動させて本番環境の予約で使用できるようにします。使用するコンピューティング リソースが少ないために遅くなりながらも、開発 / テストクエリは引き続き実行されます。

分析ニーズの内容によっては、ビジネス ユニット、機能(本番対開発 / テスト)、またはアプリケーションの種類(ビジネス インテリジェンス ダッシュボード、スケジュールされたクエリ/ジョブ、ユーザーからのアドホック クエリ)に基づいてワークロードを分離することにより、環境内に複数の BigQuery Reservations を作成することが適切な場合がよくあります。

使用されていないスロットは、単一の BigQuery 管理プロジェクト内に作成された予約内でのみ共有されることに注意してください。

予約のサイズ設定

予約の適切なサイズ設定を正確に行うには、通常、BigQuery 管理リソースグラフCloud Monitoring ダッシュボードを使用して、現在と過去の BigQuery スロットの使用状況をモニタリングすることをおすすめします。管理リソースグラフには、組織、フォルダ、プロジェクト、予約、ユーザー、またはジョブのレベルにおける、スロットの使用状況、ジョブの同時実行、ジョブのパフォーマンスに関する詳細が、リアルタイムおよび 14 日前までの過去データとして表示されます。

ジョブの信頼性の最適化

データを分析するために、次の 2 種類のクエリを送信できます。

  • インタラクティブ クエリ: 送信されたインタラクティブ クエリは、直ちに実行へ回されます。
  • バッチクエリ: 送信されたバッチクエリはキューに入り、十分なスロット リソースが使用可能になるとすぐに開始されます。BigQuery では、24 時間以内にクエリを開始しなかった場合、ジョブの優先度をインタラクティブに変更し、クエリを直ちに実行へ回します。

インタラクティブ クエリとバッチクエリの両方が同じスロット リソースを使用します。実際に、BigQuery スケジューラによってバッチクエリが開始された後は、インタラクティブ クエリとバッチクエリの優先度に違いはありません。ただし、インタラクティブ クエリとバッチクエリのクエリ上限と割り当てに対する影響は異なります。インタラクティブ クエリは同時実行クエリのレート制限に対してカウントされますが、バッチクエリはカウントされません。

同時実行クエリの上限に達すると、それを超えるインタラクティブ クエリは quotaExceeded エラーで失敗します。この割り当ては保護のために確保されています。通常、使用可能なスロットが完全に消費されていない限り、カスタマーケア営業部門に連絡することでこの割り当てを引き上げることができます。ただし、同時実行のクエリが多くなるほど、クエリごとのコンピューティング リソースが全体的に使用できなくなるため、リソースの競合を引き起こし、クエリあたりの処理スループットが低下する可能性があります。このため、同時実行クエリの割り当ては、スロット リソースの限界点を超えないようにする必要があります。クエリの同時実行エラーが発生した場合は、クエリジョブのレイテンシに悪影響が及ぶのを避けるため、指数バックオフのロジックでクエリを再試行できます。

環境内の同時実行クエリの数を減らすには、次の選択肢があります。

  • 読み取りバイト数は推定するが、実際にはクエリを処理しないドライラン モードでクエリを実行する。
  • クエリ自体を実行するのではなく、データをテストや探索するときに、BigQuery のテーブル プレビュー機能を使用してテーブルデータをプレビューする。
  • キャッシュに保存されたクエリ結果を使用する。一部の例外を除き、インタラクティブ クエリとバッチクエリの両方を含むすべてのクエリ結果は、一時テーブルに約 24 時間キャッシュ保存されます。実行中、キャッシュに保存されたクエリは同時実行クエリの上限に引き続きカウントされますが、BigQuery では結果セットを計算する必要がないため、キャッシュに保存された結果を使用するクエリは大幅に早くなります。
  • BI Engine(BigQuery の高速インメモリ分析サービス)を使用する。BI Engine を使用すると、Google データポータルSQL インターフェースなどのツールを使用してインタラクティブなダッシュボードとレポートを作成し、BigQuery に保存されているデータの同時実行を改善できます。これは、多数の小規模なクエリがある場合に特に効果的です。

クエリの同時実行とジョブのパフォーマンスに関連するその他の検討事項には、ジョブの分離とジョブを交互に配置することがあります。プロジェクトや予約間でアプリケーションのユースケースごとにクエリジョブを分離すると、うるさいご近所(クエリで大量のリソースが使用され他のクエリのパフォーマンスに悪影響を与える可能性がある)問題を軽減できます。これにより、プロジェクトあたりの同時実行クエリ上限に達する可能性も低くなります。

ジョブを交互に配置、すなわち複数のジョブを同時に送信するのではなく順番に複数のジョブを送信することによっても、全体的なパフォーマンスが向上しエラー率が低下する可能性があります。たとえば、5 つの複合的なジョブのセットについて考えてみます。これらの 5 つのクエリを同時実行すると、多数のスロットが使用され、1 時間で実行が完了するとします。同じ 5 つのジョブを連続して送信すると、同様に 1 時間で実行されるかもしれませんが、スロット リソースは他のクエリによって使用されるように解放され、同時実行クエリの上限に達する可能性が低くなります。

BigQuery では、フェア スケジューリングを使用して、プロジェクト内または予約内の競合するクエリ間でリソースが割り当てられます。これは、すべてのクエリが使用可能なすべてのスロットにいつでも同等にアクセスできること、および各クエリの要求量が変化すると、アクティブなクエリ間で容量が動的かつ自動的に再割り当てされることを意味します。このため、同じプロジェクトまたは予約でビジネス クリティカルな本番環境クエリや開発 / テストクエリを実行することは理想的ではありません。各クエリがスロットに同等にアクセスできるため、重要ではないクエリが重要な処理中のクエリのパフォーマンスに影響する可能性があるためです。クエリを実行する前に、クエリに優先順位を付けることをおすすめします。

信頼性を最適化するための DML の考慮事項

BigQuery のデータ操作言語(DML)ステートメントを使用すると、BigQuery テーブルのデータの更新、挿入、削除が可能になり、信頼性に関する独自のガイドラインも用意されています。

  • BigQuery は完全にアトミックであるため、各 DML ステートメントでは暗黙トランザクションが開始されます。つまり、ステートメントによる変更は、DML ステートメントが成功して終了するたびに自動的にコミットされます。
  • DML の UPDATE、DELETE、MERGE ステートメントは、アクティブなストリーミング バッファがあるテーブルには使用できません。そうしようとすると、クエリは失敗します。
  • DML INSERT、UPDATE、DELETE、MERGE ステートメントには、同時実行の割り当て上限がありません。ただし、同時実行ジョブの特定のしきい値に達した場合、新しいジョブは保留中のステータスのキューに入れられます。
  • 同じテーブルに対する変更 DML ステートメントが同時実行される場合、BigQuery では、DML が同じバックエンド ファイルを変更できるかどうかを判断して、1 つの DML だけに続行を許可し、他は最大 3 回再試行します。後続の DML の再試行が 3 回失敗すると、変更時の競合により、その DML ステートメントは失敗します。
  • BigQuery は、DML の UPDATE、DELETE、MERGE オペレーションを完全にサポートしていますが、トランザクション型の OLTP データベースを目的としたものではありません。

ベスト プラクティスとしては、DML 行に対する個別の更新や挿入を大量に送信しないようにします。また、可能な場合は DML オペレーションをグループ化します。

信頼性を最適化するための UDF の考慮事項

BigQuery のユーザー定義関数(UDF)は、SQL 式または JavaScript コードから作成された永続関数または一時関数であり、指定されたコードの実行に基づいて結果を返します。UDF には、信頼性に関する独自のガイドラインがあります。

  • 通常 UDF は、標準 SQL クエリよりも多くのスロット リソースを消費し、ジョブのパフォーマンスに影響を与える可能性があります。関数を SQL で表現できる場合は、コードを標準 SQL のクエリジョブとして実行するのが最適です。
  • JavaScript UDF は、タイムアウトして、クエリが完了しなくなることがあります。タイムアウトは 5 分程度ですが、関数が消費する CPU 時間、JavaScript 関数の入出力の規模など、複数の要因によって変わる可能性があります。
  • UDF には、UDF 用の割り当てと同時実行クエリの上限が適用されます。詳細については、UDF の上限をご覧ください。

割り当てと上限を管理する

前述のように、クエリジョブにはいくつかの割り当てと上限が適用されます。こうした上限は、クエリの種類やその他の要因によって異なりますが、クエリやスクリプトの実行時間の上限は 6 時間です。この上限を変更することはできません。ただし、場合によってはクエリを再試行できます。その場合、再試行されたクエリはさらに 6 時間実行でき、最大 3 回再試行できます。

クエリジョブのモニタリング

信頼性の高いアプリケーションを実行するためには、BigQuery ジョブをモニタリングすることが不可欠です。モニタリングには、BigQuery 管理リソースグラフCloud Monitoring ダッシュボード、BigQuery の Information_Schema テーブル を使用できます。
BigQuery 管理リソースグラフと Cloud Monitoring ダッシュボードでは、クエリされたバイト数、同時実行されるクエリの数、スロットの使用、クエリのレイテンシなどをネイティブにモニタリングできます。INFORMATION_SCHEMA テーブルは、ジョブタイプ、特定のエラー メッセージ、キャッシュ保存率、ジョブの複雑さなどに関する追加のメタデータを提供します。INFORMATION_SCHEMA テーブルを使用すると、現在のクエリ(保留中クエリまたは作成時からの長さ順に並べられた実行中のクエリ)のリストを提供する次のクエリのように、別のカスタマイズ余地が提供されます。

SELECT
    creation_time,
    project_id,
    user_email,
    job_id,
    job_type,
    priority,
    state,
    TIMESTAMP_DIFF(CURRENT_TIMESTAMP(), start_time,second) as running_time_sec
 FROM
   region-us.INFORMATION_SCHEMA.JOBS_BY_PROJECT
 WHERE
    creation_time BETWEEN TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY) AND CURRENT_TIMESTAMP()
    AND state != "DONE"
ORDER BY
    running_time_sec DESC

データのクエリに関するユースケース

リアルタイム分析

このユースケースでは、ストリーミング データを使用してリアルタイム BI ダッシュボードにフィードされ、それがインタラクティブ クエリを実行する多数のユーザーにより使用されます。

このユースケースでは、BI ダッシュボードがうるさい隣人になって他の汎用クエリジョブのパフォーマンスに影響を与えないようにするために、個別のプロジェクトや予約を使用して BI ダッシュボードのクエリを他の汎用クエリから分離しておく必要があります。また、処理中のクエリ、コストの高いクエリ、BigQuery のアンチパターンを示す SQL クエリのモニタリングは、INFORMATION_SCHEMA テーブルを確認することによって行われ、不要な費用とクエリのレイテンシを避けるように修正する必要があります。

多数の同時実行クエリジョブが BI ダッシュボードに対して送信された場合や、クエリのレイテンシが懸念される場合は、BI Engine の活用を検討してください。

カスタムコスト管理の上限を作成して、ユーザーまたはテーブルあたり 1 日で処理可能なデータ量に制限することを検討してください。

バッチデータ処理

このユースケースでは、丸 1 日分のデータの分析を通して複合的な夜間のジョブが処理され、データ拡充のために他のデータソースと結合されます。

リアルタイム ユースケースのガイダンスと同様、こうしたジョブがうるさい隣人になり、他のクエリジョブのパフォーマンスに影響を与える懸念を回避するため、これらの複雑なバッチクエリについては、別のプロジェクトや予約を使用して、他の汎用クエリから分離することをおすすめします。また、長時間処理中のクエリ、コストの高いクエリ、BigQuery のアンチパターンを示す SQL クエリは、INFORMATION_SCHEMA テーブルを使用してモニタリングし、不要な費用とクエリのレイテンシが発生しないように修正する必要があります。

パフォーマンスの悪いジョブに対してアラートを出すため、空きスロットの低下、長いクエリ時間、大量のスキャンバイトの発生時に、Cloud Monitoring でアラートを作成することを検討してください。

次のステップ