# 機能設計書 47-クラスタヘルス

## 概要

本ドキュメントは、OpenSearchクラスタ全体の健全性状態を監視・報告するクラスタヘルス機能の設計書である。

### 本機能の処理概要

**業務上の目的・背景**：クラスタの運用においては、クラスタ全体の健全性をリアルタイムで把握し、問題の早期検出と対処を行うことが不可欠である。クラスタヘルス機能はgreen/yellow/redの3段階のステータスを提供し、ノード数、シャードの割り当て状況、リロケーション状態などの包括的なヘルス情報を返す。

**機能の利用シーン**：クラスタ監視ダッシュボード、ヘルスチェックスクリプト、自動スケーリングの判定条件、デプロイメント時のヘルス確認など、運用全般で広く利用される。

**主要な処理内容**：
1. クラスタヘルス情報の取得：ステータス、ノード数、シャード状態の集計
2. 待機条件の指定：特定のステータス、アクティブシャード数、ノード数等の条件到達まで待機
3. アウェアネスヘルス：ゾーン・ラック等のアウェアネス属性に基づくヘルス情報
4. レベル指定：cluster/indices/shardsの詳細レベル指定

**関連システム・外部連携**：クラスタ状態（ClusterState）から情報を集約する。Awareness Health機能と連携可能。

**権限による制御**：クラスタマネージャノードへの読み取り操作（TransportClusterManagerNodeReadAction）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 90 | クラスタヘルス | 主機能 | クラスタのヘルス情報（green/yellow/red）を返す処理 |
| 151 | Cat ヘルス | 主機能 | クラスタヘルスの簡潔なテーブル形式表示を返す処理 |

## 機能種別

計算処理 / データ参照

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| indices | String[] | No | 対象インデックス（未指定時は全インデックス） | - |
| awarenessAttribute | String | No | アウェアネス属性名 | - |
| timeout | TimeValue | No | タイムアウト | デフォルト30秒 |
| waitForStatus | ClusterHealthStatus | No | 待機するヘルスステータス | green/yellow/red |
| waitForNoRelocatingShards | boolean | No | リロケーション中シャードがなくなるまで待機 | デフォルトfalse |
| waitForNoInitializingShards | boolean | No | 初期化中シャードがなくなるまで待機 | デフォルトfalse |
| waitForActiveShards | ActiveShardCount | No | 待機するアクティブシャード数 | デフォルトNONE |
| waitForNodes | String | No | 待機するノード数条件 | 数値または比較演算子付き |
| waitForEvents | Priority | No | 待機するイベント優先度 | - |
| level | Level | No | 詳細レベル | CLUSTER/INDICES/SHARDS |
| ensureNodeWeighedIn | boolean | No | ノード重み付け確認 | デフォルトfalse |

### 入力データソース

REST API経由でのリクエスト（`GET /_cluster/health`、`GET /_cluster/health/{index}`）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| cluster_name | String | クラスタ名 |
| status | String | ヘルスステータス（green/yellow/red） |
| timed_out | boolean | タイムアウトしたか |
| number_of_nodes | int | ノード数 |
| number_of_data_nodes | int | データノード数 |
| active_primary_shards | int | アクティブプライマリシャード数 |
| active_shards | int | アクティブシャード数 |
| relocating_shards | int | リロケーション中シャード数 |
| initializing_shards | int | 初期化中シャード数 |
| unassigned_shards | int | 未割り当てシャード数 |
| active_shards_percent_as_number | double | アクティブシャード割合（%） |
| indices | Map<String, ClusterIndexHealth> | インデックスレベルヘルス（level=indices時） |

### 出力先

REST APIレスポンス（JSON形式）。RestStatus連動でHTTPステータスコードも変化する（green=200, yellow=200, red=408/503等）。

## 処理フロー

### 処理シーケンス

```
1. REST APIリクエスト受信
   └─ ClusterHealthRequest生成
2. クラスタマネージャノードへ転送
   └─ TransportClusterManagerNodeReadAction経由
3. 重み付けノードチェック
   └─ ensureNodeWeighedIn時、重み付け除外ノードからのリクエストを拒否
4. 待機条件評価
   └─ ClusterStateObserverで条件成立を監視
5. ヘルス情報集計
   └─ ClusterStateHealthからステータスを算出
6. レスポンス生成
   └─ ClusterHealthResponse構築
```

### フローチャート

