# 機能設計書 1-SparkContext管理

## 概要

本ドキュメントは、Apache SparkにおけるSparkContext管理機能の設計を記述する。SparkContextはSparkアプリケーションのエントリポイントであり、クラスタへの接続管理、RDD生成、ジョブ実行制御を一元的に担う中核コンポーネントである。

### 本機能の処理概要

SparkContextは、Sparkアプリケーションとクラスタ間の接続を確立し、分散処理に必要な全てのサブシステム（スケジューラ、メモリ管理、ブロックマネージャ等）を初期化・管理するクラスである。

**業務上の目的・背景**：Sparkアプリケーションが分散クラスタ上でデータ処理を行うためには、クラスタリソースの確保、タスクスケジューリング、データの分散管理といった複雑な処理基盤が必要となる。SparkContextはこれらを統合的に管理し、ユーザーが簡潔なAPIで分散処理を実行できる環境を提供する。1つのJVMにつき1つのSparkContextのみがアクティブであることが保証される。

**機能の利用シーン**：Sparkアプリケーションの起動時に最初に生成され、アプリケーション全体のライフサイクルを通じて利用される。バッチ処理、対話的分析、ストリーミング処理など、あらゆるSparkワークロードの起点となる。

**主要な処理内容**：
1. SparkConf設定の検証とクラスタ接続パラメータの初期化
2. SparkEnv（実行環境）の生成：シリアライザ、RPC環境、ブロックマネージャ等の初期化
3. DAGScheduler、TaskScheduler、SchedulerBackendの生成と起動
4. Web UIの初期化とバインド
5. イベントログ、メトリクスシステムの設定
6. RDD、ブロードキャスト変数、アキュムレータの生成API提供
7. ジョブの実行（runJob）とキャンセル制御
8. リソースのクリーンアップとシャットダウン処理

**関連システム・外部連携**：Hadoop FileSystem（HDFS等）、YARN/Kubernetes/Standaloneクラスタマネージャ、外部メトリクスシステム

**権限による制御**：SecurityManagerによるACL制御（UIアクセス権限、変更権限の制御）。spark.acls.enable設定により有効化される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | - | - | SparkContextはバックエンドコンポーネントであり直接の画面は持たないが、Web UI全体の初期化を担う |

## 機能種別

システム初期化・リソース管理・ジョブ実行制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| config | SparkConf | Yes | アプリケーション設定オブジェクト | spark.masterとspark.app.nameが必須 |
| master | String | Yes（configに含む） | クラスタURL（例: spark://host:port, local[4], yarn） | 空文字列不可 |
| appName | String | Yes（configに含む） | アプリケーション名 | 空文字列不可 |
| sparkHome | String | No | Sparkインストールパス | - |
| jars | Seq[String] | No | クラスタに配布するJARファイルのパス | ローカルパス、HDFS、HTTP/HTTPS/FTP URL |
| environment | Map[String, String] | No | ワーカーノードに設定する環境変数 | - |

### 入力データソース

SparkConf設定オブジェクト（システムプロパティ、設定ファイル、プログラム指定）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| applicationId | String | アプリケーション一意識別子 |
| applicationAttemptId | Option[String] | アプリケーション試行ID |
| uiWebUrl | Option[String] | Web UIのURL |
| statusTracker | SparkStatusTracker | ジョブ・ステージ状態追跡オブジェクト |

### 出力先

SparkContextインスタンスのフィールドとして保持。applicationIdはクラスタマネージャにより割り当てられる。

## 処理フロー

### 処理シーケンス

```
1. SparkConf検証
   └─ spark.master, spark.app.nameの存在確認
2. DriverLoggerの初期化
   └─ ドライバーログ記録の設定
3. リソース検出
   └─ ドライバーリソース（GPU等）の検出と設定
4. LiveListenerBusの生成
   └─ イベントバスの初期化
5. AppStatusStoreの生成
   └─ アプリケーション状態管理ストアの初期化
6. SparkEnvの生成
   └─ RPC環境、シリアライザ、ブロックマネージャ等の初期化
7. Web UIの生成とバインド
   └─ SparkUI生成、ポートバインド
8. HeartbeatReceiverの登録
   └─ Executorハートビート受信エンドポイントの設定
9. TaskScheduler / SchedulerBackendの生成と起動
   └─ クラスタマネージャに応じたスケジューラの選択と起動
10. DAGSchedulerの生成
    └─ ジョブのDAGスケジューリング初期化
11. BlockManagerの初期化
    └─ ブロックストレージの初期化とドライバー登録
12. MetricsSystemの起動
    └─ パフォーマンスメトリクス収集の開始
13. EventLoggingListenerの設定（オプション）
    └─ イベントログ記録の開始
14. ExecutorAllocationManagerの設定（オプション）
    └─ 動的リソース割り当ての開始
15. ShutdownHookの登録
    └─ JVMシャットダウン時のクリーンアップ登録
```

