# 機能設計書 30-ハートビート

## 概要

本ドキュメントは、Apache Flinkのハートビート機能（flink-runtime モジュール内HeartbeatManager）の設計仕様を記述する。ハートビート機能は、クラスター内コンポーネント間の死活監視を担当する。

### 本機能の処理概要

HeartbeatManagerは、Flinkクラスター内の各コンポーネント（JobManager、TaskManager、ResourceManager）間の接続状態を監視するメカニズム。定期的なハートビート信号の送受信により、コンポーネントの障害を検出する。

**業務上の目的・背景**：分散システムにおいて、ネットワーク障害やプロセス障害を迅速に検出することは、システムの信頼性と可用性を維持するために不可欠である。ハートビートは、障害検出のための標準的なメカニズムとして機能する。

**機能の利用シーン**：
- JobManager-TaskManager間の接続監視
- ResourceManager-JobManager間の接続監視
- ResourceManager-TaskManager間の接続監視
- コンポーネント障害の早期検出

**主要な処理内容**：
1. ハートビートターゲットの監視開始/停止
2. ハートビートリクエストの送信
3. ハートビートレスポンスの受信
4. タイムアウト検出と通知
5. ペイロードによる追加情報の交換

**関連システム・外部連携**：
- JobMaster（ジョブ管理）
- TaskExecutor（タスク実行）
- ResourceManager（リソース管理）
- RPCサービス（通信基盤）

**権限による制御**：各コンポーネント内でインスタンス化。

## 関連画面

本機能は画面機能マッピングには直接含まれていない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 内部処理として使用 |

## 機能種別

死活監視 / 障害検出

## 入力仕様

### 入力パラメータ

#### HeartbeatManager作成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| resourceId | ResourceID | Yes | 自身のリソースID | null不可 |
| heartbeatListener | HeartbeatListener | Yes | タイムアウト通知リスナー | null不可 |
| mainThreadExecutor | ScheduledExecutor | Yes | スケジュール実行用 | null不可 |
| log | Logger | Yes | ロガー | null不可 |

#### ターゲット監視開始

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| resourceID | ResourceID | Yes | 監視対象のリソースID | null不可 |
| heartbeatTarget | HeartbeatTarget | Yes | ハートビート送受信先 | null不可 |

### 入力データソース

- 各コンポーネントからのハートビートリクエスト
- ハートビートレスポンスのペイロード

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイムアウト通知 | void | notifyHeartbeatTimeout()コールバック |
| 到達不能通知 | void | notifyTargetUnreachable()コールバック |
| ペイロード | O | ハートビートに付随する情報 |

### 出力先

- HeartbeatListener（タイムアウト通知）
- 監視対象コンポーネント（ハートビートレスポンス）

## 処理フロー

### 処理シーケンス

```
1. HeartbeatManager初期化
   └─ HeartbeatServicesからインスタンス作成
   └─ タイムアウト間隔設定

2. ターゲット監視開始
   └─ monitorTarget() 呼び出し
   └─ HeartbeatMonitor作成

3. ハートビート送信（Senderの場合）
   └─ 定期的にrequestHeartbeat()実行
   └─ ペイロード取得と送信

4. ハートビート受信
   └─ receiveHeartbeat() でハートビート受信
   └─ タイムスタンプ更新
   └─ ペイロード処理

5. タイムアウト検出
   └─ 一定時間ハートビートなし
   └─ HeartbeatListener.notifyHeartbeatTimeout()

6. 監視停止
   └─ unmonitorTarget() または stop()
```

### フローチャート

```mermaid
flowchart TD
    A[HeartbeatServices.createHeartbeatManager] --> B[HeartbeatManagerImpl作成]
    B --> C[monitorTarget]
    C --> D[HeartbeatMonitor作成]

    D --> E{Sender?}
    E -->|Yes| F[定期的にrequestHeartbeat]
    E -->|No| G[ハートビート待機]

    F --> H[ハートビート送信]
    H --> I{レスポンス受信?}
    I -->|Yes| J[タイムスタンプ更新]
    I -->|No| K[RPC失敗カウント増加]

    G --> L[receiveHeartbeat]
    L --> J

    J --> M{タイムアウト?}
    M -->|No| N[監視継続]
    N --> F
    M -->|Yes| O[notifyHeartbeatTimeout]
    O --> P[障害処理]

    K --> Q{閾値超過?}
    Q -->|Yes| R[notifyTargetUnreachable]
    Q -->|No| N
    R --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | タイムアウト検出 | heartbeatTimeout以内に応答なければタイムアウト | 常時 |
| BR-002 | RPC失敗検出 | 連続RPC失敗で到達不能判定 | failedRpcRequestsUntilUnreachable設定時 |
| BR-003 | ペイロード交換 | ハートビートにペイロード付加可能 | ペイロードがnullでない場合 |
| BR-004 | スレッドセーフ | ConcurrentHashMapで並行アクセス対応 | 常時 |

### 計算ロジック

- タイムアウト時間の計算
- 最終ハートビート時刻の管理

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

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

本機能は直接データベースを操作しない。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| HeartbeatTimeout | システムエラー | タイムアウト検出 | コンポーネント切断処理 |
| RecipientUnreachableException | 通信エラー | RPC失敗 | 到達不能通知 |
| IllegalArgumentException | パラメータエラー | 無効なタイムアウト値 | 設定修正 |

### リトライ仕様

- ハートビートリクエスト: 定期的に再送
- RPC失敗: 閾値までリトライ

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

ハートビート処理はステートレスで、トランザクション管理は不要。

## パフォーマンス要件

- ハートビート間隔: デフォルト10秒
- タイムアウト: デフォルト50秒
- 低オーバーヘッド: ネットワーク負荷最小化

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

- RPCレベルでの認証（Flink全体の設定に依存）

## 備考

- HeartbeatManagerImpl: 受動的なハートビート受信のみ
- HeartbeatManagerSenderImpl: 能動的なハートビート送信
- HeartbeatServicesでConfiguration値から自動設定

---

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

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

### 推奨読解順序

#### Step 1: インターフェースを理解する

HeartbeatManagerのインターフェース群を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HeartbeatManager.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManager.java` | メインインターフェース |
| 1-2 | HeartbeatTarget.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatTarget.java` | ハートビート送受信 |
| 1-3 | HeartbeatListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatListener.java` | イベントリスナー |

