# 機能設計書 62-リモートクラスタ状態管理

## 概要

本ドキュメントは、OpenSearchのリモートクラスタ状態管理機能に関する機能設計書である。本機能は、クラスタ状態（ClusterState）をリモートストレージに保存・復元する機能であり、クラスタマネージャの障害時にもクラスタ状態の一貫性を保つことを可能にする。

### 本機能の処理概要

**業務上の目的・背景**：OpenSearchのクラスタ状態はインデックスメタデータ、ルーティングテーブル、ノード情報等の重要な管理情報を含む。従来はクラスタマネージャノードのローカルディスクにのみ保存されていたが、リモートストレージに永続化することで、クラスタマネージャ障害時のリカバリを迅速かつ確実に行えるようにする。

**機能の利用シーン**：大規模クラスタにおいてクラスタマネージャノードの障害が発生した際に、新しいクラスタマネージャがリモートストレージからクラスタ状態を取得して復旧する。また、クラスタ状態のリモート公開（Remote Publication）により、フォロワーノードへの状態配布を効率化する。

**主要な処理内容**：
1. クラスタ状態（インデックスメタデータ、グローバルメタデータ、ルーティングテーブル等）のリモートストレージへのアップロード
2. ClusterMetadataManifest（マニフェスト）の生成・保存による状態バージョン管理
3. リモートストレージからのクラスタ状態のダウンロード・復元
4. クラスタ状態の差分アップロード（変更されたメタデータのみアップロード）
5. 古いクラスタ状態のクリーンアップ
6. チェックサムによるクラスタ状態の整合性検証

**関連システム・外部連携**：BlobStoreRepository経由でリモートストレージ（S3、Azure Blob Storage、GCS等）と連携する。

**権限による制御**：`cluster.remote_store.state.enabled`設定により有効化が制御される。クラスタマネージャノードのみがアップロードを行い、全ノードがダウンロードを行うことができる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接的なREST API画面との対応はないが、クラスタ状態APIの内部処理として使用される |

## 機能種別

データ永続化・状態管理 / データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cluster.remote_store.state.enabled | boolean | No | リモートクラスタ状態の有効化フラグ | true/false、NodeScope/Final |
| cluster.remote_store.publication.enabled | boolean | No | リモート公開の有効化フラグ | true/false |
| cluster.remote_store.state.read_timeout | TimeValue | No | 読み取りタイムアウト（デフォルト20秒） | 正のTimeValue |
| cluster.remote_store.state.checksum_validation.mode | Enum | No | チェックサム検証モード（NONE/DEBUG/TRACE/FAILURE） | 指定の列挙値 |
| cluster.remote_store.state.path.prefix | String | No | クラスタ状態パスの固定プレフィックス | 文字列 |

### 入力データソース

ClusterState（インデックスメタデータ、グローバルメタデータ、ルーティングテーブル、DiscoveryNodes、ClusterBlocks等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ClusterMetadataManifest | Object | アップロードされたクラスタ状態のマニフェスト（バージョン、アップロード済みメタデータ一覧等） |
| RemoteUploadStats | Object | アップロード統計（成功回数、失敗回数、所要時間等） |
| RemoteDownloadStats | Object | ダウンロード統計 |

### 出力先

リモートストレージ（BlobStoreRepository経由）

## 処理フロー

### 処理シーケンス

```
1. クラスタ状態変更がコミットされる
   └─ ClusterManagerノードでClusterStateUpdateTaskが実行
2. 変更差分の算出
   └─ ClusterStateDiffManifestで変更されたメタデータを特定
3. 変更されたメタデータをリモートストレージにアップロード
   └─ RemoteIndexMetadataManager / RemoteGlobalMetadataManager / RemoteClusterStateAttributesManager
4. マニフェストの生成・アップロード
   └─ RemoteManifestManagerがClusterMetadataManifestを生成・保存
5. 古いクラスタ状態のクリーンアップ
   └─ RemoteClusterStateCleanupManagerが不要なメタデータを削除
```

### フローチャート