### フローチャート

```mermaid
flowchart TD
    A[SparkContext生成開始] --> B[SparkConf検証]
    B --> C{master/appName設定あり?}
    C -->|No| D[SparkException発生]
    C -->|Yes| E[SparkEnv生成]
    E --> F[Web UI初期化]
    F --> G[HeartbeatReceiver登録]
    G --> H[TaskScheduler/Backend生成]
    H --> I[DAGScheduler生成]
    I --> J[BlockManager初期化]
    J --> K[MetricsSystem起動]
    K --> L[EventLogger設定]
    L --> M{動的割り当て有効?}
    M -->|Yes| N[ExecutorAllocationManager起動]
    M -->|No| O[ShutdownHook登録]
    N --> O
    O --> P[初期化完了]
    D --> Q[stop呼び出し・例外再送出]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シングルトン制約 | 1JVMにつき1つのアクティブなSparkContextのみ許可 | 常時 |
| BR-02 | ドライバー専用 | SparkContextはExecutor上での生成を禁止（EXECUTOR_ALLOW_SPARK_CONTEXT=false時） | デフォルト |
| BR-03 | 停止後の操作禁止 | stop()呼び出し後はメソッド呼び出しでIllegalStateException | stop後 |
| BR-04 | YARN制約 | YARNクラスタモードではspark.yarn.app.idが必要 | master=yarn, deployMode=cluster |

### 計算ロジック

executorMemory算出: `spark.executor.memory`設定値をMB単位で取得（デフォルト1024MB）

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | SparkContextは直接的なデータベース操作を行わない |

### テーブル別操作詳細

該当なし。SparkContextはインメモリ状態管理を行い、永続化はイベントログ（ファイルベース）で実施する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SparkException | 設定エラー | spark.masterが未設定 | SparkConfにmaster URLを設定する |
| SparkException | 設定エラー | spark.app.nameが未設定 | SparkConfにアプリケーション名を設定する |
| SparkException | YARN制約 | YARNクラスタモードでspark.yarn.app.id未設定 | spark-submit経由で実行する |
| IllegalStateException | 状態エラー | 停止済みSparkContextへのアクセス | 新しいSparkContextを生成する |
| IllegalStateException | 状態エラー | 同一JVMで複数のSparkContext生成試行 | 既存のSparkContextをstop()してから生成 |

### リトライ仕様

SparkContext初期化時のエラーはリトライされない。初期化失敗時はstop()が呼ばれ、リソースがクリーンアップされる。

## トランザクション仕様

SparkContext初期化はtry-catchブロックで保護され、初期化途中でエラーが発生した場合はstop()メソッドにより部分的に初期化されたコンポーネントが全てクリーンアップされる（409-747行目）。

## パフォーマンス要件

- SparkContext初期化: 通常数秒以内（クラスタマネージャとの接続時間に依存）
- ハートビート間隔: `spark.executor.heartbeatInterval`（デフォルト10秒）
- メトリクスポーリング間隔: `spark.driver.metrics.pollingInterval`

## セキュリティ考慮事項

- SecurityManagerによるACLベースのアクセス制御
- spark.authenticate設定による認証制御
- UIアクセス制御（spark.ui.view.acls, spark.ui.modify.acls）
- 設定値のリダクション（パスワード等の機密情報マスク処理: Utils.redact）

## 備考

- SparkContextの生成にはSparkSession.builder().getOrCreate()の利用が推奨される（Spark 2.0以降）
- JVM内で唯一のアクティブSparkContextはSparkContext.activeContextで管理される
- ShutdownHookによりJVM終了時に自動的にstop()が呼ばれる

---

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

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

### 推奨読解順序

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

SparkContextが管理する内部状態フィールドと設定オブジェクトを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SparkConf.scala | `core/src/main/scala/org/apache/spark/SparkConf.scala` | 設定管理クラス。キーバリュー形式の設定保持とバリデーション |
| 1-2 | SparkEnv.scala | `core/src/main/scala/org/apache/spark/SparkEnv.scala` | 実行環境の構成要素（シリアライザ、RPC環境、ブロックマネージャ等） |

**読解のコツ**: SparkContextの内部変数（216-246行目）は全てnullで初期化され、tryブロック内（409行目以降）で順次初期化される。この遅延初期化パターンにより、初期化途中でのstop()呼び出しが安全に行える。

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

SparkContextのコンストラクタが初期化の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SparkContext.scala | `core/src/main/scala/org/apache/spark/SparkContext.scala` | クラス定義（86行目）からコンストラクタ処理全体 |

**主要処理フロー**:
1. **86行目**: クラス定義。SparkConf引数を受け取る
2. **93-96行目**: Executor上でのSparkContext生成防止チェック
3. **101行目**: 部分構築マーク（シングルトン制約）
4. **409-417行目**: SparkConf検証と基本設定
5. **492行目**: LiveListenerBus生成
6. **497行目**: AppStatusStore生成
7. **501行目**: SparkEnv生成
8. **519-526行目**: Web UI生成
9. **590-591行目**: HeartbeatReceiver登録
10. **600-603行目**: TaskScheduler、SchedulerBackend、DAGScheduler生成
11. **629行目**: TaskScheduler起動
12. **650行目**: BlockManager初期化

#### Step 3: ジョブ実行メカニズムを理解する

SparkContextのrunJobメソッドがジョブ実行の中核API。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SparkContext.scala | `core/src/main/scala/org/apache/spark/SparkContext.scala` | runJobメソッド群：RDDに対するアクション実行 |
| 3-2 | DAGScheduler.scala | `core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala` | ジョブのDAG構築とステージ分割 |

#### Step 4: リソースクリーンアップを理解する

stop()メソッドによる各コンポーネントの停止順序を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SparkContext.scala | `core/src/main/scala/org/apache/spark/SparkContext.scala` | stop()メソッド：初期化の逆順でコンポーネントを停止 |

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

```
SparkContext(config: SparkConf)
    |
    +-- SparkConf.validateSettings()
    +-- DriverLogger(_conf)
    +-- LiveListenerBus(_conf)
    +-- AppStatusStore.createLiveStore()
    +-- createSparkEnv()
    |       +-- SparkEnv.createDriverEnv()
    |               +-- RpcEnv.create()
    |               +-- SerializerManager()
    |               +-- BlockManager()
    |               +-- ShuffleManager()
    |
    +-- SparkUI.create()
    +-- HeartbeatReceiver(this)
    +-- SparkContext.createTaskScheduler()
    |       +-- TaskSchedulerImpl()
    |       +-- SchedulerBackend (Standalone/YARN/K8s/Local)
    |
    +-- DAGScheduler(this)
    +-- BlockManager.initialize()
    +-- MetricsSystem.start()
    +-- EventLoggingListener() [optional]
    +-- ExecutorAllocationManager() [optional]
