スロットについて
BigQuery スロットは、BigQuery で SQL クエリを実行するために使用される仮想 CPU です。クエリの実行中、BigQuery はクエリのサイズと複雑さに応じて、クエリに必要なスロット数を自動的に計算します。
オンデマンド料金モデルまたは容量ベースの料金モデルのどちらを使用するかを選択できます。どちらのモデルも、データ処理にスロットを使用します。容量ベースのモデルでは、専用または自動スケーリングされたクエリ処理容量に対して支払うことができます。容量ベースのモデルではスロットと分析容量を明示的に制御できますが、オンデマンド モデルではできません。
容量ベースの料金モデルのお客様は、予約するスロット数を明示的に選択します。クエリはその容量内で実行され、デプロイされる 1 秒ごとに容量に対して継続的に支払います。たとえば、BigQuery スロットを 2,000 個購入した場合、集計クエリは任意の時点で 2,000 個の仮想 CPU を使用する状態に制限されます。この容量は削除するまで保持され、削除するまで 2,000 スロットに対して支払います。
BigQuery オンデマンド料金モデルのプロジェクトには、一時的なバースト容量を備えたプロジェクトごとのスロットの割り当てが適用されます。オンデマンド モデルを使用するほとんどのユーザーにとって、デフォルトで割り当てられるスロットの容量は十分です。ワークロードによっては、より多くのスロットにアクセスできるようにすることでクエリ パフォーマンスが向上します。アカウントで使用しているスロットの数を確認するには、BigQuery のモニタリングをご覧ください。
購入するスロット数を見積もる
BigQuery は、リソースの増加によって効率的にスケールされるように設計されています。ワークロードによっては、容量が徐々に増加することで、得られるメリットも増えていく可能性があります。このため、最適な購入スロット数は、パフォーマンス、スループット、ユーティリティの要件によって異なります。
ベースライン スロットと自動スケーリング スロットを試して、スロットの最適な構成を決定できます。たとえば、500 ベースライン スロットでワークロードをテストし、次に 1,000 スロット、1,500 スロット、2,000 スロットと順にテストして、パフォーマンスへの影響を確認します。
選択した月額料金と一緒に、プロジェクトの現在のスロット使用量も確認できます。オンデマンド ワークロードでのスロットの上限は 2,000 スロットですが、ビューの INFORMATION_SCHEMA.JOBS*
、Cloud Logging、Jobs API、または BigQuery の監査ログを使用して、プロジェクトで実際に使用されているスロットの数を確認することが重要です。詳細については、利用可能なスロットと割り当てられているスロットの表示をご覧ください。
スロットを購入して少なくとも 7 日間ワークロードを実行した後、スロット見積もりツールを使用してパフォーマンスを分析し、スロットの追加や削除の影響をモデル化できます。詳細については、スロットの容量要件の見積もりをご覧ください。
スロットを使用したクエリ実行
BigQuery がクエリジョブを実行すると、宣言型の SQL ステートメントを実行グラフに変換し、一連のクエリステージに分割します。クエリステージは、より細かい実行ステップから構成されます。BigQuery は、高度に分散された並列アーキテクチャを使用して、これらのクエリを実行します。ステージは、多くのワーカーを同時に実行できる作業単位をモデル化しています。ステージは、高速の分散シャッフル アーキテクチャを介して相互に通信を行います。このアーキテクチャの詳細については、Google Cloud ブログをご覧ください。
BigQuery のクエリ実行は動的に行われるため、クエリの実行中でもクエリプランを変更できます。クエリの実行中に追加されるステージは、主にクエリワーカー全体にわたるデータ分散を向上させるために使用されます。
BigQuery では、複数のステージを同時に実行できます。BigQuery は投機的実行を行ってクエリを高速化し、ステージを動的に再分割して最適な並列化を実現できます。
BigQuery スロットにより、クエリの各ステージで個々の作業単位が実行されます。たとえば、ステージの最適並列化係数が 10 であると BigQuery が判断した場合、ステージの処理に 10 スロットがリクエストされます。
スロット リソース エコノミーにおけるクエリ実行
現在利用できるよりも多くのスロットをクエリがリクエストした場合、個々の作業単位は、キューに入れられてスロットが使用可能になるのを待ちます。クエリ実行の処理が進行するにつれて、スロットの解放とともに、キューに格納された作業単位が動的に取得され実行されます。
BigQuery では、クエリの特定の段階で任意の数のスロットをリクエストできます。リクエストされるスロットの数は、購入容量とは関係なく、BigQuery がその段階で選択した最適な並列化係数を示します。作業単位は、キューに入れられ、スロットが使用可能になると実行されます。
クエリ要求がコミットしたスロット数を超えた場合、追加スロットには課金されません。したがって、追加のオンデマンド レートは課金されません。個々の作業単位はキューに入れられます。
たとえば
- クエリステージは 2,000 個のスロットをリクエストしていますが、1,000 個のスロットしか利用できないとします。
- 1,000 個のスロットがすべて消費され、残りの 1,000 個のスロットがキューに入れられます。
- その後、100 個のスロットが作業を終了すると、キューに入れられた 100 個の作業単位から動的に 1,000 個の作業単位が選択されます。キューには、900 作業単位が残ります。
- その後、500 個のスロットが作業を終了すると、キューに入れられた 900 個の作業単位から動的に 500 個の作業単位が選択されます。キューには、400 作業単位が残ります。
アイドル スロット
任意の時点で、一部のスロットがアイドル状態のこともあります。これには次のものが含まれます。
- 予約のベースラインに割り当てられていないスロット コミットメント。
- 予約のベースラインに割り当てられているものの、使用されていないスロット。
デフォルトでは、予約で実行されるクエリは、同じ管理プロジェクト内の他の予約のアイドル スロットを自動的に使用します。BigQuery は、割り当てられた予約に、必要に応じてすぐにスロットを割り当てます。別の予約で使用されていたアイドル スロットはすぐにプリエンプトされます。短い時間ですが、スロットの合計使用量がすべての予約で指定した最大値を超えることがありますが、この追加のスロット使用量に対しては請求されません。
たとえば、次のような予約設定があるとします。
project_a
はreservation_a
に割り当てられています。自動スケーリングのない 500 個のベースライン スロットがあります。project_b
はreservation_b
に割り当てられています。100 個のベースライン スロットがあり、自動スケーリングは行われません。- 両方の予約が同じ管理プロジェクトにあり、これらの予約に割り当てられているプロジェクトはほかにありません。
project_b
で query_b
を実行します。project_a
で実行中のクエリがない場合、query_b
は reservation_a
から 500 個のアイドル スロットにアクセスできます。query_b
が実行中の場合、最大 600 スロット(100 ベースライン スロット + 500 アイドル スロット)を使用することがあります。
query_b
の実行中に、500 個のスロットを使用できる project_a
で query_a
を実行するとします。
project_a
に 500 個のベースライン スロットが予約されているため、query_a
はすぐに開始され、500 個のスロットが割り振られます。query_b
に割り当てられるスロット数は、100 個のベースライン スロットに急速に減少します。project_b
で実行される追加のクエリは、これらの 100 個のスロットを共有します。後続のクエリで開始に十分なスロットがない場合は、現在実行中のクエリが完了してスロットが使用可能になるまでキューに追加されます。
この例では、project_b
がベースライン スロットまたは自動スケーリングのない予約に割り当てられている場合、query_a
の実行後に query_b
にスロットがなくなります。アイドル スロットが利用可能になるか、クエリがタイムアウトするまで、BigQuery は query_b
を一時停止します。project_b
の追加クエリは、アイドル状態のスロットが使用可能になるまでキューに入ります。
プロビジョニングされたスロットのみが予約で使用されるようにするには、ignore_idle_slots
を true
に設定します。ただし、ignore_idle_slots
が true
に設定された予約では、アイドル スロットを他の予約と共有できます。
異なるエディションの予約の間でアイドル スロットを共有することはできません。共有できるのは、ベースライン スロットまたはコミット済みスロットのみです。自動スケーリング済みスロットは一時的に利用できる場合がありますが、スケールダウンされる可能性があるため、他の予約のアイドル スロットとして共有することはできません。
ignore_idle_slots
が false である限り、予約にスロット数 0
の設定が可能で、未使用のスロットに引き続きアクセスできます。default
予約のみを使用する場合は、ベスト プラクティスとして ignore_idle_slots
をオフに切り替えてください。それから、その予約にプロジェクトまたはフォルダを割り当てると、アイドル スロットのみが使用されます。
ML_EXTERNAL
タイプの割り当ては例外であり、BigQuery ML の外部モデル作成ジョブで使用されるスロットはプリエンプティブルではありません。ML_EXTERNAL
と QUERY
の両方の割り当てタイプを含む予約のスロットは、ML_EXTERNAL
ジョブがスロットを占有していない場合にのみ、他のクエリジョブに使用できます。また、これらのジョブは、他の予約のアイドル スロットを使用できません。
予約内のスロット割り当て
BigQuery では、フェア スケジューリングと呼ばれるアルゴリズムを使用して、単一の予約にスロット容量を割り当てます。
BigQuery スケジューラでは、スロットを予約内の実行中のクエリとともにプロジェクト間で均等に共有し、さらに特定のプロジェクトの複数ジョブでも均等に共有するように自動的に調整されます。スケジューラでは最終的な公平性を確保します。短期間に、一部のジョブでスロットの割り当てが不均衡になる可能性がありますが、スケジューラは最終的にこれを是正します。スケジューラの目的は、積極的に実行中のタスクのエビクションが発生する(結果としてスロット時間が無駄になる)状況と、過度に寛容で、ジョブでのタスク実行が長引く(結果としてスロット時間の割り当てが不均衡になる)状況のバランスを取ることです。
重要なジョブがスケジューラから受け取るより多いスロットを終始必要とする場合は、保証されているスロット数で追加の予約を作成し、その予約にジョブを割り当てることを検討してください。
スロットの過剰使用
ジョブがスロットを長時間保持すると、上記の説明のように、不公平なスロット割り当てが発生する可能性があります。遅延を防ぐために、他のジョブが追加のスロットを借用することがあります。その結果、指定されたスロット容量を超えるスロット使用量が発生することがあります。スロットの使用量が超過した場合、その超過分は公平な割り当てを超えて受信したジョブにのみ適用されます。
超過分のスロットに対しては、直接課金されません。代わりに、ジョブは引き続き実行され、超過使用量がすべて通常の容量でカバーされるまで、公平な割合でスロット使用量が蓄積されます。余分なスロットは、特定の実行統計情報を除き、報告されるスロット使用量から除外されます。
ただし、将来の遅延を減らし、スロットのコスト変動の減少や、テール レイテンシの低減などのメリットを得るために、スロットのプリエンプティブな借用が行われることがあります。スロットの借用は、合計スロット容量のごく一部に制限されます。
BigQuery のフェア スケジューリング
スロットはプロジェクト間で均等に分配され、次にプロジェクトのジョブ内で分配されます。これは、すべてのクエリが使用可能なすべてのスロットにいつでもアクセスできることを意味します。また、各クエリの要求量が変化すると、アクティブなクエリ間で容量が動的かつ自動的に再割り当てされることも意味します。次の条件の下で、クエリが完了し、新しいクエリが送信されて実行されます。
- 新しいクエリが送信されるたびに、実行中のクエリ間で容量が自動的に再割り当てされます。個々の作業単位は、各クエリでより多くの容量が使用可能になると、一時停止、再開、キューへの格納が適切に行われます。
- クエリが完了すると、そのクエリが消費していた容量が他のすべてのクエリですぐに自動的に使用可能になります。
- クエリの動的 DAG の変更によりクエリの容量が変化するたびに、BigQuery はそのクエリおよびその他のすべてのクエリの利用可能量を自動的に再計算し、必要に応じてスロットを再割り当ておよび一時停止します。
クエリの複雑さとサイズに応じて、利用できるスロットをすべて利用しない場合もあれば、さらに多くのスロットを必要とする場合もあります。BigQuery では、フェア スケジューリングを行うことにより、すべてのスロットがいつでも完全に使用される状況を動的に実現します。