プロンプトとコンテキスト
共有コンピュートクラスタでは、インタラクティブジョブ、バッチ処理、プリエンプティブルなトレーニングが実行されます。テナントは一時的なバーストが可能ですが、特定のテナントが無制限にCPU、メモリ、GPUを占有することはできません。高優先度の処理は待機時間を短縮する必要があり、同時に低優先度のテナントがスタベーション(飢餓状態)に陥ってはなりません。
キュー、リソース台帳、スケジューリングポリシー、プリエンプション、障害復旧を設計してください。KubernetesはPriorityClass、ResourceQuota、プリエンプションを分離しています。同様に、IETFのキュー管理ガイダンスでも、公平性と輻輳制御を単一のグローバルFIFOではなく、相互に関連する制約として扱っています。
面接官がテストしていること
- テナントクォータ、ジョブ優先度、ノードの適合性の分離。
- 低優先度の処理をスタベーションさせない公平性の定義。
- プリエンプションの副作用、リトライ増幅、断片化(フラグメンテーション)の制限。
- スケジューラの障害、重複ディスパッチ、ワーカー消失からの復旧。
- クラスタ全体の平均ではなく、テナント単位のメトリクスによる公平性の証明。
明確化のための質問
- リソースはCPU、メモリ、GPUですか、それともローカルディスクを持つ異種ノードですか?
- クォータの適用範囲は、テナント、プロジェクト、キュー、組織のいずれですか?
- 優先度によって処理をプリエンプト(横取り)できますか?その場合のチェックポイント復旧コストはどのくらいですか?
- ジョブは分割、キャンセル、リトライが可能ですか?また、結果の書き込みは冪等ですか?
- 公平性はMax-Min公平分配、重み付け共有、待機時間の上限のどれに基づきますか?
30秒での回答
テナントごとにクォータ、使用量、有効期限付きの借用キャパシティを管理し、ジョブをテナントレベルのキューに配置します。ノード制約をフィルタリングした後、スケジューラは重み付け公平サービスに基づいて最もリソース提供が不足しているテナントを選択します。待機時間に応じたエージングによって実効優先度を引き上げ、処理がスタベーションしないようにします。プリエンプションは、ポリシー、クォータ、復旧可能性によって安全であると確認された場合にのみ許可します。予約、リース、フェンシングトークンは永続化し、メトリクスはテナント、キュー、リソースタイプごとにスライスして集計します。
ステップバイステップの設計
ステップ 1: リソースおよびクォータ台帳の構築
CPU、メモリ、GPU、ノードラベルをリソースベクトルとして表現します。長期の使用はテナントクォータを消費し、バースト借用には有効期限を設けます。ディスパッチ前にアトミックにリソースを予約し、完了、キャンセル、またはリース期限切れ時に返却します。呼び出し元が高い優先度を使ってクォータを回避できないよう、アドミッション時とスケジューリング時の両方でクォータを強制します。
ステップ 2: 階層型キューと公平な選択の採用
組織、テナント、ジョブクラスを階層化し、実行可能なテナントの中から重みに基づいて選択します。仮想サービス量または直近のリソース使用量を追跡して不足しているテナントを選択し、待機時間のしきい値を超えたら上限付きエージングを適用します。グローバルな単一優先度キューでは大規模テナントが先頭を永久に占有する恐れがありますが、テナントレベルのローテーションにより公平性の境界が明確になります。
ステップ 3: 優先度、借用、プリエンプションの制限
優先度は緊急性を表すものであり、無制限のキャパシティを意味しません。借用はアイドルキャパシティまたは明示的な期間内に制限されます。プリエンプションを実行する前に、解放されるリソース、チェックポイントコスト、対象となる被害ジョブのバジェットを見積もり、低優先度で復旧可能な処理を優先します。安全な復旧が証明できない場合は、重複による副作用のリスクを冒すよりも、緊急ジョブを待機させます。
ステップ 4: ノードのフィルタリングと断片化の制御
ノードのスコアリングを行う前に、アーキテクチャ、GPUモデル、ゾーン、アフィニティ、キャパシティをフィルタリングします。単一キュー内で大小のリクエストを混在させると断片化が発生するため、大規模シェイプ用に制限付きプールを確保し、待機制限を設定します。拒否の理由は、総キャパシティ不足、シェイプの不一致、クォータ枯渇に分けて個別に記録します。
ステップ 5: リースと冪等な復旧によるディスパッチ
バージョン管理された予約を永続化します。ワーカーはフェンシングトークンを使用して短いリースを取得します。重複ディスパッチは (job_id, attempt) によってチェックされ、期限切れのリースを引き継ぐことができるのは新しいトークンのみです。結果のコミット後に予約を解放します。スケジューラ再起動時は、メモリから推測するのではなく、ログまたはデータベースから未完了ジョブを再構築します。
ステップ 6: 障害、キャンセル、リトライの処理
消失したワーカーはまず不明(unknown)としてマークし、リースとハートビートのウィンドウ経過後に回収します。復旧可能なジョブはチェックポイントから再開し、非冪等な副作用がある場合はステータス確認または補償トランザクションを実行します。リトライは上限付きバックオフを伴い、テナントおよびジョブのバジェットを消費します。障害復旧時に、タイムアウトしたすべてのタスクを一度に再ディスパッチしてはなりません。
ステップ 7: キャパシティのスケーリングとポリシー変更
ノードや重みが変更された場合は、バージョン管理されたポリシーを発行します。すでにキューに入っているジョブには古いポリシーを維持し、新しいワークロードを段階的に移行します。重みの変更によって、約束されたシェアが即座に取り消されてはなりません。GPU、ゾーン、ローカルディスクなどの希少リソースは個別に追跡し、借用と回収の監査イベントを記録します。
ステップ 8: 公平性と効率性の検証
合成ワークロードおよび実ワークロードを用いて負荷テストを実施します。1つの飽和テナント、複数の低速テナント、ランダムなノード消失、チェックポイント復旧、ホットポリシー変更などのシナリオをテストします。テナントの待機時間(p50/p95)、リソースシェア、最大スタベーション間隔、プリエンプション回数、重複実行、キュー滞留時間、断片化、復旧時間を測定します。FIFO、厳密な優先度制御、公平スケジューリングを比較してトレードオフを明らかにします。
高品質な回答例
クォータ、優先度、ノード適合性を分離して設計します。テナントキューは、重み付けされた不足サービス量と制限付きエージングに基づいて選択されます。借用には有効期限付きのアイドルキャパシティを使用し、プリエンプションには復旧可能性の証明、クォータチェック、チェックポイントバジェットを必須とします。すべての割り当てにおいて予約、リース、フェンシングトークンが永続化され、実行結果は試行ごとに冪等性が保たれます。スケジューラはログから状態を再構築し、リトライはテナントのバジェットを消費します。障害テストでは、ノイジーネイバーやワーカー消失を再現し、テナントの待機時間、シェア、スタベーション、重複作業、断片化、復旧時間を比較検証します。
よくある間違い
- 単一のグローバル優先度キュー → 大規模テナントが先頭を占有する → テナントローカルのジョブを選ぶ前にまずテナントを選択する。
- クォータを優先度として扱う → 緊急ジョブが制限を回避してしまう → クォータチェックはアトミックかつ独立して維持する。
- 制限のないプリエンプション → チェックポイントコストと重複の副作用が爆発する → バジェットとクールダウンを設ける。
- メモリ内のみのキュー → 再起動時にディスパッチが重複または消失する → 予約、リース、トークンを永続化する。
- クラスタ平均のみの監視 → 特定テナントのスタベーションが見逃される → 待機時間とシェアをテナントごとにスライスして集計する。
- ワーカー消失直後のリトライ → 古い実行がまだ動いている可能性がある → フェンシングを待つか冪等なパスを使用する。
フォローアップの質問
スタベーションが発生しないことをどのように証明しますか?
実行可能なすべてのテナントに対して最小サービスシェアを確保し、エージングに上限を設けます。固定キャパシティと継続的にスケジューリング可能なワークロードの下で、最大待機時間がポリシーの上限内に収まることを検証します。
プリエンプション後の二重課金をどのように防ぎますか?
試行ごとではなく、論理ジョブまたはコミットされたステージに対して課金します。外部への副作用には冪等性キーとステータス確認を使用します。
クォータがアイドルキャパシティと競合した場合はどうしますか?
有効期限付きの借用を許可し、回収可能なキャパシティとして記録します。まず新規の借用を停止し、処理の完了を待つか、復旧可能な処理のみをプリエンプトします。
スケジューラに強い一貫性は必要ですか?
予約、リース、フェンシングには線形化可能な条件付き更新が必要です。ダッシュボードは非同期でも構いません。古いキャッシュによって最後のGPUが二重割り当てされてはなりません。
公平スケジューリングが不要になるのはどのような場合ですか?
単一テナントの場合、固定のバッチウィンドウの場合、あるいはスタベーションが許容される厳密な優先度制御の場合は、単純な優先度キューの方が検証が容易です。
ロールバックのトリガーは何ですか?
重複実行、復旧の失敗、待機時間上限の違反、テナントシェアのバジェット逸脱が発生した場合に新ポリシーを停止します。古いバージョンを復元し、リプレイ用に予約ログを保持します。