# バッチ設計書 14-start-connect-server.sh

## 概要

本ドキュメントは、Spark Connectサーバーを起動するシェルスクリプト `start-connect-server.sh` のバッチ設計書である。スクリプトの処理内容、実行条件、入出力仕様、エラー処理等について記載する。

### 本バッチの処理概要

`start-connect-server.sh` は、Spark Connect サーバー（SparkConnectServer）をデーモンプロセスとして起動するシェルスクリプトである。Spark Connectは、gRPCベースのクライアント-サーバーアーキテクチャを提供し、多言語クライアントからSparkに接続するためのエンドポイントを提供する。内部的には `spark-daemon.sh` の submit モードを使用し、`spark-submit` 経由で SparkConnectServer クラスを起動する。

**業務上の目的・背景**：Spark Connectは従来のJDBC/ODBCとは異なり、gRPCプロトコルを使用した新しい接続方式を提供する。Python、Scala、R等の多言語クライアントからリモートのSparkクラスタに接続するためのサーバーサイドプロセスであり、このスクリプトにより統一的なデーモン管理インターフェースを通じて起動される。`--wait` オプションによりフォアグラウンド実行にも対応しており、Kubernetes環境等での利用も想定されている。

**バッチの実行タイミング**：手動実行が基本。Sparkクラスタのセットアップ時やSpark Connectサーバーの再起動時に管理者が実行する。`--wait` オプション使用時はコンテナオーケストレーターからの起動も想定される。

**主要な処理内容**：
1. SPARK_CONNECT_MODE環境変数を0に設定
2. SPARK_HOME環境変数の設定（未設定の場合はスクリプト配置場所から自動検出）
3. `--help` / `-h` オプションが指定された場合、使用方法を表示して終了
4. `load-spark-env.sh` による環境設定の読み込み
5. `--wait` オプションが指定された場合、SPARK_NO_DAEMONIZEを設定（フォアグラウンド実行）
6. `spark-daemon.sh` の submit モードで SparkConnectServer クラスをデーモンとして起動

**前後の処理との関連**：`stop-connect-server.sh`（No.15）と対になるスクリプトである。起動処理は `spark-daemon.sh`（No.16）のsubmitモードに委譲され、さらに内部で `spark-submit`（No.20）が呼び出される。`load-spark-env.sh`（No.30関連）を使用してSpark環境変数を読み込む。

**影響範囲**：Spark Connectサーバーが起動することで、gRPCベースのクライアントからのSpark接続が可能となる。デフォルトではポート15002でgRPCリクエストを待ち受ける。

## バッチ種別

デーモン管理（プロセス起動）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| SPARK_HOME | 環境変数が設定済み、または自動検出可能であること |
| spark-daemon.sh | `${SPARK_HOME}/sbin/spark-daemon.sh` が存在し実行可能であること |
| spark-submit | `${SPARK_HOME}/bin/spark-submit` が存在し実行可能であること |
| load-spark-env.sh | `${SPARK_HOME}/bin/load-spark-env.sh` が存在し実行可能であること |
| Java実行環境 | JAVA_HOMEまたはPATHにjavaコマンドが存在すること |
| Spark Connect依存関係 | SparkConnectServerクラスに必要なJARがクラスパスに含まれていること |

### 実行可否判定

`spark-daemon.sh` 内でPIDファイルの存在確認とプロセスの生存確認を行い、既に同名プロセスが稼働中の場合は「running as process [PID]. Stop it first.」というメッセージを出力し、起動を拒否する（終了コード1）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| --wait | フラグ | No | - | フォアグラウンドで実行（SPARK_NO_DAEMONIZE=1を設定） |
| --help / -h | フラグ | No | - | 使用方法を表示して終了 |
| [options] | 文字列 | No | - | spark-submitに渡されるオプション（--master, --conf等） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| PIDファイル | テキストファイル | 既存プロセスの確認に使用 |
| spark-env.sh | シェルスクリプト | Spark環境設定の読み込み（load-spark-env.sh経由） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | 起動処理のステータスメッセージ |
| 標準エラー出力 | テキスト | ヘルプ情報（--help時） |
| PIDファイル | テキスト | 起動したプロセスのPID（デーモンモード時のみ） |
| ログファイル | テキスト | デーモンの出力ログ |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| PIDファイル名 | `spark-${SPARK_IDENT_STRING}-org.apache.spark.sql.connect.service.SparkConnectServer-1.pid` |
| PID出力先 | `${SPARK_PID_DIR}/`（デフォルト: /tmp） |
| ログファイル名 | `spark-${SPARK_IDENT_STRING}-org.apache.spark.sql.connect.service.SparkConnectServer-1-${HOSTNAME}.out` |
| ログ出力先 | `${SPARK_LOG_DIR}/`（デフォルト: ${SPARK_HOME}/logs） |

