Snowflakeでウェアハウスの負荷監視を試してみた

2021.08.24

こんにちは!エノカワです。

Snowflakeでクエリの実行やDML操作を行うには、ウェアハウスが必要です。

ウェアハウスにはサイズがあり、サイズによって使用できるコンピューティングリソースが決まります。
また、ウェアハウスをマルチクラスターで構成し、同時並行で大量のクエリを捌くといったこともできます。

用途に応じてサイズを変更したり、マルチクラスター構成にしたりと柔軟に対応できるのですが、
このメリットを活かすには最適なサイズや構成を見積もることがポイントになってきます。

Snowflakeではウェアハウス負荷監視の機能が提供されています。

今回は実際にウェアハウスの負荷監視を試してみました。

ウェアハウス負荷の監視

ウェアハウスの負荷はウェブインターフェースで確認できます。

画面上部の「ウェアハウス」でウェアハウス一覧画面に切り替え、対象のウェアハウスを選択します。

画面中央に時系列データの棒グラフが表示されました。

横軸は5分間隔の時間、縦軸はクエリ数です。
バーはウェアハウスによって処理された同時クエリを示しています。

表示する時間範囲は最小8時間から最大2週間の範囲を選択できます。
チャートのスライダーを任意の位置にドラッグして、表示する期間を変更することができます。

バーにカーソルを合わせると、各クエリステータスの個別の負荷が表示されます。

クエリステータスには、実行中や実行待ち(キュー済み)などがあります。
クエリステータスやクエリ負荷の計算方法などの詳細についてはドキュメントを参照ください。

それでは実際にクエリを実行して負荷を確認してみましょう。

サンプルデータの検索

サンプルデータベースSNOWFLAKE_SAMPLE_DATATPCH_SF100.LINEITEMを利用します。
数十億オーダーの件数を持つテーブルです。

実行クエリ

ドキュメントに記載されている格概要レポートのクエリを使用します。

select
       l_returnflag,
       l_linestatus,
       sum(l_quantity) as sum_qty,
       sum(l_extendedprice) as sum_base_price,
       sum(l_extendedprice * (1-l_discount)) as sum_disc_price,
       sum(l_extendedprice * (1-l_discount) * (1+l_tax)) as sum_charge,
       avg(l_quantity) as avg_qty,
       avg(l_extendedprice) as avg_price,
       avg(l_discount) as avg_disc,
       count(*) as count_order
 from
       snowflake_sample_data.tpch_sf100.lineitem
 where
       l_shipdate <= dateadd(day, -90, to_date('1998-12-01'))
 group by
       l_returnflag,
       l_linestatus
 order by
       l_returnflag,
       l_linestatus;

実行回数

以下の回数分のクエリを実行します。

100回

※同時刻にクエリを開始するタスクを100個作成
※リザルトキャッシュ機能はOFF


【CASE.1】ウェアハウスサイズ:X-Small

まずはウェアハウスサイズX-Smallで実行してみましょう。
最大クラスターは1とし、マルチクラスターは使用しません。

作成画面

SQL

CREATE OR REPLACE WAREHOUSE SINGLE_XS_WH WITH
  WAREHOUSE_SIZE = 'XSMALL'
  WAREHOUSE_TYPE = 'STANDARD'
  AUTO_SUSPEND = 600
  AUTO_RESUME = TRUE
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 1
  SCALING_POLICY = 'STANDARD';

クエリ負荷

バーの青色の部分が実行中のクエリ、オレンジ色の部分が実行待ちのクエリです。
キューに入って実行待ちになっているクエリの割合が多くなっていることが分かりますね。

クエリの数が多いためにリソースが足りず、実行待ちとなっている時間がボトルネックになっているようです。
クラスター数を増やすことで改善が期待できそうなので、次はマルチクラスターを使用してみましょう。


【CASE.2】ウェアハウスサイズ:X-Small、マルチクラスター

最大クラスターを10に変更し、マルチクラスターは使用します。
ウェアハウスサイズX-Smallのままとします。

作成画面

SQL

CREATE OR REPLACE WAREHOUSE MULTI_XS_WH WITH
  WAREHOUSE_SIZE = 'XSMALL'
  WAREHOUSE_TYPE = 'STANDARD'
  AUTO_SUSPEND = 600
  AUTO_RESUME = TRUE
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 10
  SCALING_POLICY = 'STANDARD';

クエリ負荷

実行待ちのクエリの割合が少なくなりました!
マルチクラスターを使用したことによりクラスター数が自動的に増え、捌けるクエリの数も増えたようです。
また、バーの数も3本から1本に減っているので完了するまでの時間も短縮されていることが分かりますね。

マルチクラスターを使用することでボトルネックを解消することができました。
では、マルチクラスターを使用せずにウェアハウスのサイズを大きくしたらどうなるでしょうか?
試してみましょう。


【CASE.3】ウェアハウスサイズ:X-Large

ウェアハウスサイズX-Largeで実行します。
最大クラスターは1とし、マルチクラスターは使用しません。

作成画面

SQL

CREATE OR REPLACE WAREHOUSE SINGLE_XL_WH WITH
  WAREHOUSE_SIZE = 'XLARGE'
  WAREHOUSE_TYPE = 'STANDARD'
  AUTO_SUSPEND = 600
  AUTO_RESUME = TRUE
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 1
  SCALING_POLICY = 'STANDARD';

クエリ負荷

実行待ちのクエリの割合が増えてしまいました。。
僅かですがグレー色のバーも出現していますね。
ブレー色のバーはウェアハウスをプロビジョニングしている間に実行待ちとなったクエリです。

バーの数は1本なので完了するまでの時間は延びていないようです。

ウェアハウスのサイズを大きくしたことで個々のクエリにかかる時間は短くなったのですが、
シングルクラスターなので実行待ちのクエリが多くなってしまったようですね。

実行結果

今回実行したCASEと実行時間を以下に整理しておきます。
実行する条件や環境によって結果は異なりますので、あくまで参考として見てください。

CASE ウェアハウスサイズ マルチクラスター 全体実行時間 平均実行時間
1 X-Small 735秒 387秒
2 X-Small 169秒 109秒
3 X-Large 77秒 23秒
  • 全体実行時間
    最初のクエリを開始してから最後のクエリが完了するまでの時間
  • 平均実行時間
    個々のクエリの実行時間の平均

QUERY_HISTORYテーブル関数

実行時間はQUERY_HISTORYテーブル変数を使用して算出しました。

クエリ毎の開始時間、終了時間や実行されたクラスターの番号などが取得できますので、
より詳細な負荷分析をしたい場合はQUERY_HISTORYテーブル変数を使用すると良いと思います。

取得できる項目については、ドキュメントを参照ください。

また、以下の記事ではQUERY_HISTORYテーブル変数を使ったロード履歴の可視化を行っていますので、
興味のある方は参照してみてください。

まとめ

以上、ウェアハウスの負荷監視を試してみました。

専用の機能が提供されているので、簡単にウェアハウスの負荷監視を設定することができました。

棒グラフ表示なので、実行したクエリのうち実行待ちが占める割合がひと目で分かるのが良いですね。
また、時間経過による推移も確認できるので、ウェアハウスサイズやクラスター構成などチューニングの
判断材料として活用できそうです。

なお、ウェブインターフェイスではフィルター機能は無いようなので、
対象ごとにウェアハウスの名前を分かるなどの工夫は必要そうだと感じました。

より詳細な負荷状況を確認したいのであれば、QUERY_HISTORYテーブル変数を使用し、
負荷の概観を確認したいのであれば、ウェブインターフェイスを使用するといった使い分けができそうですね。

参考