Snowflakeのコストと性能は、テーブル設計やSQLよりも先に「仮想ウェアハウスをどう切るか」で大枠が決まります。サイズを一段上げるだけでクレジット消費は倍になり、自動停止の設定を一つ忘れるだけでアイドル時間が静かに課金され続けます。本記事では、サイズ選定・AUTO_SUSPEND/AUTO_RESUME・マルチクラスタ・ワークロード分離という四つの勘所を、AWS上で動くSnowflakeという前提を踏まえて整理します。落とし穴は検証段階で先に踏み抜き、本番では未然に防ぐ——EMWが実案件で徹底している考え方も交えて解説します。

01コンピュートとストレージの分離が設計の出発点

Snowflakeの仮想ウェアハウス(Virtual Warehouse)は、クエリを実行するためのコンピュートクラスタです。AWS上のSnowflakeでは、この計算資源はマネージドなEC2インスタンス群として内部的にプロビジョニングされ、データの実体はAmazon S3上に列指向のマイクロパーティションとして保持されます。ここで重要なのは、コンピュート(ウェアハウス)とストレージ(S3)が完全に分離しているという点です。同じS3上の1つのデータ実体に対して、複数のウェアハウスを独立して割り当てられるため、ワークロードごとに専用のコンピュートを用意しても、データを複製する必要はありません。

この分離こそが設計の自由度であり、そのままコスト最適化の余地になります。ウェアハウスは秒単位で起動・停止・リサイズでき、稼働している秒数だけ課金される(各起動時に60秒の最低課金あり)ため、「必要なときだけ、必要なサイズで、必要なワークロードにだけ」計算資源を割り当てる設計が可能です。逆に言えば、この自由度を活かせない設計——常時起動しっぱなし、全ワークロードを1つの巨大ウェアハウスに集約——にすると、性能もコストも同時に悪化します。

02サイズ選定:スケールアップは複雑クエリに効く

ウェアハウスのサイズはX-Smallから6X-Largeまで用意されており、X-Smallが1クレジット/時、そこから1サイズ上げるごとにクレジット消費は倍になります(6X-Largeで512クレジット/時)。課金は秒単位で、再開のたびに60秒ぶんの最低課金が発生します。サイズを上げる(スケールアップ)と、各クエリに割り当てられるメモリとローカルSSD、並列度が増えます。

公式ドキュメントは、大きく複雑なクエリほどウェアハウスサイズに対してほぼ線形に性能がスケールする一方、小さく単純なクエリは大きくしても速くならない、と述べています。つまりサイズアップは「重いバッチ集計や大規模JOIN、メモリにスピルしているクエリ」に効く手段であって、軽いクエリを闇雲に大きなウェアハウスで回すと、速くならないうえに最低課金ぶんだけ割高になります。判断材料はQuery Profileです。ローカル/リモートへのスピルが多い、あるいは実行時間の大半がスキャンに費やされているなら、一段上げる価値があります。

現場のコツ:迷ったら小さく始めるのが鉄則です。まずX-Small〜Smallで代表的なクエリを流し、Query Profileでスピルとキューの有無を確認してから、必要なワークロードだけを一段ずつ上げます。「とりあえずLarge」から始めると、下げる判断は心理的にもデータ的にも難しくなります。

03AUTO_SUSPEND / AUTO_RESUME:アイドル課金とキャッシュのトレードオフ

AUTO_SUSPEND(一定時間アイドルなら自動停止)とAUTO_RESUME(クエリが来たら自動再開)は、いずれもデフォルトで有効です。この2つはセットで使うのが原則で、片方だけ切ると「止まったまま再開しない」あるいは「起動しっぱなし」の事故につながります。停止時にはウェアハウスのローカルキャッシュが破棄されるため、再開直後のクエリは一時的に遅くなり、稼働を続けるうちにキャッシュが再構築されて速度が戻ります。ここに「クレジットを節約するために止める」対「キャッシュを温存して速度を保つ」というトレードオフがあります。

