# 画面設計書 24-Master Overview（マスター概要）

## 概要

本ドキュメントは、Standaloneクラスタのマスターノード情報・ワーカー一覧・アプリケーション一覧・ドライバー一覧を表示する画面「Master Overview（マスター概要）」の設計書である。

### 本画面の処理概要

本画面は、Spark Standalone Modeにおけるマスターノードのクラスタ全体の概要を表示する画面であり、MasterWebUIのデフォルト画面である。

**業務上の目的・背景**：Spark Standaloneクラスタの運用管理者は、クラスタ全体のリソース利用状況、ワーカーノードの稼働状態、実行中アプリケーションの状態、ドライバーの状態を一元的に把握する必要がある。本画面は、マスターノードが保持するクラスタ状態情報を集約表示することで、リソースの過不足確認、異常ワーカーの検知、アプリケーションの監視を可能にする。また、アプリケーションやドライバーのKill操作も提供する。

**画面へのアクセス方法**：Standaloneクラスタのマスターノードが提供するWeb UIのルートURL（http://{master-host}:{master-port}/）にアクセスする。MasterWebUIのデフォルトページである。

**主要な操作・処理内容**：
1. マスター基本情報の表示（URL、REST URL、ワーカー状態サマリー、コア/メモリ/リソース使用状況、アプリケーション/ドライバー状態サマリー）
2. Workers一覧テーブルの表示（全ワーカーノードの状態・リソース情報）
3. Running Applications一覧テーブルの表示（実行中アプリケーション一覧）
4. Running Drivers一覧テーブルの表示（実行中ドライバー一覧、ドライバー投入時のみ表示）
5. Completed Applications一覧テーブルの表示（完了アプリケーション一覧）
6. Completed Drivers一覧テーブルの表示（完了ドライバー一覧、ドライバー投入時のみ表示）
7. アプリケーションのKill操作（killEnabled時のみ）
8. ドライバーのKill操作（killEnabled時のみ）
9. JSON API応答（/json/ パスへのアクセス時）

**画面遷移**：
- 遷移先：Application Detail画面（No.25）へアプリケーションID選択、Master Log画面（No.26）へログ表示リンク、Master Environment画面（No.27）へEnvironmentリンク、Spark Application UIへアプリケーションUI表示リンク、Worker UIへワーカーID選択

**権限による表示制御**：Kill操作は `spark.ui.killEnabled` が `true` の場合にのみ表示される。実際のKill実行時には `SecurityManager.checkModifyPermissions(request.getRemoteUser)` による権限チェックが行われる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Spark Web UI | 主機能 | Standaloneクラスタのマスターノード情報をJSON APIとHTML形式で表示する主処理 |
| 84 | Standaloneクラスタマネージャ | 主機能 | MasterEndpointからワーカー一覧・アプリケーション一覧・ドライバー一覧・リソース状況を取得して表示 |
| 15 | 動的リソース割り当て | 補助機能 | クラスタ全体のCPUコア・メモリの使用率・残量を集計して表示 |

## 画面種別

一覧（ダッシュボード）

## URL/ルーティング

- **URL**: `/`（MasterWebUIのルート）
- **HTTPメソッド**: GET
- **JSON API URL**: `/json/`、`/json/clusterutilization`、`/json/{field}`
- **Kill API**: `/app/kill/`（POST）、`/driver/kill/`（POST）
- **ページ名（WebUIPage）**: `""` （デフォルトページ）

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| なし（GETパラメータなし） | - | - | - | マスター状態はRPCで取得 |

### Kill操作パラメータ（POST）

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| id | 入力（POSTパラメータ） | String | 必須 | Kill対象のアプリケーションID/ドライバーID |
| terminate | 入力（POSTパラメータ） | String | 必須 | "true" で実行（確認ダイアログ後） |

## 表示項目