```mermaid
flowchart TD
    A[クラスタ状態変更] --> B{リモート状態有効?}
    B -->|No| C[ローカル永続化のみ]
    B -->|Yes| D[変更差分算出]
    D --> E[インデックスメタデータアップロード]
    D --> F[グローバルメタデータアップロード]
    D --> G[ルーティングテーブルアップロード]
    D --> H[クラスタ属性アップロード]
    E --> I[マニフェスト生成]
    F --> I
    G --> I
    H --> I
    I --> J[マニフェストアップロード]
    J --> K{チェックサム検証}
    K -->|成功| L[完了]
    K -->|失敗| M[エラー処理]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | 差分アップロード | 前回のクラスタ状態から変更があったメタデータのみをアップロードする | クラスタ状態更新時 |
| BR-62-02 | マニフェストバージョニング | CODECバージョン（V2、V3、CURRENT）でマニフェスト形式を管理 | マニフェスト生成時 |
| BR-62-03 | チェックサム検証 | 検証モードに応じてクラスタ状態の整合性を検証（NONE/DEBUG/TRACE/FAILURE） | ダウンロード後 |
| BR-62-04 | クリーンアップ | 一定期間経過した古いクラスタ状態メタデータをリモートストレージから削除 | 定期的なクリーンアップタスク |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| メタデータアップロード | リモートBlobStore | WRITE | インデックスメタデータ、グローバルメタデータ等のアップロード |
| マニフェストアップロード | リモートBlobStore | WRITE | ClusterMetadataManifestの保存 |
| メタデータダウンロード | リモートBlobStore | READ | クラスタ状態のダウンロード |
| クリーンアップ | リモートBlobStore | DELETE | 古いメタデータの削除 |

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

#### リモートBlobStore

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| WRITE | cluster-state/{clusterUUID}/manifest | ClusterMetadataManifest | マニフェスト |
| WRITE | cluster-state/{clusterUUID}/index-metadata | IndexMetadata | インデックスメタデータ |
| WRITE | cluster-state/{clusterUUID}/global-metadata | CoordinationMetadata, Settings, Templates等 | グローバルメタデータ |
| WRITE | cluster-state/{clusterUUID}/routing-table | IndexRoutingTable | ルーティングテーブル |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| RemoteStateTransferException | 転送エラー | リモートストレージへのアップロード/ダウンロード失敗 | リトライまたはローカル状態で回復 |
| IOException | I/Oエラー | BlobStore操作の失敗 | ネットワーク/ストレージの確認 |
| IllegalStateException | 状態エラー | 未初期化のサービスへのアクセス | サービスライフサイクルの確認 |

### リトライ仕様

アップロード失敗時はClusterStateUpdateTask内で例外が伝播し、次回のクラスタ状態変更時に再度アップロードが試行される。

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

クラスタ状態のアップロードはマニフェストをアトミックに書き込むことで一貫性を保証する。メタデータのアップロードは並列で行われるが、すべてのアップロードが完了した後にマニフェストが書き込まれる。

## パフォーマンス要件

- 変更差分のみアップロードすることで帯域幅を最小化
- メタデータのアップロードは並列実行（CountDownLatch + LatchedActionListener）
- SLOW_WRITE_LOGGING_THRESHOLDによる遅延書き込みの検出・ログ出力

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

- リモートストレージへのアクセスはリポジトリ認証情報で保護
- チェックサム検証モード（FAILURE）を有効にすることでデータ整合性を担保
- クラスタ状態にはセンシティブな情報（設定値等）が含まれる可能性があるため、暗号化されたストレージの使用を推奨

## 備考

- RemoteClusterStateServiceは@InternalApiとして提供されており、内部APIである
- マニフェストのCODECバージョンはV2（ルーティングテーブルなし）、V3（差分マニフェスト対応）、CURRENT（最新）がある
- リモートクラスタ状態とリモートルーティングテーブルは独立して設定可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClusterMetadataManifest.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterMetadataManifest.java` | マニフェストのデータ構造、CODECバージョン（V2, V3, CURRENT）、UploadedIndexMetadata、UploadedMetadataAttributeの内部クラス |
| 1-2 | ClusterStateDiffManifest.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterStateDiffManifest.java` | クラスタ状態差分のデータ構造 |
| 1-3 | ClusterStateChecksum.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterStateChecksum.java` | チェックサムの算出方法 |

