スロットについて
BigQuery スロットは、BigQuery で SQL クエリやその他のジョブタイプの実行に使用される仮想コンピューティング ユニットです。クエリの実行中に、クエリで使用されるスロット数が BigQuery により自動的に決定されます。使用されるスロット数は、処理されるデータの量、クエリの複雑さ、使用可能なスロット数によって異なります。一般に、アクセスできるスロットが多いほど、同時実行できるクエリの数が増え、複雑なクエリをより高速に実行できます。
すべてのクエリでスロットが使用されますが、使用量の課金方法には、オンデマンド料金モデルと容量ベースの料金モデルの 2 つのオプションがあります。
デフォルトでは、オンデマンド モデルを使用して課金されます。このモデルでは、各クエリによって処理されたデータの量(TiB 単位)に基づいて課金されます。オンデマンド モデルを使用するプロジェクトには、一時的なバースト容量を備えた、プロジェクトごとおよび組織ごとのスロット上限が適用されます。オンデマンド モデルを使用するほとんどのユーザーにとって、スロット容量の上限は十分です。ただし、ワークロードによっては、アクセスできるスロットが多いほど、クエリのパフォーマンスが向上する場合があります。アカウントで使用しているスロットの数を確認するには、BigQuery のモニタリングをご覧ください。
容量ベースのモデルでは、クエリに割り当てられたスロット容量に対して時間の経過とともに課金されます。このモデルでは、合計スロット容量を明示的に制御できますが、オンデマンド モデルではできません。使用するスロットの数は、予約で明示的に選択します。予約のスロット数は、常に割り当てられるベースライン数として指定することも、必要に応じて割り当てられる自動スケーリング数として指定することもできます。
スロットを使用したクエリ実行
BigQuery がクエリジョブを実行すると、SQL ステートメントが実行プランに変換され、一連のクエリステージに分割されます。クエリステージは、より細かい実行ステップから構成されます。BigQuery は、高度に分散された並列アーキテクチャを使用して、これらのクエリを実行します。ステージは、多くのワーカーを同時に実行できる作業単位をモデル化しています。データは、高速の分散シャッフル アーキテクチャを使用してステージ間で渡されます。このアーキテクチャの詳細については、Google Cloud ブログをご覧ください。
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 のフェア スケジューリング
BigQuery では、フェア スケジューリングと呼ばれるアルゴリズムを使用して、単一の予約にスロット容量を割り当てます。
BigQuery スケジューラでは、スロットを予約内の実行中のクエリとともにプロジェクト間で均等に共有し、さらに特定のプロジェクトの複数ジョブでも均等に共有するように自動的に調整されます。スケジューラでは最終的な公平性を確保します。短期間に、一部のジョブでスロットの割り当てが不均衡になる可能性がありますが、スケジューラは最終的にこれを是正します。スケジューラの目的は、積極的に実行中のタスクでエビクションが発生する(結果としてスロット時間が無駄になる)状況と、過度に寛容で、ジョブでのタスク実行が長引く(結果としてスロット時間の割り当てが不均衡になる)状況のバランスを取ることです。
フェア スケジューリングは、すべてのクエリが、使用可能なすべてのスロットにいつでもアクセスできることを意味します。また、各クエリの要求量が変化すると、アクティブなクエリ間で容量が動的かつ自動的に再割り当てされることも意味します。次の条件の下で、クエリが完了し、新しいクエリが送信されて実行されます。
- 新しいクエリが送信されるたびに、実行中のクエリ間で容量が自動的に再割り当てされます。個々の作業単位は、各クエリでより多くの容量が使用可能になると、一時停止、再開、キューへの格納が適切に行われます。
- クエリが完了すると、そのクエリが消費していた容量が他のすべてのクエリですぐに自動的に使用可能になります。
- クエリの動的 DAG の変更によりクエリの容量が変化するたびに、BigQuery はそのクエリおよびその他のすべてのクエリの利用可能量を自動的に再計算し、必要に応じてスロットを再割り当ておよび一時停止します。
クエリの複雑さとサイズに応じて、利用できるスロットをすべて利用しない場合もあれば、さらに多くのスロットを必要とする場合もあります。BigQuery では、フェア スケジューリングを行うことにより、すべてのスロットがいつでも完全に使用される状況を動的に実現します。
重要なジョブが、スケジューラから受け取るより多いスロットを終始必要とする場合は、必要なスロット数で追加の予約を作成し、その予約にジョブを割り当てることを検討してください。
スロットの割り当てと上限
スロットの割り当てと上限により、BigQuery の安全性が確保されます。次のように、料金モデルによって使用するスロット割り当てのタイプが異なります。
オンデマンド料金モデル: 一時的なバースト機能を備えた、プロジェクトごとおよび組織ごとのスロット数の上限が適用されます。ワークロードによっては、アクセスできるスロットが多いほど、クエリのパフォーマンスが向上します。
容量ベースの料金モデル: 予約の割り当てと上限によって、ロケーション内のすべての予約に割り当てることができるスロットの最大数が決まります。割り当てではなく、予約とコミットメントに対してのみ課金されます。 スロットの割り当てを増やす方法については、割り当ての増加リクエストをご覧ください。
使用しているスロットの数を確認するには、BigQuery のモニタリングをご覧ください。
アイドル スロット
任意の時点で、一部のスロットがアイドル状態のこともあります。これには次のものが含まれます。
- 予約のベースラインに割り当てられていないスロット コミットメント。
- 予約のベースラインに割り当てられているものの、使用されていないスロット。
アイドル スロットは、オンデマンド料金モデルを使用する場合は適用されません。
デフォルトでは、予約で実行されるクエリは、同じ管理プロジェクト内の他の予約のアイドル スロットを自動的に使用します。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 では他のジョブが追加のスロットを借りられます。その結果、指定されたスロット容量を超えるスロット使用量が発生することがあります。スロットの使用量が超過した場合、その超過分は、公平な割り当て以上の割り当てを受けたジョブにのみ適用されます。
超過分のスロットに対しては、直接課金されません。代わりに、ジョブは引き続き実行され、超過使用量が、すべて割り当てられた容量でカバーされるまで、公平な割合でスロット使用量が蓄積されます。余分なスロットは、特定の実行統計情報を除き、報告されるスロット使用量から除外されます。
ただし、将来の遅延を減らし、スロットのコスト変動の減少や、テール レイテンシの低減などのメリットを得るために、スロットのプリエンプティブな借用が行われることがあります。スロットの借用は、合計スロット容量のごく一部に制限されます。