### マスター基本情報セクション

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| URL | state.uri | マスターのSparkプロトコルURL（spark://host:port） |
| REST URL | state.restUri | REST API URL（cluster mode用、存在する場合のみ） |
| Workers | state.workers | Alive/Dead/Decommissioned/Unknown別のワーカー数 |
| Cores in use | aliveWorkers | 総コア数と使用コア数 |
| Memory in use | aliveWorkers | 総メモリと使用メモリ |
| Resources in use | aliveWorkers | カスタムリソースの使用状況 |
| Applications | state.activeApps, state.completedApps | 実行中/完了アプリケーション数 |
| Drivers | state.activeDrivers, state.completedDrivers | 実行中（Waiting含む）/完了（Killed/Failed/Error/Relaunching別）ドライバー数 |
| Status | state.status | マスターの状態（ALIVE/STANDBY等） |

### Workersテーブル

| カラム名 | 説明 |
|----------|------|
| Worker Id | ワーカー識別子（ALIVEの場合はWorker UIへのリンク付き） |
| Address | ワーカーのhost:port |
| State | ワーカー状態（ALIVE/DEAD/DECOMMISSIONED/UNKNOWN） |
| Cores | 総コア数（使用コア数） |
| Memory | 総メモリ（使用メモリ） |
| Resources | カスタムリソース詳細（リソースを持つワーカーが存在する場合のみ表示） |

### Running Applicationsテーブル

| カラム名 | 説明 |
|----------|------|
| Application ID | アプリケーション識別子（Application Detail画面へのリンク付き）。killEnabled時はKillリンク付き |
| Name | アプリケーション名（実行中でUIあればSpark UIへのリンク付き） |
| Cores | 付与されたコア数 |
| Memory per Executor | エグゼキュータあたりのメモリ |
| Resources Per Executor | エグゼキュータあたりのリソース要件 |
| Submitted Time | 投入日時 |
| User | 実行ユーザー |
| State | アプリケーション状態 |
| Duration | 実行時間 |

### Running Driversテーブル（ドライバー投入時のみ表示）

| カラム名 | 説明 |
|----------|------|
| Submission ID | ドライバー識別子。killEnabled時はKillリンク付き |
| Submitted Time | 投入日時 |
| Worker | 実行ワーカー（ALIVEの場合はWorker UIへのリンク付き） |
| State | ドライバー状態 |
| Cores | 使用コア数 |
| Memory | 使用メモリ |
| Resources | 使用リソース |
| Main Class | メインクラス名 |
| Duration | 実行時間 |

### Completed Applications/Driversテーブル

Running Applicationsテーブルと同一のカラム構成（ドライバーはDuration列なし）。

## イベント仕様

### 1-ページ読み込み

1. `master.askSync[MasterStateResponse](RequestMasterState)` でマスター状態をRPCで取得する
2. ワーカー一覧をIDでソートして表示する
3. アクティブアプリケーションを開始時刻の降順でソートして表示する
4. 完了アプリケーションを終了時刻の降順でソートして表示する
5. アクティブドライバーを開始時刻の降順でソートして表示する
6. 完了ドライバーを開始時刻の降順でソートして表示する
7. ドライバーセクションはドライバーが存在する場合のみ表示する

### 2-アプリケーションKill

1. アプリケーション行の(kill)リンクをクリックする
2. JavaScript確認ダイアログ「Are you sure you want to kill application {appId} ?」が表示される
3. 確認後、`/app/kill/` にPOSTリクエストが送信される
4. `handleAppKillRequest` で `killEnabled` と `checkModifyPermissions` をチェック後、`master.removeApplication(app, KILLED)` が呼び出される
5. 100msの待機後、ルートページにリダイレクトされる

### 3-ドライバーKill

1. ドライバー行の(kill)リンクをクリックする
2. JavaScript確認ダイアログ「Are you sure you want to kill driver {driverId} ?」が表示される
3. 確認後、`/driver/kill/` にPOSTリクエストが送信される
4. `handleDriverKillRequest` で `killEnabled` と `checkModifyPermissions` をチェック後、`master.ask[KillDriverResponse](RequestKillDriver(id))` が呼び出される
5. 100msの待機後、ルートページにリダイレクトされる

### 4-JSON API応答

`/json/` パスへのアクセス時、`renderJson` メソッドが呼び出される。
- `/json/` : マスター全体状態のJSON
- `/json/clusterutilization` : クラスタ利用率のJSON
- `/json/{field}` : 特定フィールドのJSON

### 5-テーブル折りたたみ

