テーマ切替
確認問題|Professional ④ モニタリング・アラート(配点 10%)
教材 04-monitoring-alerting.md の内容に基づく確認問題です(全10問)。 まず問題を解き、下の「解答・解説」で答え合わせをしてください。
問題
Q1. 次の 4 つの監視要件に対して使うべきツールの組み合わせとして、正しいものはどれか。
- アカウント全体のコストとジョブ実行履歴を後から SQL で分析したい
- テーブルの鮮度・完全性・分布の変化を自動監視したい
- いま流れているストリームの入力/処理レートと遅延・状態を観測したい
- 条件が満たされたら担当者に通知したい
- A. 1=SQL アラート、2=システムテーブル、3=ジョブ通知、4=StreamingQueryListener
- B. 1=システムテーブル(
systemカタログ)、2=データ品質監視(異常検知+データプロファイル)、3=StreamingQueryListener / Spark UI Streaming タブ、4=Databricks SQL アラート / ジョブ通知 - C. 1=データ品質監視、2=システムテーブル、3=SQL アラート、4=Spark UI
- D. すべてシステムテーブルで対応でき、他のツールは不要である
Q2. システムテーブルの前提条件・アクセス権限・運用上の注意として、正しい説明はどれか。
- A. システムテーブルはワークスペースごとに独立しており、Unity Catalog は不要である
- B. すべてのワークスペースユーザーが既定で
systemカタログを参照でき、書き込みも可能である - C. システムテーブルはリアルタイム監視に対応しており、直近のイベントも即座に反映される
- D. アクセスには Unity Catalog 有効なワークスペースが必要で、既定でアクセスできるのはアカウント管理者かつメタストア管理者。他ユーザーには
systemカタログへのUSE CATALOG+システムスキーマへのUSE SCHEMA+SELECTを付与する。読み取り専用で、リアルタイム監視はサポートされない(データは 1 日を通して更新される)。選択性の低いクエリはSystem Table query returned too much data...で失敗するため述語で期間を絞る
Q3.(シナリオ)system.billing.usage でジョブごとのコストを集計したいが、一部のジョブで usage_metadata.job_id が設定されておらずコストを帰属できない。原因と対処として正しいものはどれか。
- A.
usage_metadata.job_idはジョブコンピュートまたはサーバーレスで実行したジョブにのみ設定される。汎用(All-Purpose)コンピュートで実行したジョブはリソース共有のため正確なコスト帰属ができないので、正確なコスト追跡には専用ジョブコンピュートかサーバーレスを使う。なおWORKFLOW_RUN(ノートブックワークフロー)のコストは親ノートブックに帰属する - B.
system.billing.usageは保持期間 30 日なので、それより古いジョブはjob_idが消えている - C.
job_idはsystem.lakeflow.jobsにしか存在しないため、billing.usage側では常に NULL になる - D. ジョブにタグを付ければ過去分も遡って
job_idが補完される
Q4. system.lakeflow.job_run_timeline を使ってジョブの失敗を分析する。列の意味として正しい説明はどれか。
- A.
result_stateはすべての行に設定されるため、フィルターなしで集計してよい - B.
run_duration_secondsなどの期間列はマルチタスクジョブでも正確に設定される - C.
result_state(SUCCEEDED/FAILED/SKIPPED/CANCELLED/TIMED_OUT/ERROR/BLOCKED/NULL)とtermination_code(SUCCESS/DRIVER_ERROR/CLUSTER_ERROR/MAX_CONCURRENT_RUNS_EXCEEDEDなど)で失敗原因を切り分ける。タイムラインは 1 行あたり最大 1 時間にスライスされ、result_state/termination_codeは実行の終了を表す最終行にのみ設定される(中間スライス行はNULL)。期間列はレガシ単一タスクジョブのみに設定され、マルチタスクは0なのでjob_task_run_timelineを使う - D.
run_typeはJOB_RUNのみで、ノートブックワークフローも同じ値で記録される
Q5. データプロファイルが作成・更新する 2 つのメトリックテーブルと、ドリフト指標について正しい説明はどれか。
- A. 作成されるのは
{table}_quality_metricsのみで、ドリフトはその中の列として表現される - B.
{output_schema}.{table_name}_profile_metrics(各列×時間ウィンドウ×スライス×グループの概要統計)と{output_schema}.{table_name}_drift_metrics(分布変化)の 2 つ。ドリフトは連続(CONSECUTIVE)=直前の時間ウィンドウと比較、ベースライン(BASELINE)=ベースラインテーブルと比較(提供時のみ)。分布検定はカテゴリ列=カイ二乗検定 / TV 距離 / L∞距離 / JS 距離、数値列=KS 検定 / Wasserstein 距離 / PSI。PSI は< 0.1有意な変化なし、< 0.2中程度、>= 0.2有意な母集団変化 - C. ドリフトメトリックテーブルは常にベースラインドリフトと連続ドリフトの両方を計算する
- D. PSI は数値列とカテゴリ列の両方に適用され、
>= 0.5で初めて有意と判断する
Q6. データプロファイルの分析タイプと時間ウィンドウの関係として、正しい説明はどれか。
- A. どの分析タイプでも時間ウィンドウは
granularityのみで決まる - B.
Snapshotはtimestamp_colを必須とし、TimeSeriesは単一時点のウィンドウになる - C.
Snapshot分析ではウィンドウは「更新時刻の単一時点」、TimeSeries/InferenceLogではgranularity(粒度)とtimestamp_colに基づく。InferenceLogではモデル ID ごとにも計算される。時系列/推論プロファイルは作成時刻から30 日を振り返るため、最初の分析ウィンドウは部分的になり得る - D. スライス(
slicing_exprs)を指定した場合、テーブル全体のメトリックは計算されなくなる
Q7. Structured Streaming のバックプレッシャー(遅延)を判定するためのメトリックとして、正しい組み合わせはどれか。
- A.
numInputRowsがbatchIdより大きい状態が続けばバックプレッシャーである - B.
durationMs.triggerExecutionがバックログの唯一の指標である - C. Kafka では
numFilesOutstanding、Delta / Auto Loader ではmaxOffsetsBehindLatestを見る - D.
inputRowsPerSecond(入力レート)>processedRowsPerSecond(処理レート)が続くと未処理データが溜まる。バックログは Delta / Auto Loader =sources.metrics.numBytesOutstanding/numFilesOutstanding(Auto Loader は通知モード時にapproximateQueueSizeも)、Kafka =avgOffsetsBehindLatest/maxOffsetsBehindLatest/minOffsetsBehindLatest/estimatedTotalBytesBehindLatest、Kinesis =*MsBehindLatestで観測する
Q8. StreamingQueryListener と監視可能メトリック(df.observe)について、正しい説明はどれか。
- A. 実装するコールバックは
onQueryStarted/onQueryProgress/onQueryIdle/onQueryTerminated(DBR 11.3 LTS 以降、Python / Scala)。onQueryProgressはストリーミングバッチの最後にのみ配信される。リスナーの処理遅延はクエリの処理速度に大きく影響し得るため処理ロジックを制限し、Kafka のような高速応答システムへの書き込みが推奨される。df.observe("name", 集計)の結果はStreamingQueryProgress.observedMetricsから取得し、Databricks はcontinuousトリガーモードをサポートしない - B.
onQueryProgressはマイクロバッチの途中でも逐次配信されるため、リアルタイムに近い粒度で観測できる - C.
df.observeの結果はバッチモードでもストリーミングモードでもQueryExecutionListenerから取得する - D.
StreamingQueryListenerはどのアクセスモード・DBR バージョンでも制限なく UC 管理オブジェクトと対話できる
Q9. Databricks SQL アラート(新エディター)について、正しい説明はどれか。
- A. 既存の保存済み SQL クエリを再利用でき、状態は
OK/TRIGGERED/UNKNOWN/ERRORの 4 つである - B. パラメーターを含むクエリをサポートしており、実行時に値を渡せる
- C. 各アラートは自身のクエリ定義を所有し既存の保存済みクエリを再利用できない。状態は
UNKNOWNを廃止してOK/TRIGGERED/ERRORに解決される。パラメーターを含むクエリはサポートされない。条件は「値(最初の行 or 集計 SUM / AVERAGE 等)+列+論理演算子+しきい値(既定は静的な値)」で構成する。アラート実行は他のジョブ種と同じワークスペースのアクティブ実行クォータ(既定 250 同時実行)を共有し、全スロット使用中はその実行がスキップされるため、スケジュールをずらすのが対策 - D. アラートは専用の実行枠を持つため、ジョブやパイプラインの同時実行数に影響されない
Q10. Lakeflow ジョブの通知について、正しい説明はどれか。
- A. 失敗したタスクが再試行されるたびにジョブレベル通知が送られるため、タスク通知は不要である
- B. 通知イベントは「開始 / 正常完了 / 失敗 / 期間がしきい値超過 / ストリーミングバックログメトリックがしきい値超過」。失敗タスクが再試行されてもジョブレベル通知は送られないので、失敗タスクごとに通知したいならタスク通知を使う。「失敗を伴う成功(Success with failures)」で完了したジョブは成功扱い。期間超過通知には予想期間(タイムアウト)の設定が必要。ストリーミングバックログ通知は10 分間の平均がしきい値を超えると送信され、送信後 30 分待って次を判断する。ジョブ内で
awaitTermination()を使わない - C. 「失敗を伴う成功」で完了したジョブは失敗扱いになるため、失敗通知を選べばよい
- D. ストリーミングバックログ通知は 1 分間の瞬間値で判定され、しきい値超過中は 1 分ごとに通知が送られる
解答・解説
Q1. 正解: B 監視のレイヤーは役割ごとに分かれている。①アカウント全体のコスト・監査・ジョブ/パイプライン履歴はシステムテーブル(system カタログ、SQL でクエリ/ダッシュボード)。②テーブルのデータ品質(鮮度・完全性・統計・ドリフト)はデータ品質監視(異常検知+データプロファイル、旧 Lakehouse Monitoring)。③Structured Streaming クエリの健全性(レート・遅延・状態)は StreamingQueryListener / Spark UI Streaming タブ。④条件に基づく能動的な検知と通知は Databricks SQL アラート / ジョブ通知。「プル型(履歴分析)/ストリーミング型(リアルタイム観測)/プッシュ型(能動通知)」の 3 視点で整理すると覚えやすい。
Q2. 正解: D システムテーブルは system カタログにあるアカウント運用データの Databricks ホスト型分析ストアで、Unity Catalog 有効なワークスペースが必要(A が誤り)。既定でアクセスできるのはアカウント管理者かつメタストア管理者で、他ユーザーには USE CATALOG+USE SCHEMA+SELECT を付与する。読み取り専用で変更不可(B が誤り)。リアルタイム監視はサポートされない(データは 1 日を通して更新され直近イベントが未反映のことがある)ため C も誤り。他の注意点として、既存テーブルに新しい列がいつでも追加され得る(別テーブルへ書き出すならスキーマ進化を有効化)、選択性の低いクエリは失敗する、ストリーミング利用時は skipChangeCommits=true を設定する、などがある。
Q3. 正解: Asystem.billing.usage の usage_metadata.job_id は、ジョブコンピュートまたはサーバーレスで実行したジョブにのみ設定される。汎用(All-Purpose)コンピュートで実行したジョブはリソース共有のため正確なコスト帰属ができないので、正確なコスト追跡には専用ジョブコンピュートまたはサーバーレスの使用が推奨される(コスト最適化の観点でも汎用でジョブを流さないのが原則)。WORKFLOW_RUN(ノートブックワークフロー)のコストは親ノートブックに帰属する。B は billing.usage の無料保持が 365 日である点、D はタグが過去に遡って適用されない点で誤り。
Q4. 正解: Cjob_run_timeline の period_start_time〜period_end_time は 1 行あたり最大 1 時間で、1 時間超の実行は複数行に分割され、result_state / termination_code は最終行にのみ設定される(中間スライス行は NULL)。したがって集計時は result_state IS NOT NULL で中間行を除外する(A が誤り)。期間列(run_duration_seconds 等)はレガシ単一タスクジョブのみに設定され、マルチタスク/非レガシは 0 になるため、マルチタスクのコスト・所要時間分析には job_task_run_timeline を使う(B が誤り)。run_type は JOB_RUN / SUBMIT_RUN / WORKFLOW_RUN の 3 種で、WORKFLOW_RUN は job_run_timeline にのみ記録され jobs / job_tasks には現れない(D が誤り)。
Q5. 正解: B プロファイルを実行すると 2 つのメトリックテーブルが作成・更新される。_profile_metrics は各列と時間ウィンドウ・スライス・グループ化列の各組み合わせの概要統計(count, num_nulls, quantiles(1000 分位点の配列、中央値は quantiles[500]), distinct_count(approx_count_distinct のため概数), frequent_items 等)。_drift_metrics はメトリック分布の変化を追跡し、CONSECUTIVE(直前の時間ウィンドウと比較、集計後に連続ウィンドウがある場合のみ)と BASELINE(ベースラインテーブル提供時のみ)を計算する(C が誤り)。分布検定はカテゴリ列=カイ二乗 / TV 距離 / L∞距離 / JS 距離、数値列=KS 検定 / Wasserstein 距離 / PSI。PSI の解釈は < 0.1 有意な変化なし、< 0.2 中程度、>= 0.2 有意な母集団変化(D が誤り)。
Q6. 正解: C メトリックはウィンドウ(時間間隔)ごとに計算され、Snapshot 分析では「更新時刻の単一時点」、TimeSeries / InferenceLog では granularity と timestamp_col に基づく(A・B が誤り)。InferenceLog ではモデル ID ごとにも計算される。時系列/推論プロファイルは作成時刻から 30 日を振り返るため、この境界により最初の分析ウィンドウが部分的になり得る(最初のウィンドウのみに影響)。メトリックは常にテーブル全体に対して計算され、加えて slicing_exprs を指定するとスライスごとにも計算される(テーブル全体は slice_key = NULL, slice_value = NULL)ので D も誤り。
Q7. 正解: D入力レート(inputRowsPerSecond)> 処理レート(processedRowsPerSecond) が続くと未処理データ(バックログ)が溜まる=バックプレッシャー。バックログメトリックはソースごとに異なり、Delta / Auto Loader は sources.metrics.numBytesOutstanding(未処理ファイルの合計サイズ)と numFilesOutstanding(未処理ファイル数)、Auto Loader は通知モード時に approximateQueueSize も持つ。Kafka は avgOffsetsBehindLatest / maxOffsetsBehindLatest / minOffsetsBehindLatest / estimatedTotalBytesBehindLatest。Kinesis は avgMsBehindLatest などの *MsBehindLatest。C はソースとメトリックの対応が逆。
Q8. 正解: AStreamingQueryListener は DBR 11.3 LTS 以降で Python / Scala 対応、コールバックは onQueryStarted(DataStreamWriter.start() と同期、ブロックしないこと)/ onQueryProgress(ストリーミングバッチの最後にのみ配信、B が誤り)/ onQueryIdle(ソースにデータがなく新データ待ちのとき)/ onQueryTerminated(エラー有無問わず停止時)。リスナーの処理遅延はクエリの処理速度に大きく影響し得るため、処理ロジックを制限し Kafka のような高速応答システムへ書き込むのが推奨。df.observe の結果はモードで取得先が異なり、バッチ=QueryExecutionListener、ストリーミング/マイクロバッチ=StreamingQueryListener(StreamingQueryProgress.observedMetrics)(C が誤り)。Databricks は continuous トリガーモードをサポートしない(マイクロバッチのみ)。D も誤りで、UC 管理オブジェクトと対話するには DBR 15.1 以降(資格情報使用)または専用アクセスモードが必要、標準アクセスモードの Scala は DBR 16.1 以降が必要。
Q9. 正解: C 新エディターのアラートはレガシーアラートと違い、各アラートが自身のクエリ定義を所有し既存の保存済みクエリを再利用できない。状態は UNKNOWN を廃止して OK / TRIGGERED / ERROR に解決される(A が誤り)。条件は「チェックする値(クエリ結果の列の最初の値、または 1 列全行への集計 SUM / AVERAGE 等)+列+論理演算子+しきい値(既定は静的な値)」で構成し、「テスト条件」でプレビューできる。重要な制約としてパラメーターを含むクエリをサポートしない(B が誤り)。またアラート実行はノートブックジョブ・パイプラインなど他のジョブ種と同じワークスペースのアクティブ実行クォータ(既定 250 同時実行)を共有し、全スロット使用中に発生したスケジュールアラートはスキップされ評価されない。対策はスケジュールをずらすこと(01:30, 01:32, 01:34 …)で、恒常的に上限に達するならクォータ増加をサポートに依頼する(D が誤り)。
Q10. 正解: B ジョブ通知のイベントは「開始 / 正常完了 / 失敗 / 期間がしきい値超過 / ストリーミングバックログメトリックがしきい値超過」で、通知先は 1 つ以上のメールアドレスまたはサードパーティ宛先(Slack / Microsoft Teams / PagerDuty / Webhook)、ジョブ/タスクごと・通知イベント種別ごとに最大 3 つのシステム宛先。失敗タスクが再試行されてもジョブレベル通知は送られないため、失敗タスクごとに通知したいならタスク通知を使う(A が誤り)。「失敗を伴う成功」で完了したジョブは成功扱いなので、通知を受けたいなら「成功」を選ぶ(C が誤り)。期間超過通知を受けるには予想期間(タイムアウト)の設定が必要。ストリーミングバックログ通知は10 分間の平均バックログがしきい値を超えると送信され、過剰メッセージ防止のため送信後 30 分待って次を判断する(D が誤り)。またジョブサービスがアクティブなストリーミングクエリを追跡できる必要があるため、ジョブ内で awaitTermination() を使わない。