```mermaid
flowchart TD
    A[Cluster Health Request] --> B[Route to Cluster Manager]
    B --> C{Wait conditions?}
    C -->|No| D[Calculate Health]
    C -->|Yes| E[Start ClusterStateObserver]
    E --> F{Conditions met?}
    F -->|Yes| D
    F -->|Timeout| G[Return timed_out=true]
    D --> H[Build ClusterHealthResponse]
    H --> I[Return Response]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | ヘルスステータス判定 | green=全シャード割り当て済み、yellow=レプリカ未割り当て、red=プライマリ未割り当て | 常時 |
| BR-47-02 | 待機タイムアウト | 待機条件が指定されtimeout内に達成されない場合、timed_out=trueで返却 | waitFor*パラメータ指定時 |
| BR-47-03 | ノード重み付け除外 | ensureNodeWeighedIn=trueの場合、重み付けゼロのノードからのリクエストは拒否 | ensureNodeWeighedIn指定時 |
| BR-47-04 | デコミッションノード除外 | デコミッション済みノードからのリクエストは拒否 | デコミッション状態時 |

### 計算ロジック

ヘルスステータスはClusterStateHealthクラスで算出される。各インデックスのヘルスステータスのうち最も深刻なものがクラスタ全体のステータスとなる。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| ヘルス取得 | ClusterState | SELECT | クラスタ状態からヘルス情報を集計 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ClusterManagerNotDiscoveredException | クラスタマネージャが未発見 | クラスタマネージャの起動を待つ |
| - | NodeDecommissionedException | デコミッション済みノードからのリクエスト | 別のノードから実行 |
| - | NodeWeighedAwayException | 重み付けゼロのノードからのリクエスト | 別のノードから実行 |
| - | IndexNotFoundException | 指定インデックスが存在しない | インデックス名を確認 |

### リトライ仕様

待機条件指定時はClusterStateObserverにより条件成立まで自動的に監視が継続される。

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

読み取り専用操作であり、トランザクション管理は不要。

## パフォーマンス要件

デフォルトタイムアウト30秒。待機条件を使用する場合はタイムアウト値に注意が必要。

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

- クラスタ読み取り権限が必要
- デコミッションノードや重み付けゼロノードからのアクセス制御

## 備考

ClusterHealthResponseはStatusToXContentObjectを実装しており、ヘルスステータスに応じたHTTPステータスコードが返却される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClusterHealthRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthRequest.java` | リクエストパラメータ。waitFor*系パラメータ、Level列挙型を理解する |
| 1-2 | ClusterHealthResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/ClusterHealthResponse.java` | レスポンスデータ構造。StatusToXContentObjectの実装を確認 |

**読解のコツ**: ClusterHealthRequestの**60-77行目**でリクエストのフィールド定義とデフォルト値を確認する。Level列挙型（CLUSTER/INDICES/SHARDS/AWARENESS_ATTRIBUTES）が詳細レベルを制御する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TransportClusterHealthAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/TransportClusterHealthAction.java` | TransportClusterManagerNodeReadActionを継承。待機条件の評価ロジックが核心 |

**主要処理フロー**:
- TransportClusterManagerNodeReadActionの継承により、クラスタマネージャノードで実行される読み取り操作
- ClusterStateObserverを使用して待機条件の成立を監視
- 重み付けルーティングとデコミッションのチェックロジック

#### Step 3: ヘルス集計ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ClusterStateHealth.java | `server/src/main/java/org/opensearch/cluster/health/ClusterStateHealth.java` | クラスタ状態からヘルス情報を集計するクラス |
| 3-2 | ClusterIndexHealth.java | `server/src/main/java/org/opensearch/cluster/health/ClusterIndexHealth.java` | インデックスレベルのヘルス情報 |
| 3-3 | ClusterAwarenessHealth.java | `server/src/main/java/org/opensearch/cluster/awarenesshealth/ClusterAwarenessHealth.java` | アウェアネス属性ベースのヘルス情報 |

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

```
TransportClusterHealthAction
    |
    +-- clusterManagerOperation()
    |       +-- WeightedRoutingUtils (ensureNodeWeighedIn check)
    |       +-- ClusterStateObserver (wait conditions)
    |       +-- ClusterStateHealth (health calculation)
    |
    +-- ClusterHealthResponse
            +-- ClusterStateHealth
            |       +-- ClusterIndexHealth
            |               +-- ClusterShardHealth
            +-- ClusterAwarenessHealth (optional)
```

### データフロー図

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

ClusterHealthRequest --> TransportClusterHealthAction    --> ClusterHealthResponse
  (indices, timeout,       |                                  (status, nodes, shards,
   waitFor*, level)        +-> ClusterState                    timed_out, ...)
                           +-> ClusterStateHealth
                           +-> ClusterAwarenessHealth
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClusterHealthAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/health/` | ソース | アクション定義 |
| ClusterHealthRequest.java | 同上 | ソース | リクエスト定義 |
| ClusterHealthResponse.java | 同上 | ソース | レスポンス定義 |
| TransportClusterHealthAction.java | 同上 | ソース | トランスポートアクション |
| ClusterStateHealth.java | `server/src/main/java/org/opensearch/cluster/health/` | ソース | ヘルス集計ロジック |
| ClusterIndexHealth.java | 同上 | ソース | インデックスヘルス |
| ClusterHealthStatus.java | 同上 | ソース | ヘルスステータス列挙型 |
| ClusterAwarenessHealth.java | `server/src/main/java/org/opensearch/cluster/awarenesshealth/` | ソース | アウェアネスヘルス |
