Databricks Certified Data Engineer Associate 教科書
第6章 トラブルシューティング・監視・最適化(Troubleshooting, Monitoring, and Optimization, 10%)
🎯 この節の学習目標
この節で扱うのは、6-2 のような「実行中の性能問題」ではなく、そもそも実行環境が立ち上がらない・壊れているタイプの問題です。ジョブのステータスが Pending のまま進まない、クラスタが「起動失敗(terminated)」になる、という症状はここに分類されます。診断の起点はクラスタのイベントログ(Event log)で、より詳細な情報が必要ならドライバーログを確認します。
| 原因 | 症状・ログでの現れ方 | 対策 |
|---|---|---|
| クラウド側のインスタンス不足 (capacity 不足) | イベントログに「要求したインスタンスタイプを確保できない」旨のクラウドプロバイダ由来のエラー。特定リージョン・特定タイプで発生 | 別のインスタンスタイプ・アベイラビリティゾーンを試す。スポットからオンデマンドへ切り替える。インスタンスプールで事前確保する |
| クォータ(上限)超過 | イベントログにクラウドアカウントの vCPU 数などのクォータ超過エラー。大きなクラスタや同時起動が増えた時期に発生 | クラウドプロバイダにクォータの引き上げを申請する。不要クラスタの自動終了(auto termination)を徹底する |
| 権限の不足 (インスタンスプロファイル等) | 起動時の認可エラー。指定したインスタンスプロファイル/サービス資格情報でインスタンス作成やストレージアクセスが拒否される | クラウド側の IAM 設定(ロール・ポリシー)を確認・修正する。ワークスペースに登録された資格情報の設定を見直す |
| init script の失敗 | インスタンス自体は確保できたのに、初期化スクリプトが非ゼロ終了して起動が中断。イベントログに init script failure、詳細はinit script のログ・ドライバーログ | スクリプトのエラー(参照先URLの死活、依存パッケージ、実行権限)を修正する。まず init script なしで起動して切り分ける |
📝 試験のポイント
「クラスタが起動しない。まずどこを確認するか」→ クラスタのイベントログが第一の答えです。イベントログにはインスタンス確保・起動・終了・リサイズなどのライフサイクルイベントと失敗理由が時系列で残ります。「コードのエラー→ドライバーログ/ノートブック出力」「起動の失敗→イベントログ」という対応付けを覚えておきましょう。
Databricks のクラスタでは、Python ライブラリが次の3つの層で存在し、同じライブラリの異なるバージョンが層の間で衝突することがあります。
| 層 | インストール方法 | 適用範囲 |
|---|---|---|
| Databricks Runtime 同梱 | ランタイムにあらかじめ含まれる(pandas、pyarrow など) | クラスタ全体(基盤) |
| クラスタライブラリ | クラスタ設定画面や API でインストール | そのクラスタで動くすべてのノートブック・ジョブ |
| notebook-scoped ライブラリ | ノートブック内で %pip install | そのノートブックのセッションのみ。他のノートブックには影響しない |
症状:ImportError / AttributeError(存在しないはずの属性)、「昨日まで動いていたノートブックが今日から壊れた」、同じクラスタの別ノートブックだけ動かない、など。
確認箇所:ノートブックで実際に読み込まれているバージョンを確認します(pip list や ライブラリ.__version__)。クラスタ設定のライブラリ一覧、ノートブック内の %pip 行、使用中の Runtime バージョンの同梱ライブラリ一覧を突き合わせます。
原因:典型パターンは次の3つです。
%pip がそのセッションでクラスタライブラリを上書きし、想定と違うバージョンで動く(逆に、上書きされないと思い込んで古い方が動く)対策:
%pip install ライブラリ==X.Y.Z のように明示し、「latest 任せ」で日によって挙動が変わる事態を防ぎます%pip(notebook-scoped)で入れるのが原則です💡 具体例:「別のチームがクラスタライブラリを更新したら壊れた」
共有の汎用クラスタで、あるチームが自分たちのノートブックのためにクラスタライブラリとして機械学習ライブラリの新バージョンをインストールしたところ、同じクラスタを使う別チームの既存ノートブックが AttributeError で動かなくなりました。クラスタライブラリはそのクラスタの全ユーザーに影響するためです。恒久対策は、チーム固有の要求バージョンを notebook-scoped(%pip install ライブラリ==X.Y.Z)へ移すか、ジョブごとに専用のジョブクラスタを使って環境を分離することです。
OOM(Out Of Memory)の診断で最初にすべきことは、「どこでメモリが尽きたのか」の切り分けです。Spark ではドライバーとエグゼキュータの役割が異なるため、原因も対策も別物になります。
症状:ノートブック全体が応答しなくなる、カーネルの再起動、「Driver is up but unresponsive」系のメッセージ。クラスタ上のすべての処理が巻き添えになります。
確認箇所:ドライバーログにヒープ不足・GC 多発の記録。直前に実行したコードに collect()・大きな DataFrame の toPandas()・巨大な結果の display がないか。
原因:分散処理の結果をドライバー1台のメモリに集約する操作。collect() と大規模データの toPandas() が2大要因です。
対策:集約系操作を避け、結果はテーブルやファイルへ分散のまま書き出す。確認用には limit() や display の件数制限を使う。pandas 的な処理が必要なら pandas API on Spark 等の分散実装を検討する。
症状:特定のタスク・ステージが失敗と再試行を繰り返した末にジョブが失敗する。ノートブック自体は応答している。
確認箇所:失敗したステージを Spark UI で開き、失敗タスクのメトリクスを確認。特定タスクだけ入力・shuffle read が突出していればスキュー、全タスク一様に大きければパーティション過大。エグゼキュータのログにヒープ不足の記録。
原因:データスキューによる特定タスクへの集中、パーティションサイズの過大、メモリ設定に対して重すぎる処理(巨大な結合・爆発的な explode など)。
対策:スキューなら 6-2 の対策(AQE の skew join 処理確認・ブロードキャスト結合・salting)。パーティション過大ならパーティション数を増やす(spark.sql.shuffle.partitions・repartition)。それでも不足するならメモリ最適化インスタンスへの変更を検討します。
| 症状 | ログ・UIで見る場所 | 原因の典型 | 対策 |
|---|---|---|---|
| クラスタが起動しない/Pending が長い | クラスタのイベントログ(詳細はドライバーログ・init script ログ) | インスタンス不足・クォータ・権限・init script 失敗 | タイプ/AZ 変更、クォータ申請、IAM 修正、スクリプト修正 |
| ImportError/AttributeError、昨日まで動いたコードが壊れた | ノートブックの pip list、クラスタのライブラリ設定、Runtime 同梱一覧 | ライブラリのバージョン競合 | Runtime 更新、バージョン固定、notebook-scoped/ジョブ単位で分離 |
| ノートブック全体が無応答・ドライバー再起動 | ドライバーログ、直前のコード | ドライバー OOM(collect / 大きな toPandas) | collect 回避、limit、分散のまま書き出す |
| 特定ステージのタスクが失敗・再試行を繰り返す | Spark UI の失敗ステージ、エグゼキュータログ | エグゼキュータ OOM(スキュー・パーティション過大) | スキュー対策、パーティション数増、メモリ最適化インスタンス |
症状への対処と同じくらい重要なのが、そもそもワークロードに合ったコンピュートを選ぶことです(2章の内容の復習です)。合わないコンピュートは、遅延・OOM・コスト超過という形で「症状」を生み続けます。
✅ この節のまとめ
collect()・大きな toPandas() などの集約操作が原因で、ノートブック全体が無応答になる。エグゼキュータ OOM はスキューやパーティション過大が原因で、特定タスクの失敗・再試行として現れる。問1. ジョブクラスタが起動に失敗し、ジョブが実行できない。失敗の理由を特定するために最初に確認すべき場所はどれか。
正解:B
イベントログにはクラスタのライフサイクル(インスタンス確保・起動・終了)と失敗理由が時系列で記録されており、インスタンス不足・クォータ超過・権限エラー・init script 失敗のいずれかをここで切り分けられます。Aの Spark UI はクラスタが起動して処理が動いた後の診断手段であり、起動前の失敗には使えません。Cは性能トレンドの確認用です(6-1)。Dはデータアクセスの監査が目的で、クラスタ起動の失敗理由は記録されません。
問2. 共有の汎用クラスタで、あるノートブックだけが特定バージョンのライブラリを必要としている。他のユーザーのノートブックに影響を与えずにこれを満たす方法として最も適切なのはどれか。
正解:B
notebook-scoped ライブラリ(%pip)は、そのノートブックのセッションにのみ適用され、同じクラスタの他ノートブックへ影響しません。バージョン固定(==X.Y.Z)も再現性の観点から適切です。AとDはどちらもクラスタ全体に適用されるため、他ユーザーの環境を変えてしまい競合の火種になります。Cはランタイムの変更でクラスタ全体の同梱ライブラリがすべて変わるうえ、古いランタイムへ下げる合理性もありません。
問3. 大きなテーブルを DataFrame に読み込んで toPandas() を呼んだところ、ノートブック全体が応答しなくなり、しばらくしてドライバーが再起動した。原因と対策として最も適切なのはどれか。
正解:B
toPandas() は分散していたデータ全件をドライバー1台のメモリ上の pandas DataFrame に変換する操作で、大きなテーブルではドライバー OOM の代表的な原因です。「ノートブック全体が無応答→ドライバー再起動」という症状もドライバー側の障害を示しています。Aはワーカーを増やしてもドライバーに集まるデータ量は変わらないため無効です。Cは再起動しても同じコードで再発します。Dはバージョン違いのエラー(ImportError 等)として現れる問題で、この症状とは異なります。
問4. 数百人のアナリストが日中、BIダッシュボードやアドホックなSQLクエリを断続的に実行する。同時実行が多く、応答の速さが求められる。最も適切なコンピュートはどれか。
正解:C
多数ユーザーの同時アドホック SQL という要件には、SQL に最適化され、即時起動と自動スケーリングで高い同時実行性を提供するサーバーレス SQL ウェアハウスが適合します。Aは同時実行の増減に追従しにくく、ピーク時は詰まり、閑散時は無駄なコストが出ます。Bのジョブクラスタは自動化されたパイプライン向けで、対話的なアドホック分析には不向きです(人数分のクラスタはコストも管理も非現実的です)。Dのシングルノードは軽量な開発・実験用で、数百人の同時利用を支えられません。