**読解のコツ**:
- **HeartbeatManager.java 30行目**: HeartbeatManagerはHeartbeatTargetを継承
- **HeartbeatManager.java 40行目**: monitorTarget()で監視対象登録
- **HeartbeatManager.java 47行目**: unmonitorTarget()で監視停止
- **HeartbeatManager.java 50行目**: stop()で全監視停止
- **HeartbeatManager.java 59行目**: getLastHeartbeatFrom()で最終ハートビート取得

#### Step 2: サービスクラスを理解する

HeartbeatServicesでのインスタンス作成方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HeartbeatServices.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatServices.java` | サービスインターフェース |
| 2-2 | HeartbeatServicesImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatServicesImpl.java` | デフォルト実装 |

**読解のコツ**:
- **HeartbeatServices.java 46-50行目**: createHeartbeatManager()で受動型作成
- **HeartbeatServices.java 65-69行目**: createHeartbeatManagerSender()で能動型作成
- **HeartbeatServices.java 77-88行目**: fromConfiguration()でConfiguration値から自動設定
- **HeartbeatServicesImpl.java 33-38行目**: heartbeatIntervalとheartbeatTimeoutの管理

#### Step 3: 実装を理解する

HeartbeatManagerの実装詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HeartbeatManagerImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManagerImpl.java` | 基本実装 |
| 3-2 | HeartbeatManagerSenderImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManagerSenderImpl.java` | 能動送信実装 |

**読解のコツ**:
- **HeartbeatManagerImpl.java 48-49行目**: @ThreadSafeアノテーション、スレッドセーフ設計
- **HeartbeatManagerImpl.java 52-73行目**: フィールド定義（タイムアウト、リソースID、リスナー、ターゲットマップ）
- **HeartbeatManagerImpl.java 136-163行目**: monitorTarget()でHeartbeatMonitor作成と登録
- **HeartbeatManagerImpl.java 207-219行目**: receiveHeartbeat()でハートビート受信処理
- **HeartbeatManagerImpl.java 221-243行目**: requestHeartbeat()でリクエスト処理
- **HeartbeatManagerSenderImpl.java 35行目**: Runnableを実装して定期実行
- **HeartbeatManagerSenderImpl.java 77行目**: コンストラクタでスケジュール開始
- **HeartbeatManagerSenderImpl.java 80-90行目**: run()で全ターゲットにハートビートリクエスト

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

```
HeartbeatServices (interface)
    │
    ├─ createHeartbeatManager()
    │      └─ HeartbeatManagerImpl作成
    │
    └─ createHeartbeatManagerSender()
           └─ HeartbeatManagerSenderImpl作成
                  │
HeartbeatManager (interface)
    │
    ├─ monitorTarget()
    │      └─ HeartbeatMonitor作成
    │             └─ タイムアウト監視開始
    │
    ├─ unmonitorTarget()
    │      └─ HeartbeatMonitor.cancel()
    │
    ├─ receiveHeartbeat()
    │      └─ reportHeartbeat()
    │             └─ HeartbeatMonitor更新
    │
    ├─ requestHeartbeat()
    │      └─ reportHeartbeat()
    │             └─ HeartbeatTarget.receiveHeartbeat()
    │
    └─ stop()
           └─ 全HeartbeatMonitor.cancel()
```

### データフロー図

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

監視対象登録 ───────────▶ HeartbeatManager ─────────────▶ タイムアウト通知
                              │
                              ▼
                     HeartbeatMonitor(Map)
                              │
           ┌──────────────────┼──────────────────┐
           │                  │                  │
           ▼                  ▼                  ▼
    ハートビート受信     タイムアウト検出      RPC失敗検出
           │                  │                  │
           ▼                  ▼                  ▼
    タイムスタンプ更新  notifyHeartbeatTimeout  notifyTargetUnreachable
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HeartbeatManager.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManager.java` | ソース | メインインターフェース |
| HeartbeatTarget.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatTarget.java` | ソース | ハートビート送受信 |
| HeartbeatListener.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatListener.java` | ソース | イベントリスナー |
| HeartbeatServices.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatServices.java` | ソース | サービスインターフェース |
| HeartbeatServicesImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatServicesImpl.java` | ソース | サービス実装 |
| HeartbeatManagerImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManagerImpl.java` | ソース | 基本実装 |
| HeartbeatManagerSenderImpl.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatManagerSenderImpl.java` | ソース | 能動送信実装 |
| HeartbeatMonitor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/HeartbeatMonitor.java` | ソース | 監視モニター |
| DefaultHeartbeatMonitor.java | `flink-runtime/src/main/java/org/apache/flink/runtime/heartbeat/DefaultHeartbeatMonitor.java` | ソース | モニター実装 |
