はじめに
BigQueryのオンデマンド/エディション環境で負荷テストを行う際、「同時実行数を増やしてスロット(slot)がどこまで自動的にスケールするか」を検証する場面があります。
今回、staging環境(baseline 0、autoscalingによるslot割り当て)で負荷テストを実施した際に、想定通りにslotが上がらず、クエリがpending状態のまま詰まるという事象に遭遇しました。その原因と対策をまとめます。
前提:BigQueryのslotとautoscaling
BigQueryのエディションモデルでは、クエリの実行にはslot(計算リソースの単位)が必要です。baselineを0に設定している環境では、常時確保されているslotが無く、クエリが実行されるたびにautoscalingが必要な分だけslotを動的に割り当てる仕組みになっています。
同時に複数のクエリが実行されると、これらは割り当てられたslotを取り合う形になり、slotが不足していれば後続のクエリはpending(順番待ち)状態になります。
問題現象
負荷テストとして、複数クエリを同時実行してslotがどこまでスケールするかを検証しようとしました。このとき、テスト用クエリとして単純な SELECT 1 のようなクエリを大量に同時実行する構成にしていました。
実行してみると、想定よりも明らかに実行時間が長くかかっており、BigQueryのジョブ詳細を確認したところ、複数のジョブが pending状態 のまま止まっていることが分かりました。
同時実行しているにもかかわらず、autoscalingによるslotの増加が起きていないように見える状況でした。
原因:cache hitによりautoscalingが発火しない
原因は、負荷テストに使っていたクエリが単純すぎたことでした。
SELECT 1 のように毎回全く同じ内容のクエリを投げると、BigQuery側のキャッシュ機構により cache hit してしまいます。cache hitしたクエリは実際の計算処理を行わないため、BigQuery側から見ると「計算リソースが不足している」状態にはならず、autoscalingの判断材料(スロット逼迫のシグナル)が発生しません。
結果として、同時にクエリを投げているにもかかわらず、
- 実際の計算が発生していないのでslotの追加割り当てが起きない
- それでいてジョブ自体は同時実行の枠を消費している
という状態になり、後続のジョブがpendingで詰まる、という現象が発生していたと考えられます。
対策:random要素を入れてcache missを起こす
対策として、負荷テストに使うクエリに ランダムな要素を含める ことで、意図的にcache missを発生させるようにしました。
イメージとしては以下のような形です。
-- cache hitしてしまうパターン(毎回同じ結果)
SELECT 1
-- cache missを起こすパターン(実行のたびに条件が変わる)
SELECT COUNT(*)
FROM `project.dataset.table`
WHERE some_column = CAST(RAND() * 1000000 AS INT64)
この変更により、各クエリが実際に計算処理を必要とするようになり、autoscalingが実行状況を検知してslotを増やす挙動が確認できるようになりました。手元の記録ではbaseline 0の状態から 概ね5前後まで slotが上昇したことを確認しています(正確な数値までは記録が残っていませんが、0から明確に増加が見られました)。
学んだこと:slotと同時実行数の関係
今回の件を通じて、slotと同時実行数の関係について以下のような整理ができました。
- slotはあくまで実際に計算処理が発生した場合にautoscalingの対象になる。クエリを同時に投げること自体がslot増加のトリガーになるわけではない
- cache hitするクエリは「同時実行している」ように見えても、BigQuery内部では計算リソースをほぼ使っていない
- baseline 0の環境で負荷テストを行う場合、autoscalingの挙動そのものを検証したいなら、キャッシュが効かない設計のクエリを使う必要がある
まとめ
負荷テストの目的が「実際の負荷がかかった際にautoscalingがどう振る舞うか」を検証することであれば、テストクエリ自体がキャッシュに乗ってしまわないよう設計する必要があります。
SELECT 1 のような一見無害なクエリでも、BigQueryのキャッシュ機構と組み合わさることで「同時実行しているのにリソースが増えない」という一見矛盾した挙動を引き起こすことがある、という点は今後の負荷テスト設計でも意識しておきたいポイントです。