TL;DR
Databricksのコスト最適化は、5つの習慣に集約されます。コストの実際の発生源を把握すること(DBUレートと、それとは別に発生するクラウドインフラの請求)、自動終了とタイムアウトでアイドル状態のコンピュートをなくすこと、サーバーレスをデフォルトとしつつ最もコストの高いワークロードにはクラシックコンピュートを使い分けてライトサイジングすること、実行頻度と増分処理の観点からワークフローを見直すこと、そしてストレージとガバナンスの設定を固めて、得られた成果が時間とともに失われないようにすることです。ウェビナーで共有された実数値では、監視されていないGPUクラスターが月額2万ドルの請求に4,000ドルを上乗せしてから発覚し、あるジョブの実行頻度を1日472回から1時間に1回へ減らしたことで、そのコストの95%、年間約19,000ドルを削減できました。
なぜDatabricksのコストは制御しにくいのか
Databricksはデータチームに並外れた自由度を与えます。同じパイプラインを、インタラクティブクラスターとして、スケジュールされたジョブとして、あるいはサーバーレスジョブとして、クラシックコンピュートでもサーバーレスでも実行でき、その間には多数のノードタイプやスケーリング構成が存在します。この柔軟性こそが、コスト管理を難しくしている要因です。選択肢が多いほど設定ミスの可能性も増え、しかもDatabricksの請求書を見ても、ミスが起きたことが必ずしも明らかになるとは限りません。
これが、SELECTの共同創業者であるIan Whitestoneと、DatabricksコンサルタントのOlivier Soucyが先日開催したウェビナーの出発点でした。Soucyは長年にわたりデータプラットフォームをゼロから構築してきた人物で、暗号資産取引所のデータ責任者としてDatabricks環境を一から構築した経験もあります。現在はDatabricksのコストとパフォーマンスに特化した自身のコンサルティング事業を営んでおり、このセッションでは、Databricksの支出を管理下に置くための5つの具体的な戦略を、いずれもクライアント案件での実数値を交えて解説しました。
以下、その内容を振り返ります。
まずはコストの行き先を正確に把握する
何かを最適化する前に、自分が何に対して支払っているのかを知る必要があります。そしてDatabricksでは、これが必要以上に難しくなっています。コストは2つの別々の場所から発生します。Databricks自体が課金するDatabricksユニット(DBU)レートと、Databricksがプロビジョニングするインスタンスに対してAWS、Azure、GCPが課金する基盤側のクラウドコンピュートです。
DBUレートだけを見ると誤解を招きかねません。Soucyは、同じETLパイプラインを3通りの方法で実行した場合の価格を紹介しました。インタラクティブクラスターとして実行するとDBUあたり55セント、クラシックコンピュート上のジョブとして実行すると30セント、サーバーレスのジョブとして実行すると45セントです。DBU単価だけを見ると、サーバーレスが高い選択肢に見えます。しかしクラシックコンピュートには、サーバーレスには発生しないクラウドインフラの請求が別途かかるため、両方のコストを合算すると全体像はまったく違って見えることが少なくありません。
ほとんどのチームは、この合算を行いません。WhitestoneがDBUコストとクラウドインフラコストをジョブ単位で一緒に追跡している顧客はいるかと尋ねたとき、Soucyは率直に「通常はしていない」と答えました。それぞれの側を別のチームが管理しているためです。Databricksチームはシステムテーブルとワークフローを監視し、クラウドチームはAWSやAzureの請求書を見て、Databricksを1行の項目として扱います。適切なタグを付けて2つのデータソースを結合するのはそれなりの手間がかかるため、重要だとわかっていても多くの組織が手を付けずにいます。
Databricksは利用状況と価格データを含むシステムテーブルを公開しており、DBU支出についてはかなり正確なコストモデルを構築できます。クラシック(非サーバーレス)コンピュートについては、基盤となるクラウドインフラコストはDBUコストとほぼ同額と見なすのがSoucyの経験則です。つまりDBUの請求が5万ドルなら、クラウドコンピュートを加えると実際には10万ドル近くになることが多いのです。これは大まかな見積もりで、GPUワークロードでは大きく変動しますが、より精緻なモデルがまだない場合の出発点としては妥当です。Databricksの料金体系の詳しい仕組みについては、SELECTが最も重要な3つのコントロールを解説した記事をご覧ください。
何よりも先に無駄をなくす
アイドル状態のコンピュートは、Soucyの言葉を借りれば、チームが犯しうる最も高くつくミスです。稼働している間、何の価値も生まないリソースに対して支払い続けることになるからです。彼は自身のクライアント案件から2つの例を共有しました。1つは、新人のインターンが自動終了もガードレールもないままGPUクラスターを立ち上げたケースです。このクラスターは数週間稼働し続け、月額2万ドルの請求に約4,000ドルを上乗せしてからようやく発覚しました。もう1つは、QA環境では約20分で問題なく完了していたジョブが、本番環境で異なるデータに当たり、誰かが気づくまでに47時間も実行され続けたケースです。
対策はシンプルで、他の施策とは関係なく、まず実施する価値があります。
- すべてのクラスターとウェアハウスに自動終了を設定する。 Soucyは妥当なデフォルト値として、クラスターはアイドル約30分、ウェアハウスは10分を挙げましたが、正確な数値よりも、そもそも設定があること自体が重要です。
- オートスケーリングを有効にし、コンピュートが常時フルプロビジョニングされたままになるのではなく、実際の需要に応じて増減するようにする。
- ジョブとクエリのタイムアウトを設定する。 DatabricksのSQLステートメントのデフォルトタイムアウトは2日間で、これは長すぎるというのが両登壇者の一致した見解でした。Whitestoneは率直に、1日以上走り続けているクエリは、おそらくもう動いているべきではなく、このデフォルト値はアカウント全体で引き下げる価値があると述べています。
- クラスターポリシーで強制する。 個々人が自動終了を覚えていることに頼るのではなく、クラスターポリシーを使えばアカウントレベルで必須にできます。
ジョブに合わせてコンピュートをライトサイジングする
無駄をなくせたら、次によくあるミスは過剰プロビジョニング、つまりワークロードに必要以上のコンピュートを割り当てることです。Soucyのデフォルトの推奨は、本人も多少物議を醸すと認めつつ、特別な理由がない限りサーバーレスをデフォルトにすることです。
彼はこれを、クライアントの1時間ごとのETLパイプラインの例で裏付けました。クラシックコンピュートでは、このジョブは1日あたり約44 DBUをDBUあたり30セントで消費し(DBUコストで1日約13ドル)、さらに1日10ドルのクラウドインフラ費用が加わって、合計で1日23ドル近くになっていました。サーバーレスに移行すると、同じジョブはより高いDBU単価で38 DBUを消費しましたが、総コストはほぼ同等、このケースではむしろわずかに安くなりました。主な理由は、クラシックコンピュートが毎回の実行で支払っている2〜4分のクラスター起動時間が、サーバーレスでは不要になるためです。起動時間がなくなったことで、ジョブの総実行時間も20分から12分に短縮されました。
Soucyの実践的なアドバイスはこうです。Databricksを使い始めたばかり、あるいはまだワークフローのチューニングをしていないなら、まずすべてをサーバーレスにし、その上で請求の大半を占める上位5〜10個のワークロードを特定して、それらだけをクラシックコンピュートに戻すことを検討する。クラシックコンピュートのほうが、コストとパフォーマンスのバランスを調整する手段が多いためです。それ以外のワークロードは、通常チューニングに時間をかける価値がありません。分岐点になりやすいのはワークロードの実行時間です。数時間単位で実行され続けるジョブは、ノードタイプ、オートスケーリング、ワーカー数を直接細かく調整できるクラシックコンピュートの恩恵を受けやすい傾向があります。
クラシックコンピュートでは、利用可能な最小のインスタンスサイズから始め、Spark UIのCPU使用率やノード使用率などのメトリクスを判断材料に、実際にボトルネックに当たったときだけスケールアップすることをSoucyは推奨しています。最初から大きすぎるサイズで始めると、彼の言う「サイレントな請求」が発生しがちです。エラーも障害もなく、ただ必要以上に高いコストが続くだけ、という状態です。また、コンピュートのタイプをワークロードに合わせることも重要です。SQLのみの処理はSQL Warehouseに、一般的なジョブのロジックはジョブコンピュートに置き、インタラクティブ(汎用)クラスターは本当にインタラクティブな作業のためだけに使うべきです。Whitestoneは、これがSELECTが目にする最も一般的な落とし穴の1つだと指摘しました。スケジュールされたジョブを専用のジョブクラスターではなくインタラクティブクラスターで実行すると、そのジョブのDatabricksコストが何のメリットもなくほぼ2倍になることがあります。
ワークフローそのものを見直す
コンピュートのサイジングにとどまらず、パイプラインの構築方法に関するいくつかの変更は、利用できる最適化の中でも特に効果の大きいものとして際立っていました。
実行頻度は、多くのチームが思う以上に重要です。 日次更新を基準にすると、1時間ごとの実行ではコストが約5倍、ほぼリアルタイムの更新では約60倍になります。Soucyのアドバイスは、ビジネス側のステークホルダーからのリアルタイムや準リアルタイムの要件に対して一度立ち止まって問い直すことです。「リアルタイム」のダッシュボードを求める要望の多くは、実際には継続的なストリームではなく、レポートが特定時点の状態を反映していればよいという意味だからです。
テーブルを複製する代わりにビューを使う。 単純なフィルタリングやカラム選択であれば、新しい物理テーブルではなくビューを作成することで、データのコピーと、そのコピーを維持し続けるコストを回避できます。クエリを実行する側にとって実質的なデメリットはありません。
すべてを再処理するのではなく、増分処理する。 DatabricksのAuto Loaderはクラウドストレージ上の新規・変更ファイルを自動的に識別でき、構造化ストリーミングと組み合わせることで、パイプラインは毎回データセット全体ではなく変更分だけを処理できます。Soucyはこれを、セットアップはやや複雑だが、大量データを扱うワークロードには不可欠だと評しました。
コストの高いクエリをプロファイリングして書き直す。 Databricksのクエリプロファイルビューでは、見落としがちなシャッフルやスピルを含め、Sparkが変換を実際にどう実行したかを確認できます。Soucyは、このプロファイル情報を変換コードとともにAIコーディングアシスタントに渡すことで、自身の業務でも実際に使える書き直し案が得られており、かつては深いSparkの専門知識を要したタスクが格段に取り組みやすくなったと述べています。
ストレージも見逃さず、成果を定着させる
ストレージ面でのSoucyのアドバイスは、パーティショニングやZオーダリングを手動でチューニングするのは避け、予測的最適化に対応したUnity Catalogのマネージドテーブルを利用することです。予測的最適化は、vacuum、optimize、analyzeの各操作をスケジュールに沿って自動実行し、不要になったファイルの削除、小さなファイルの大きなファイルへの統合、メタデータの更新を行うため、クエリは読む必要のないファイルをスキップできます。実行自体にコストはかかりますが、差し引きでは手動メンテナンスよりも請求額が下がるのが通常です。手動のZオーダリングをほぼ置き換えたリキッドクラスタリングにも同様の利点があります。クラスタリングに使うカラムを変更する必要が生じても、既存データの書き換えが不要です。
こうした取り組みも、ガバナンスなしには長続きしません。Soucyの推奨は、TerraformやDatabricks Asset Bundlesなどのツールを使ってすべてをコードとして管理し、CI/CD経由でデプロイすることです。これにより、設定が環境間で一貫し、いつの間にかずれていくことを防げます。ここで中心となるのがクラスターポリシーです。大多数のユーザーには妥当なデフォルトを設定し、自動終了とノードタイプの制限を強制しつつ、本当に高い柔軟性が必要なパワーユーザーには申請の余地を残します。クラスタープールも、クラウドプロバイダー側で一定数のインスタンスをウォーム状態に保ち、ジョブがクラスター起動を待たずに済むため有効ですが、Databricksからの課金はなくても、そのアイドル容量に対するクラウドプロバイダーへの支払いは発生します。
Soucyは見落とされがちなコストのカテゴリーにも言及しました。アプリ、モデルサービングエンドポイント、ベクトル検索、品質モニターといったDatabricksの新しい機能です。彼自身、大規模テーブルの品質モニターを誤って設定し、気づくまでにそのテーブルの日次請求額が50%増加した経験を語りました。Whitestoneは、DatabricksがGenieのようにこれまで無料だったツールへの課金を開始した動きを挙げ、AI関連機能はDatabricksの請求全般において今後ますます大きな項目になるだろうと付け加えました。両者の結論は同じです。コストアラートは、新しい機能を有効にした後ではなく、有効にする前に設定すべきです。
すべてに共通するパターン
5つの戦略すべてに、同じパターンが現れています。Databricksがコスト面で派手に失敗を知らせてくることは、ほとんどありません。アイドル状態のクラスターは静かに動き続け、過剰にスケジュールされたジョブも静かに実行され、サイズの大きすぎるコンピュートも静かに稼働し、新機能は請求書が届くまで誰もコストを確認しないまま有効化されます。ここで紹介した対策に特別なものは1つもありません。自動終了、適切なタイムアウト、ワークロードに合ったコンピュートタイプの選択、そして設定のコード化だけで、ほとんどのチームは回避可能な支出の大半に対処できます。
これを手作業ではなく自動で処理したいチームのために、SELECT for Databricksはこうした無駄を直接可視化します。自動終了の設定漏れ、過剰にスケジュールされたジョブ(セッション中に共有された実例では、1日472回実行されていたジョブを1時間に1回に減らしたことで、コストの95%、年間約19,000ドルを削減)、支出の中で突出した割合を占めるウェアハウスやジョブを、個々のクエリレベルまで特定します。詳しくはselect.devをご覧ください。
FAQ
Databricksの不要なコストの最大の要因は何ですか? アイドル状態のコンピュートです。自動終了なしで放置されたクラスターやウェアハウス、タイムアウトなしでハングするジョブは、何の価値も生まないまま課金を発生させます。他の施策より先にこれを修正するのが、最も早く効果が出る傾向にあります。
Databricksではサーバーレスとクラシックコンピュートのどちらをデフォルトにすべきですか? ほとんどのワークロードでは、サーバーレスが妥当なデフォルトです。クラスター起動時間がなくなり、手動チューニングなしでも多くのチームが適切なコスト水準に収まります。例外は支出額で上位5〜10個の最も高コストなワークロードで、これらはノードタイプ、オートスケーリング、ワーカー数をより細かく制御できるクラシックコンピュートの恩恵を受けやすいのが通常です。
DBUコストとクラウドインフラコストの違いは何ですか? DBU(Databricksユニット)レートはDatabricks自体がコンピュートに対して課金するもので、コンピュートのタイプによって異なります。クラシックコンピュートでは、基盤となるインスタンスに対してAWS、Azure、GCPからのクラウドインフラ請求が別途発生しますが、サーバーレスコンピュートでは発生しません。大まかな経験則として、クラシックコンピュートではクラウドインフラコストはDBUコストとほぼ同額と見なしてください。
自動終了で実際にどれくらい節約できますか? ワークロードによって異なりますが、設定しなかった場合の損失は大きくなりえます。実例では、自動終了のない誤設定のGPUクラスターが、誰かが気づくまでにひと月の請求に約4,000ドルを上乗せしていました。
ジョブの実行頻度はDatabricksのコストにどう影響しますか? 大きく影響します。日次更新を基準にすると、同じジョブを1時間ごとに実行するとコストは約5倍、ほぼリアルタイムの更新では約60倍になります。そのワークロードが本当にその頻度で実行される必要があるのかを問い直すことが、多くの場合、単体で最も効果の大きいコスト対策になります。
DatabricksはGenieのようなAI機能に課金しますか? Databricksは、Genieを含む従来無料だったツールへの課金を開始しており、AI関連機能はDatabricksの請求において今後ますます大きな項目になると見込まれています。思わぬ請求を防ぐ最善の策は、新機能を有効にする前にコストアラートを設定しておくことです。