```

### データフロー図

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

SparkConf設定      ───▶  SparkContext初期化     ───▶  applicationId
                         |                           Web UI URL
                         +-- SparkEnv生成             statusTracker
                         +-- Scheduler生成
                         +-- BlockManager初期化

ユーザーコード     ───▶  runJob()               ───▶  計算結果
(RDDアクション)          |
                         +-- DAGScheduler.submitJob()
                         +-- TaskScheduler.submitTasks()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SparkContext.scala | `core/src/main/scala/org/apache/spark/SparkContext.scala` | ソース | 本機能のメインクラス |
| SparkConf.scala | `core/src/main/scala/org/apache/spark/SparkConf.scala` | ソース | 設定管理 |
| SparkEnv.scala | `core/src/main/scala/org/apache/spark/SparkEnv.scala` | ソース | 実行環境管理 |
| DAGScheduler.scala | `core/src/main/scala/org/apache/spark/scheduler/DAGScheduler.scala` | ソース | DAGスケジューリング |
| TaskSchedulerImpl.scala | `core/src/main/scala/org/apache/spark/scheduler/TaskSchedulerImpl.scala` | ソース | タスクスケジューリング |
| LiveListenerBus.scala | `core/src/main/scala/org/apache/spark/scheduler/LiveListenerBus.scala` | ソース | イベントバス |
| HeartbeatReceiver.scala | `core/src/main/scala/org/apache/spark/HeartbeatReceiver.scala` | ソース | ハートビート受信 |
| SecurityManager.scala | `core/src/main/scala/org/apache/spark/SecurityManager.scala` | ソース | セキュリティ管理 |
| ContextCleaner.scala | `core/src/main/scala/org/apache/spark/ContextCleaner.scala` | ソース | リソースクリーンアップ |
| SparkStatusTracker.scala | `core/src/main/scala/org/apache/spark/SparkStatusTracker.scala` | ソース | ジョブ状態追跡 |
