# 画面設計書 8-RDD Detail（RDD詳細）

## 概要

本ドキュメントは、Apache Spark Web UIの「RDD Detail（RDD詳細）」画面の設計書である。特定RDDのストレージ詳細情報（データ分布・パーティション情報）を表示する。

### 本画面の処理概要

**業務上の目的・背景**：特定の永続化RDDについて、Executor別のデータ分布（OnHeap/OffHeapメモリ使用量、ディスク使用量）とパーティション別のストレージ情報を確認するための画面である。キャッシュの偏り（データスキュー）の検出や、メモリ使用量の最適化検討に使用される。特定のExecutorにデータが偏っていないか、パーティション単位でストレージレベルが適切かを確認する。

**画面へのアクセス方法**：Storage（ストレージ一覧）画面のRDD名リンクをクリックしてアクセスする。URLパラメータとして`id`（RDD ID）が必要。

**主要な操作・処理内容**：
1. RDDの基本情報表示（Storage Level、Cached Partitions、Total Partitions、Memory Size、Disk Size）
2. Data Distribution on Executors テーブル表示（Executor別のOnHeap/OffHeapメモリ使用量、ディスク使用量）
3. Partitions テーブル表示（パーティション別のBlock Name、Storage Level、メモリ・ディスク使用量、Executors情報、ページング・ソート対応）

**画面遷移**：
- この画面からの遷移先：なし
- この画面への遷移元：Storage画面（RDD名リンク選択）

**権限による表示制御**：特になし。全ユーザーが同一の表示を閲覧できる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Spark Web UI | 主機能 | 特定RDDのストレージ詳細（データ分布・パーティション情報）を表示する主処理 |
| 7 | ブロックストレージ管理 | 主機能 | RDDのExecutor別データ分布（OnHeap/OffHeapメモリ・ディスク使用量）を取得して表示 |
| 5 | Executorプロセス管理 | 補助機能 | パーティションのExecutor配置情報をExecutorリストと突合して表示 |
| 95 | KVStore | API連携 | AppStatusStore.rdd()経由で特定RDDの詳細ストレージ情報を非同期取得 |

## 画面種別

詳細

## URL/ルーティング

- パス: `/storage/rdd/?id={rddId}`
- クラス: `RDDPage` (WebUIPage("rdd"))
- タブ: `StorageTab` (SparkUITab(parent, "storage"))
- 必須パラメータ: `id` (RDD ID、整数)

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|------|------|
| id | 入力（URLパラメータ、必須） | Int | 表示対象のRDD ID |
| block.page | 入力（URLパラメータ） | Int | パーティションテーブルのページ番号（デフォルト: 1） |
| block.sort | 入力（URLパラメータ） | String | パーティションテーブルのソートカラム名（デフォルト: "Block Name"） |
| block.desc | 入力（URLパラメータ） | Boolean | パーティションテーブルのソート順 |
| block.pageSize | 入力（URLパラメータ） | Int | パーティションテーブルの1ページあたり表示件数 |

## 表示項目

### RDD基本情報

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| Storage Level | rddStorageInfo.storageLevel | ストレージレベル |
| Cached Partitions | rddStorageInfo.numCachedPartitions | キャッシュされたパーティション数 |
| Total Partitions | rddStorageInfo.numPartitions | 総パーティション数 |
| Memory Size | rddStorageInfo.memoryUsed | メモリ使用量（bytesToString形式） |
| Disk Size | rddStorageInfo.diskUsed | ディスク使用量（bytesToString形式） |

### Data Distribution on Executors テーブル

| カラム名 | データソース | 説明 |
|----------|-------------|------|
| Host | worker.address | Executorのホストアドレス |
| On Heap Memory Usage | worker.onHeapMemoryUsed / worker.onHeapMemoryRemaining | OnHeapメモリ使用量と残量 |
| Off Heap Memory Usage | worker.offHeapMemoryUsed / worker.offHeapMemoryRemaining | OffHeapメモリ使用量と残量 |
| Disk Usage | worker.diskUsed | ディスク使用量 |

### Partitions テーブル（ページング・ソート対応）

| カラム名 | ソート可否 | データソース | 説明 |
|----------|-----------|-------------|------|
| Block Name | 可 | rddPartition.blockName | ブロック名 |
| Storage Level | 可 | rddPartition.storageLevel | ストレージレベル |
| Size in Memory | 可 | rddPartition.memoryUsed | メモリ上のサイズ |
| Size on Disk | 可 | rddPartition.diskUsed | ディスク上のサイズ |
| Executors | 可 | rddPartition.executors | 配置先のExecutor一覧（アドレス表示） |

## イベント仕様

### 1-パーティションテーブルソート

Partitionsテーブルのカラムヘッダーをクリックすると、そのカラムでソートされる。全5カラムがソート可能。ソートはサーバーサイドで行われる。

### 2-パーティションテーブルページング

テーブル下部のページナビゲーションでページ遷移が可能。ページサイズも変更可能。

### 3-ソートカラム指定時のスクロール

URLにblock.sortパラメータが含まれる場合、ページ読み込み後にパーティションテーブル（#blocks-section）の位置まで自動スクロールする（jQuery animate）。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | KVStore (AppStatusStore) | SELECT | RDDストレージ情報・Executor一覧の読み取り |

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

本画面はデータの読み取り専用である。

## メッセージ仕様

