# 画面設計書 9-データスキュー

## 概要

本ドキュメントは、Apache Flink Web Dashboardのデータスキュー画面の設計仕様を記述したものである。本画面はデータの偏り（スキュー）を分析・表示する。

### 本画面の処理概要

データスキュー画面は、ジョブの各頂点（オペレーター）におけるデータの偏り（スキュー）を分析・表示する。各頂点のnumRecordsInメトリクスからスキュー率を計算し、降順でソートして一覧表示する。

**業務上の目的・背景**：ストリーム処理において、データの偏りはパフォーマンス劣化の主要な原因の一つである。特定のパーティションやキーにデータが集中すると、その処理を担当するタスクがボトルネックになる。本画面により、運用者はデータスキューを早期に検知し、パーティショニング戦略の見直しなどの対策を講じることができる。

**画面へのアクセス方法**：ジョブ詳細画面の「Data Skew」タブをクリック、または`/job/:status/:jid/dataskew`パスに直接アクセスする。

**主要な操作・処理内容**：
1. 各頂点のスキュー率の計算・表示
2. スキュー率による降順ソート
3. 手動リフレッシュ機能

**画面遷移**：
- 遷移元：ジョブ詳細画面
- 遷移先：なし（本画面内で完結）

**権限による表示制御**：本画面に関しては、特別な権限制御は実装されていない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 32 | REST API | 主機能 | データスキュー情報の取得・表示 |
| 57 | メトリクスコア | API連携 | メトリクスからのスキュー率計算 |

## 画面種別

詳細 / 一覧

## URL/ルーティング

- パス: `/job/:status/:jid/dataskew`

## 入出力項目

| 項目名 | 種別 | データ型 | 説明 |
|--------|------|----------|------|
| jid | URLパラメータ | string | ジョブID（親から継承） |

## 表示項目

### スキュー一覧テーブル

| 項目名 | データ型 | 説明 | 取得元 |
|--------|----------|------|--------|
| 頂点名 | string | オペレーター名 | JobLocalService |
| スキュー率 | number | データスキューの度合い（%） | メトリクスAPI |

## イベント仕様

### 1-画面初期化

**トリガー**: コンポーネント初期化時（ngOnInit）

**処理フロー**:
1. refresh$サブジェクトを設定
2. JobLocalService.jobDetailChanges()をサブスクライブ
3. ジョブ詳細を受信したらrefresh$をトリガー
4. refresh$.next()が発火したらスキューデータを取得

**データソース**: JobLocalService.jobDetailChanges()

### 2-スキューデータ取得

**トリガー**: refresh$イベント発火

**処理フロー**:
1. isLoadingをtrueに設定
2. ジョブ詳細からvertices情報を取得
3. 各頂点に対してMetricsService.loadAggregatedMetrics()を呼び出し
4. numRecordsInメトリクスのskewを取得
5. スキュー率をパーセンテージに変換
6. 結果をスキュー率で降順ソート
7. listOfVerticesAndSkewに設定

**API呼び出し**:
- メトリクスAPI（numRecordsIn, skew aggregation）

### 3-手動リフレッシュ

**トリガー**: リフレッシュボタンクリック

**処理フロー**:
1. refresh()が呼び出される
2. refresh$.next()でスキューデータ再取得をトリガー

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

本画面はデータ参照のみを行い、データベースへの更新処理は発生しない。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 該当なし | - | SELECT | 全ての操作は参照のみ |

## メッセージ仕様

本画面では明示的なメッセージ表示は行われない。

## 例外処理

| 例外種別 | 発生条件 | 処理内容 |
|----------|----------|----------|
| メトリクス取得エラー | メトリクスAPI失敗 | スキュー率を0として表示 |
| NaN値 | メトリクスがNaNの場合 | スキュー率を0として設定 |

## 備考

- スキュー計算はloadAggregatedMetrics()のskew集計を使用
- Number.isNaN()でNaN値をチェックし、0に置換
- Math.round()で整数に丸め
- 結果はスキュー率の降順でソート
- ng-zorro-antdのNzTableModuleを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | job-detail.ts | `src/app/interfaces/job-detail.ts` | VerticesItem型の定義 |

**読解のコツ**: スキュー情報はメトリクスAPIから取得され、頂点情報と結合される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | data-skew.component.ts | `src/app/pages/job/dataskew/data-skew.component.ts` | メインコンポーネント |

**主要処理フロー**:
1. **54-94行目**: ngOnInit()でrefresh$とjobDetailChanges()をセットアップ
2. **55-81行目**: refresh$からのスキューデータ取得ロジック
3. **66-77行目**: 各頂点に対するメトリクス取得と結果構築
4. **102-104行目**: refresh()メソッドで手動リフレッシュ

#### Step 3: メトリクスサービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | metrics.service.ts | `src/app/services/metrics.service.ts` | loadAggregatedMetrics()メソッド |

**主要処理フロー**:
- loadAggregatedMetrics()でnumRecordsInメトリクスのskew集計を取得

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

```
DataSkewComponent
    │
    ├─ ngOnInit()
    │      ├─ refresh$.subscribe()
    │      └─ jobDetailChanges().subscribe()
    │
    ├─ JobLocalService.jobDetailChanges()
    │      └─ ジョブ詳細の取得
    │
    ├─ MetricsService.loadAggregatedMetrics()
    │      └─ numRecordsIn skewメトリクスの取得
    │
    └─ refresh()
           └─ refresh$.next()
```

### データフロー図

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

JobLocalService ─────────▶ jobDetail受信
                              │
                              ▼
                        refresh$.next()
                              │
                              ▼
                        vertices取得
                              │
                              ▼
                        各頂点に対してループ
                              │
                              ▼
                        MetricsService.loadAggregatedMetrics()
                              │
                              ▼
                        numRecordsIn.skew取得
                              │
                              ▼
                        パーセンテージ変換 + ソート ──▶ スキュー一覧表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| data-skew.component.ts | `src/app/pages/job/dataskew/data-skew.component.ts` | ソース | メインコンポーネント |
| data-skew.component.html | `src/app/pages/job/dataskew/data-skew.component.html` | テンプレート | レイアウト |
| data-skew.component.less | `src/app/pages/job/dataskew/data-skew.component.less` | スタイル | スタイル定義 |
| metrics.service.ts | `src/app/services/metrics.service.ts` | ソース | メトリクス取得 |
| job-local.service.ts | `src/app/pages/job/job-local.service.ts` | ソース | データ共有 |
| job-detail.ts | `src/app/interfaces/job-detail.ts` | 型定義 | VerticesItem型 |