公式ガイダンスは、AUTO_SUSPENDを低め(例:5〜10分以下)に設定することを推奨しています。ただし、絞りすぎにも落とし穴があります。クエリの到着間隔が2〜3分空くワークロードでAUTO_SUSPENDを1分にすると、ウェアハウスは停止と再開を繰り返し、そのたびに60秒の最低課金が発生して、かえってクレジットを浪費します。下の図は、この「絞りすぎによる再開の乱発」と、適切に温存した場合の課金の違いを示したものです。

AUTO_SUSPEND 1分(絞りすぎ):クエリ間で毎回停止再開3回 → 60秒の最低課金 ×3 + 毎回キャッシュ破棄AUTO_SUSPEND 5分(調整後):ギャップを跨いで稼働継続再開1回・キャッシュ保持クエリ到着60秒の最低課金稼働(課金対象)
AUTO_SUSPENDを絞りすぎると再開が乱発し、短いクエリでも毎回60秒の最低課金が発生する。到着間隔に合わせて温存すると再開は1回で済み、キャッシュも保持される。

EMWでは実案件のPoC・検証環境で、このトレードオフを先に踏み抜くようにしています。あるBIワークロードの検証で、コスト削減を狙ってAUTO_SUSPENDを攻めすぎ、さらに一部のウェアハウスで自動停止を無効化したまま放置したところ、アイドル時間に想定外のクレジットを消費すると分かりました。この気づきを踏まえ、本番ではワークロードの到着間隔に合わせて停止時間を設定し、自動停止の無効化は原則禁止とする運用ルールを敷いています。落とし穴を検証段階で先に踏むことで、本番では未然に防ぐ——結果としてEMWは重大障害0を継続しています。

04マルチクラスタ:同時実行を「スケールアウト」で捌く

サイズアップ(スケールアップ)と混同しやすいのがマルチクラスタウェアハウス(スケールアウト)です。両者は解く問題が違います。スケールアップは1つの重いクエリを速くするための手段、マルチクラスタは多数の同時ユーザー・同時クエリでキューが発生する状況を解消するための手段です。単発の遅いクエリやデータロードの高速化にマルチクラスタは効きません。なお、マルチクラスタウェアハウスはEnterprise Edition以上の機能です。

マルチクラスタには2つのモードがあります。MIN_CLUSTER_COUNTとMAX_CLUSTER_COUNTを同じ値(かつ1超)にするMaximizedモードでは、起動時に全クラスタが立ち上がり常時稼働します。最小値を最大値より小さくするAuto-scaleモードでは、キューの発生状況に応じてSnowflakeがクラスタを自動で増減します。Auto-scale時のスケーリングポリシーは2つで、既定のStandardはキューが出たら速やかにクラスタを起動して待ち時間を最小化します。一方Economyは、新しいクラスタを起動しても6分以上は稼働で埋められると見込めるまで起動を待つことでクレジットを節約しますが、その分クエリがキューに並んで完了が遅れる可能性があります。課金は「ウェアハウスサイズ × 稼働中クラスタ数」を秒単位で積算します。

現場のコツ:検証でMaximizedモードを付けっぱなしにすると、夜間や週末など負荷が無い時間帯も全クラスタぶんが課金され続けると分かりました。本番ではオンライン利用のピークが読めるBIでもAuto-scale+MIN_CLUSTER_COUNT=1を基本とし、真に一定の高並列が前提の場合だけMaximizedを検討します。まず並列度の実測を取ってから決めるのが安全です。

05ワークロード分離:ETL / BI / アドホックを別ウェアハウスに

公式ドキュメントは「同質なクエリ(複雑さ・データセットなどが近いもの)を同じウェアハウスで実行する」ことを推奨しています。性質の異なるクエリを混在させると負荷分析が難しくなり、適切なサイズも決められず、重いバッチが軽いダッシュボードのレスポンスを巻き添えにするといった相互影響も起きるためです。これを設計に落とすと、ETL(データ取込・変換)、BI(ダッシュボード)、アドホック分析を、それぞれ専用のウェアハウスに分けるという形になります。前述のとおりデータ実体はS3上に1つだけ存在し、各ウェアハウスがそれを共有するので、分離してもデータの複製コストは生じません。