各テーブルのヘッダをクリックすると、`collapseTable` JavaScript関数で表示/非表示が切り替わる。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ読み込み | MasterEndpoint | RPC/SELECT | RequestMasterStateでクラスタ状態を取得 |
| アプリケーションKill | MasterEndpoint | RPC/UPDATE | removeApplicationでアプリケーション状態をKILLEDに変更 |
| ドライバーKill | MasterEndpoint | RPC/UPDATE | RequestKillDriverでドライバー停止要求を送信 |

### テーブル別更新項目詳細

#### MasterStateResponse（RPC応答）

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| SELECT | uri, restUri, status | - | マスター基本情報 |
| SELECT | workers | - | ワーカー一覧（WorkerInfo） |
| SELECT | activeApps, completedApps | - | アプリケーション一覧（ApplicationInfo） |
| SELECT | activeDrivers, completedDrivers | - | ドライバー一覧（DriverInfo） |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|--------------|----------|
| MSG-01 | 確認 | "Are you sure you want to kill application {appId} ?" | アプリケーションKillリンク押下時（JavaScript確認ダイアログ） |
| MSG-02 | 確認 | "Are you sure you want to kill driver {driverId} ?" | ドライバーKillリンク押下時（JavaScript確認ダイアログ） |

## 例外処理

| 例外 | 発生条件 | 処理 |
|------|----------|------|
| RPC通信エラー | MasterEndpointとの通信が失敗した場合 | Spark UIフレームワークによるエラーページ表示 |

## 備考

- ページタイトルは `spark.master.ui.title` 設定で変更可能（デフォルトは "Spark Master at {uri}"）
- reverseProxy設定時はワーカーやアプリケーションUIへのリンクがプロキシ経由のパスとなる
- Resources列はカスタムリソース（GPU等）を持つワーカーが存在する場合にのみ表示される
- DriverセクションはactiveDrivers + completedDriversが1件以上ある場合にのみ表示される
- Kill操作時には100msのThread.sleepが挟まれる（状態反映の待機）
- JSON APIは `JsonProtocol.writeMasterState` で生成される
- MasterWebUIではDecommission機能も提供されるが、本画面のHTML表示には含まれない（別途REST APIとして `/workers/kill` エンドポイントが存在）

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

マスター状態レスポンスとその中のエンティティクラスを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DeployMessages.scala | `core/src/main/scala/org/apache/spark/deploy/DeployMessages.scala` | MasterStateResponse: uri, workers, activeApps, completedApps, activeDrivers, completedDrivers, status, restUri フィールド |
| 1-2 | WorkerInfo.scala | `core/src/main/scala/org/apache/spark/deploy/master/WorkerInfo.scala` | WorkerInfo: id, host, port, cores, coresUsed, memory, memoryUsed, state, webUiAddress, resourcesInfo, resourcesInfoUsed, resourcesInfoFree |
| 1-3 | ApplicationInfo.scala | `core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala` | ApplicationInfo: id, desc, startTime, endTime, state, coresGranted, executors, removedExecutors |

**読解のコツ**: MasterStateResponseはRPCメッセージであり、MasterEndpoint.receiveAndReply内のRequestMasterStateハンドラから返却される。WorkerState, ApplicationState, DriverState はそれぞれ状態列挙型。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MasterPage.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala` | renderメソッド（101-272行目）: getMasterState()でクラスタ状態取得後、ワーカー・アプリケーション・ドライバーの各テーブルを生成 |

**主要処理フロー**:
1. **102行目**: `getMasterState` でRPC呼び出し
2. **104行目**: リソースカラム表示判定
3. **110-111行目**: ワーカーをID順ソート、ALIVEワーカーをフィルタ
4. **116-118行目**: アクティブアプリケーションを開始時刻降順ソート、完了アプリケーションを終了時刻降順ソート
5. **122-131行目**: アクティブ/完了ドライバーテーブル生成
6. **137-269行目**: HTML生成（基本情報、Workers、Running/Completed Apps、Running/Completed Drivers）
7. **271行目**: `UIUtils.basicSparkPage` でHTMLレスポンス生成

#### Step 3: Kill処理の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MasterPage.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala` | handleAppKillRequest（51-57行目）: アプリケーションKill処理。handleDriverKillRequest（59-63行目）: ドライバーKill処理。handleKillRequest（65-76行目）: 共通Kill処理（権限チェック含む） |