| 種別 | メッセージ | 表示条件 |
|------|----------|----------|
| エラー | "RDD Not Found" | 指定されたRDD IDが存在しない場合（ページタイトルとして表示） |
| エラー | "Missing id parameter" | idパラメータ未指定時（require文） |
| エラー | テーブルレンダリングエラーメッセージ | IllegalArgumentException/IndexOutOfBoundsException発生時（alert表示） |

## 例外処理

| 例外 | 発生条件 | 処理 |
|------|----------|------|
| IllegalArgumentException | idパラメータ未指定 | require文によるエラー |
| NoSuchElementException | RDD IDがKVStoreに存在しない | "RDD Not Found"ページを表示 |
| IllegalArgumentException | 不正なソートカラム名 | テーブル領域にalert表示 |
| IndexOutOfBoundsException | 不正なページ番号 | テーブル領域にalert表示 |

## 備考

- Executor一覧はstore.executorList(true)で取得（activeのみではなく全Executorを含む）
- パーティションのExecutors表示は、executorIdをexecutorSummaries経由でhostPortに変換して表示する
- ソートカラム指定時の自動スクロールはjQuery($(function(){ ... }))で実装される
- ページタイトルは"RDD Storage Info for {rddName}"となる
- BlockPagedTableのテーブルIDは"rdd-storage-by-block-table"、CSSクラスは"table table-bordered table-sm table-striped table-head-clickable"

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | api.scala | `core/src/main/scala/org/apache/spark/status/api/v1/api.scala` | RDDStorageInfo（dataDistribution, partitionsフィールドに注目）、RDDDataDistribution、RDDPartitionInfo |

**読解のコツ**: RDDStorageInfoのdataDistributionとpartitionsフィールドはOption[Seq[...]]型。store.rdd()で取得する場合はSomeが返る。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RDDPage.scala | `core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala` | renderメソッド（35行目）が主処理 |

**主要処理フロー**:
1. **36-37行目**: URLパラメータid取得、requireチェック
2. **39行目**: ページ番号パラメータ取得
3. **42-48行目**: `store.rdd(rddId)` でRDDストレージ情報を取得。NoSuchElementExceptionの場合"RDD Not Found"ページ
4. **51-52行目**: workerTableをUIUtils.listingTableで生成（Data Distribution）
5. **54-65行目**: BlockPagedTableでパーティションテーブルを生成（例外時alert表示）
6. **67-81行目**: ソートカラム指定時の自動スクロールJavaScriptを生成
7. **83-126行目**: RDD基本情報 + Executor分布テーブル + パーティションテーブルをHTMLに結合
8. **128-129行目**: ページタイトル"RDD Storage Info for {rddName}"でラップ

#### Step 3: ページングテーブルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RDDPage.scala | `core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala` | BlockPagedTable（210行目）とBlockDataSource（163行目）がページング・ソート付きパーティションテーブルを構成 |

**主要処理フロー**:
- **163-208行目**: BlockDataSourceがRDDPartitionInfoをBlockTableRowDataに変換。executorIdToAddressマップでExecutor IDをアドレスに変換
- **210-271行目**: BlockPagedTableがテーブルHTML生成。5カラム全てソート可能

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

```
RDDPage.render(request)
    |
    +-- store.rdd(rddId)                    ... RDDストレージ情報取得
    |     （NoSuchElementException -> "RDD Not Found"）
    |
    +-- UIUtils.listingTable(workerHeader, workerRow, dataDistribution)
    |                                        ... Executor分布テーブル生成
    |
    +-- new BlockPagedTable()                ... パーティションテーブル生成
    |     +-- new BlockDataSource()
    |     |     +-- blockRow()               ... RDDPartitionInfo -> BlockTableRowData
    |     |           +-- executorIdToAddress マッピング
    |     +-- table(blockPage)               ... ページ指定でテーブルHTML
    |
    +-- store.executorList(true)              ... Executor一覧取得
    |
    +-- UIUtils.headerSparkPage()             ... ページラップ
```

### データフロー図

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

HTTPリクエスト
  id=rddId          ---> RDDPage.render()
                            |
KVStore              --> rdd(rddId)                --> RDDStorageInfo
                         .dataDistribution         --> Executor分布テーブル
                         .partitions               --> パーティションテーブル
                     --> executorList(true)         --> ExecutorId -> Address変換マップ
                            |
                            v
                        HTML(Seq[Node])             --> ブラウザ表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RDDPage.scala | `core/src/main/scala/org/apache/spark/ui/storage/RDDPage.scala` | ソース | 画面のメインページクラス、BlockPagedTable、BlockDataSource |
| StorageTab.scala | `core/src/main/scala/org/apache/spark/ui/storage/StorageTab.scala` | ソース | Storageタブ定義 |
| AppStatusStore.scala | `core/src/main/scala/org/apache/spark/status/AppStatusStore.scala` | ソース | データアクセス層 |
| api.scala | `core/src/main/scala/org/apache/spark/status/api/v1/api.scala` | ソース | RDDStorageInfo, RDDDataDistribution, RDDPartitionInfoデータモデル |
| PagedTable.scala | `core/src/main/scala/org/apache/spark/ui/PagedTable.scala` | ソース | ページング付きテーブル基底クラス |
| UIUtils.scala | `core/src/main/scala/org/apache/spark/ui/UIUtils.scala` | ソース | HTML生成ユーティリティ |