ワークロード別ウェアハウス分離(1つのデータ実体を共有)ELT・データ取込dbt / SnowpipeBIダッシュボード多数の同時ユーザーアドホック分析データサイエンスETL_WH(L)単一クラスタAUTO_SUSPEND 短BI_WH(M)マルチクラスタ 1→3Standard ポリシーADHOC_WH(XS〜S)単一クラスタAUTO_SUSPEND 短共有ストレージ層Amazon S3 上の単一データ実体(コピー不要)
ワークロードごとに専用ウェアハウスを割り当て、サイズ・クラスタ数・自動停止をそれぞれの特性に合わせる。データはS3上に1つだけ存在し、全ウェアハウスが共有する。

具体的には、決まった時間に走る重いバッチであるETLは、Lサイズ・単一クラスタ・短めのAUTO_SUSPENDで、実行中だけ大きく回してすぐ止めます。多数のユーザーが同時にアクセスするBIは、MサイズをベースにマルチクラスタのAuto-scaleでキューを吸収します。到着が不定期なアドホック分析は、XS〜Sで短いAUTO_SUSPENDにし、待機コストを抑えます。加えて、Cortex関数やAmazon Bedrock連携(External Access Integration経由)といったAI系ワークロードも、コスト特性と負荷が読みにくいため、専用ウェアハウスやサーバレスコンピュートとして本体のETL/BIから隔離しておくと、コストの可視性と安定性の両方が保てます。

06ガードレール:Resource Monitorと「先に踏み抜く」検証フロー

設計が正しくても、想定外のクエリや設定ミスは起こり得ます。その最終防波堤がResource Monitor(リソースモニター)です。リソースモニターはクレジットのクォータ(割当量)を期間単位で定義し、その消費割合(%)を閾値として、しきい値到達時のアクションを設定できます。アクションはNotify(通知、最大5件)、Suspend(実行中クエリの完了を待って停止)、Suspend Immediate(即時停止)で、NOTIFY_USERSに指定したユーザーへメール通知を送れます。アカウント全体に1つ設定して総枠を守ることも、個別のウェアハウスに割り当てて枠を分けることも可能です。ETL/BI/アドホックを分離した各ウェアハウスに月次クォータを割り当てておけば、どのワークロードが暴走してもそこで頭打ちになります。

コスト面のガードレールに加え、基盤としてはセキュリティ側の設計も同時に固めておきます。AWS上のSnowflakeであれば、S3ステージへのアクセスはIAMのストレージ統合で最小権限に絞り、通信はAWS PrivateLinkで閉域化し、暗号化にはKMSを組み合わせます。これらはコストの話ではありませんが、ウェアハウス設計と一緒にIaCで定義しておくことで、検証環境と本番環境の構成差異による事故を防げます。

現場のコツ:コスト事故は「本番で気づく」ものにしないのがEMWの流儀です。PoC・検証環境に本番相当のResource Monitorとタグ付けを先に入れ、負荷試験で自動停止・マルチクラスタ・クォータの挙動を一通り踏み抜いてから本番へ上げます。落とし穴を先に見つける設計フローそのものが、重大障害0を支えています。

07まとめ:4つの勘所を設計時に決め切る

仮想ウェアハウス設計は、後から調整もできますが、最初の切り方で大枠のコストと性能が決まります。押さえるべき勘所は4つです。第一にサイズは小さく始めてQuery Profileで上げる。第二にAUTO_SUSPEND/AUTO_RESUMEは到着間隔に合わせて調整し、片方だけ切らない。第三に同時実行のスケールアウトが必要な箇所だけマルチクラスタを使い、Maximizedの付けっぱなしを避ける。第四にETL・BI・アドホック(そしてAI系)をワークロードごとに専用ウェアハウスへ分離する。そのうえでResource Monitorを最終防波堤に置きます。いずれの落とし穴も、検証段階で先に踏み抜いておけば、本番では静かなアイドル課金も突発的なクレジット消費も未然に防げます。

参考情報(一次情報)

EMWはAWS上のSnowflakeについて、仮想ウェアハウス設計からコスト最適化・セキュリティ構成まで、検証で落とし穴を先に潰す一貫支援を提供しています。お気軽にご相談ください。

相談する
← ブログ一覧へ戻る