#### Step 4: JSON API処理の理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MasterPage.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala` | renderJson（42-49行目）: JSONフィールドパターンマッチでclusterutilization等の応答を切り替え |

#### Step 5: Web UIフレームワークの理解

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | MasterWebUI.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala` | initialize（54-96行目）: MasterPage, ApplicationPage, LogPage, EnvironmentPageの登録、Kill/Decommission用ハンドラの登録 |

### プログラム呼び出し階層図

```
MasterPage.render(request)
    |
    +-- getMasterState()
    |       +-- master.askSync[MasterStateResponse](RequestMasterState)
    |
    +-- ワーカーテーブル生成
    |       +-- UIUtils.listingTable(workerHeaders, workerRow, workers)
    |
    +-- アクティブアプリテーブル生成
    |       +-- UIUtils.listingTable(appHeaders, appRow, activeApps)
    |
    +-- アクティブドライバーテーブル生成（存在時のみ）
    |       +-- UIUtils.listingTable(activeDriverHeaders, activeDriverRow, activeDrivers)
    |
    +-- 完了アプリテーブル生成
    |       +-- UIUtils.listingTable(appHeaders, appRow, completedApps)
    |
    +-- 完了ドライバーテーブル生成（存在時のみ）
    |       +-- UIUtils.listingTable(completedDriverHeaders, completedDriverRow, completedDrivers)
    |
    +-- UIUtils.basicSparkPage(request, content, title)

MasterPage.handleAppKillRequest(request)     [POST /app/kill/]
    +-- handleKillRequest(request, action)
            +-- checkModifyPermissions(remoteUser)
            +-- master.removeApplication(app, KILLED)

MasterPage.handleDriverKillRequest(request)  [POST /driver/kill/]
    +-- handleKillRequest(request, action)
            +-- checkModifyPermissions(remoteUser)
            +-- master.ask[KillDriverResponse](RequestKillDriver(id))
```

### データフロー図

```
[入力]                       [処理]                           [出力]

HTTPリクエスト           ───> MasterPage.render              ───> HTML Page / JSON
                              |                                  |
MasterEndpoint           ───> askSync(RequestMasterState)   ───> マスター基本情報
  +-- WorkerInfo[]             |                                  +-- Workersテーブル
  +-- ApplicationInfo[]        |                                  +-- Applicationsテーブル
  +-- DriverInfo[]             |                                  +-- Driversテーブル
                              |
                         UIUtils.listingTable()
                         UIUtils.basicSparkPage()

Kill POST               ───> handleAppKillRequest           ───> リダイレクト "/"
                              +-- checkModifyPermissions
                              +-- removeApplication(KILLED)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MasterPage.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterPage.scala` | ソース | マスター概要画面のメインページクラス |
| MasterWebUI.scala | `core/src/main/scala/org/apache/spark/deploy/master/ui/MasterWebUI.scala` | ソース | MasterWebUIの初期化、ページ・ハンドラ登録 |
| DeployMessages.scala | `core/src/main/scala/org/apache/spark/deploy/DeployMessages.scala` | ソース | RPC メッセージ定義（RequestMasterState, MasterStateResponse等） |
| JsonProtocol.scala | `core/src/main/scala/org/apache/spark/deploy/JsonProtocol.scala` | ソース | JSON API応答の生成 |
| WorkerInfo.scala | `core/src/main/scala/org/apache/spark/deploy/master/WorkerInfo.scala` | ソース | ワーカー情報データクラス |
| ApplicationInfo.scala | `core/src/main/scala/org/apache/spark/deploy/master/ApplicationInfo.scala` | ソース | アプリケーション情報データクラス |
| DriverInfo.scala | `core/src/main/scala/org/apache/spark/deploy/master/DriverInfo.scala` | ソース | ドライバー情報データクラス |
| StandaloneResourceUtils.scala | `core/src/main/scala/org/apache/spark/deploy/StandaloneResourceUtils.scala` | ソース | リソースフォーマットユーティリティ |
| UIUtils.scala | `core/src/main/scala/org/apache/spark/ui/UIUtils.scala` | ソース | HTML生成ユーティリティ |