**読解のコツ**: ClusterMetadataManifestはXContentでシリアライズ/デシリアライズされる。CODECバージョンによってフィールドが異なるため、parseメソッドのバージョン分岐に注意すること。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RemoteClusterStateService.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateService.java` | サービスクラスの全体構造。設定値（REMOTE_CLUSTER_STATE_ENABLED_SETTING等）、アップロード/ダウンロードの主要メソッド |

**主要処理フロー**:
1. **136-141行目**: REMOTE_PUBLICATION_SETTING - リモート公開の有効化設定
2. **153-158行目**: REMOTE_CLUSTER_STATE_ENABLED_SETTING - リモートクラスタ状態の有効化設定
3. **160-167行目**: REMOTE_STATE_READ_TIMEOUT_SETTING - 読み取りタイムアウト設定
4. **169-175行目**: チェックサム検証モード設定
5. **194-198行目**: RemoteClusterStateValidationMode列挙型（DEBUG, TRACE, FAILURE, NONE）

#### Step 3: サブマネージャーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RemoteIndexMetadataManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteIndexMetadataManager.java` | インデックスメタデータのアップロード/ダウンロード |
| 3-2 | RemoteGlobalMetadataManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteGlobalMetadataManager.java` | グローバルメタデータ（CoordinationMetadata, Settings, Templates等）のアップロード/ダウンロード |
| 3-3 | RemoteClusterStateAttributesManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateAttributesManager.java` | クラスタ状態属性（DiscoveryNodes, ClusterBlocks等）のアップロード/ダウンロード |
| 3-4 | RemoteManifestManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteManifestManager.java` | マニフェストの生成・アップロード・読み取り |

#### Step 4: クリーンアップと統計を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RemoteClusterStateCleanupManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateCleanupManager.java` | 古いメタデータのクリーンアップロジック |
| 4-2 | RemotePersistenceStats.java | `server/src/main/java/org/opensearch/gateway/remote/RemotePersistenceStats.java` | 永続化統計 |
| 4-3 | RemoteUploadStats.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteUploadStats.java` | アップロード統計 |
| 4-4 | RemoteDownloadStats.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteDownloadStats.java` | ダウンロード統計 |

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

```
RemoteClusterStateService
    |
    +-- RemoteIndexMetadataManager
    |       +-- BlobStoreTransferService
    |
    +-- RemoteGlobalMetadataManager
    |       +-- BlobStoreTransferService
    |
    +-- RemoteClusterStateAttributesManager
    |       +-- BlobStoreTransferService
    |
    +-- RemoteManifestManager
    |       +-- BlobStoreTransferService
    |
    +-- RemoteClusterStateCleanupManager
    |
    +-- RemoteRoutingTableService (オプション)
    |
    +-- RemoteClusterStateCache
```

### データフロー図

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

ClusterState変更 ──> RemoteClusterStateService ──> リモートBlobStore
                         |                            (manifest/)
                         +-- 差分算出                   (index-metadata/)
                         +-- 並列アップロード             (global-metadata/)
                         +-- マニフェスト生成             (routing-table/)
                         +-- チェックサム検証
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RemoteClusterStateService.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateService.java` | ソース | リモートクラスタ状態管理のメインサービス |
| ClusterMetadataManifest.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterMetadataManifest.java` | ソース | マニフェストデータ構造 |
| ClusterStateDiffManifest.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterStateDiffManifest.java` | ソース | 状態差分マニフェスト |
| ClusterStateChecksum.java | `server/src/main/java/org/opensearch/gateway/remote/ClusterStateChecksum.java` | ソース | チェックサム検証 |
| RemoteIndexMetadataManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteIndexMetadataManager.java` | ソース | インデックスメタデータ管理 |
| RemoteGlobalMetadataManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteGlobalMetadataManager.java` | ソース | グローバルメタデータ管理 |
| RemoteClusterStateAttributesManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateAttributesManager.java` | ソース | クラスタ状態属性管理 |
| RemoteManifestManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteManifestManager.java` | ソース | マニフェスト管理 |
| RemoteClusterStateCleanupManager.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateCleanupManager.java` | ソース | クリーンアップ管理 |
| RemoteClusterStateUtils.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateUtils.java` | ソース | ユーティリティ |
| RemoteClusterStateCache.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteClusterStateCache.java` | ソース | キャッシュ管理 |
| RemoteStateTransferException.java | `server/src/main/java/org/opensearch/gateway/remote/RemoteStateTransferException.java` | ソース | 転送例外 |
| RemotePersistenceStats.java | `server/src/main/java/org/opensearch/gateway/remote/RemotePersistenceStats.java` | ソース | 永続化統計 |