## 処理フロー

### 処理シーケンス

```
1. SPARK_CONNECT_MODE=0 を設定
   └─ 環境変数の初期化
2. POSIXモードを有効化（set -o posix）
   └─ Bashの拡張機能を制限し互換性を確保
3. SPARK_HOME環境変数の確認・設定
   └─ 未設定の場合、スクリプトの配置ディレクトリから親ディレクトリを算出
4. 起動クラスの設定
   └─ CLASS=org.apache.spark.sql.connect.service.SparkConnectServer
5. ヘルプオプションの判定
   └─ --help/-hが指定された場合、使用方法を表示して終了
6. load-spark-env.shの読み込み
   └─ spark-env.shの環境変数をロード
7. --waitオプションの判定
   └─ 指定された場合、SPARK_NO_DAEMONIZE=1を設定してフォアグラウンド実行モードに
8. spark-daemon.sh submit の呼び出し
   └─ exec経由で spark-daemon.sh submit $CLASS 1 --name "Spark Connect server" "$@" を実行
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[SPARK_CONNECT_MODE=0設定]
    B --> C[POSIXモード有効化]
    C --> D[SPARK_HOME設定確認]
    D --> E{--help/-h指定?}
    E -->|Yes| F[使用方法表示]
    F --> G[終了 exit 0]
    E -->|No| H[load-spark-env.sh読み込み]
    H --> I{--wait指定?}
    I -->|Yes| J[SPARK_NO_DAEMONIZE=1設定]
    I -->|No| K[spark-daemon.sh submit呼び出し]
    J --> K
    K --> L{既存プロセス稼働中?}
    L -->|Yes| M["エラー: Stop it first."]
    L -->|No| N[ログローテーション]
    N --> O[spark-submit --class で起動]
    O --> P{SPARK_NO_DAEMONIZE設定?}
    P -->|Yes| Q[フォアグラウンド起動]
    P -->|No| R[nohupでバックグラウンド起動]
    R --> S[PIDファイル書き込み]
    S --> T[プロセス起動確認]
    T --> U[バッチ終了]
    Q --> U
    M --> U
```

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

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

本スクリプト自体はデータベース操作を行わない。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 終了コード1 | 既存プロセス稼働中 | 同じクラス・インスタンス番号のプロセスが既に稼働中 | stop-connect-server.shで先に停止する |
| 終了コード1 | SPARK_HOME不正 | SPARK_HOMEの自動検出に失敗 | SPARK_HOME環境変数を手動で正しく設定する |
| なし | 起動失敗 | Javaプロセスが起動後すぐに終了 | ログファイルの末尾10行を表示。ログファイルで詳細を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

起動失敗時はログファイル `${SPARK_LOG_DIR}/spark-*-org.apache.spark.sql.connect.service.SparkConnectServer-*.out` を確認する。PIDファイルが残存している場合は手動で削除し、再度起動を試みる。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（シェルスクリプトのためトランザクション管理なし） |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1プロセス |
| 目標処理時間 | 起動確認まで約7秒（デーモンモード時） |
| メモリ使用量上限 | スクリプト自体は最小限。起動されるJVMのメモリはSpark設定に依存 |

## 排他制御

PIDファイルによる排他制御が行われる。同一クラス名・インスタンス番号のプロセスが既に稼働中の場合、新たな起動は拒否される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | デーモン起動時 | 「starting org.apache.spark.sql.connect.service.SparkConnectServer, logging to [ログパス]」 |
| 起動失敗ログ | プロセス起動失敗時 | 「failed to launch: [コマンド]」+ ログ末尾10行 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 該当なし | - | 本スクリプト自体に監視・アラート機能は実装されていない |

## 備考

- `--wait` オプションが指定された場合、SPARK_NO_DAEMONIZE=1が設定され、プロセスはフォアグラウンドで実行される。PIDファイルは生成されない。このモードはKubernetes環境等でコンテナのメインプロセスとして実行する場合に使用される。
- SPARK_CONNECT_MODE=0 が設定されている。
- `exec` コマンドで `spark-daemon.sh` を呼び出しているため、本スクリプトのプロセスは `spark-daemon.sh` に置き換わる。
- `--name "Spark Connect server"` がアプリケーション名として設定される。
- SparkConnectServerのクラス名は `SparkSubmit` 内部で特別にマッチングされるため、変更する場合は `SparkSubmit` 側の修正も必要（ソースコードコメントに記載あり）。
- `load-spark-env.sh` が `--wait` オプションの判定前に読み込まれるため、spark-env.sh内の設定が反映される。
- ソースファイルパス: `sbin/start-connect-server.sh`
