# 機能設計書 50-クラスタ設定管理

## 概要

本ドキュメントは、OpenSearchクラスタレベルの動的設定を更新・取得するクラスタ設定管理機能の設計書である。

### 本機能の処理概要

**業務上の目的・背景**：クラスタの運用においては、シャードアロケーションルール、レプリカ数のデフォルト値、リカバリ設定などのクラスタレベル設定を動的に変更する必要がある。本機能は一時的（transient）および永続的（persistent）な設定の更新・取得を提供し、クラスタの再起動なしに設定変更を行えるようにする。

**機能の利用シーン**：シャードアロケーションの一時的な無効化（メンテナンス時）、リカバリ設定の変更、互換性モードの切り替え、リモートストアマイグレーション設定の変更など。

**主要な処理内容**：
1. クラスタ設定の更新（PUT）：transientおよびpersistent設定の更新
2. クラスタ設定の取得（GET）：現在のクラスタ設定の参照
3. 設定更新後のreroute：設定変更がシャード配置に影響する場合の自動再配置

**関連システム・外部連携**：AllocationServiceと連携し、設定変更後にシャードの再配置（reroute）を実行する。RemoteStoreNodeServiceと連携し、リモートストア互換性モードの変更を制御する。

**権限による制御**：METADATA_WRITEレベルのクラスタブロックチェック。ただし、READ_ONLYやREAD_ONLY_ALLOW_DELETE設定自体の変更はブロック対象外。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 93 | クラスタ設定取得 | 主機能 | クラスタレベルの設定を返す処理 |
| 94 | クラスタ設定更新 | 主機能 | クラスタレベルの動的設定を更新する処理 |

## 機能種別

CRUD操作

## 入力仕様

### 入力パラメータ（設定更新）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| transient | Settings | No | 一時的設定（クラスタ再起動で消える） | transientまたはpersistentの少なくとも一方が必要 |
| persistent | Settings | No | 永続的設定（クラスタ再起動後も保持） | transientまたはpersistentの少なくとも一方が必要 |

### 入力パラメータ（設定取得）

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| include_defaults | boolean | No | デフォルト設定を含めるか | - |

### 入力データソース

REST API経由でのリクエスト（`PUT /_cluster/settings`、`GET /_cluster/settings`）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| acknowledged | boolean | 操作が承認されたか |
| transient | Settings | 更新後の一時的設定 |
| persistent | Settings | 更新後の永続的設定 |

### 出力先

REST APIレスポンス（JSON形式）

## 処理フロー

### 処理シーケンス

```
1. REST APIリクエスト受信
   └─ ClusterUpdateSettingsRequest生成
2. クラスタブロックチェック
   └─ METADATA_WRITEブロックの確認（READ_ONLY設定変更の場合はスキップ）
3. バリデーション
   └─ クラスタ全プライマリシャード数制限の検証
   └─ 互換性モード変更時の全ノード同一バージョン・同一タイプ検証
4. 設定更新
   └─ SettingsUpdater.updateSettings() でクラスタ状態を更新
5. リモートストアマイグレーション確認
   └─ 互換性モード変更時のリモートストアマイグレーション完了処理
6. 設定変更検出
   └─ 変更があった場合のみreroute処理を実行
7. reroute実行
   └─ AllocationService.reroute() でシャード再配置
8. レスポンス返却
   └─ 設定更新+reroute両方のACKを確認して返却
```

### フローチャート

```mermaid
flowchart TD
    A[Cluster Update Settings Request] --> B[Check Cluster Blocks]
    B --> C[Validate Settings]
    C --> D{Compatibility Mode Change?}
    D -->|Yes| E[Validate All Nodes Same Version/Type]
    D -->|No| F[Apply Settings via SettingsUpdater]
    E --> F
    F --> G{State Changed?}
    G -->|No| H[Return Response]
    G -->|Yes| I[Wait for ACK from all nodes]
    I --> J{Still Cluster Manager?}
    J -->|No| K[Return without reroute]
    J -->|Yes| L[Submit Reroute Task]
    L --> M[AllocationService.reroute]
    M --> N[Wait for Reroute ACK]
    N --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | 設定優先順位 | transient設定はpersistent設定より優先される | 設定解決時 |
| BR-50-02 | READ_ONLY設定例外 | READ_ONLYまたはREAD_ONLY_ALLOW_DELETE設定の変更はMETADATA_WRITEブロック中でも許可 | 設定が1つだけの場合 |
| BR-50-03 | 互換性モード変更制約 | 互換性モード変更時は全ノードが同一バージョンであること | REMOTE_STORE_COMPATIBILITY_MODE_SETTING変更時 |
| BR-50-04 | STRICT互換性モード制約 | STRICTモードへの切り替え時は全ノードが同一タイプ（全remote or 全non-remote） | STRICTモードへの切り替え時 |
| BR-50-05 | プライマリシャード制限 | CLUSTER_TOTAL_PRIMARY_SHARDS_PER_NODEはリモートストア有効クラスタでのみ使用可能 | 設定変更時 |
| BR-50-06 | 設定変更後reroute | 設定変更がシャード配置に影響する可能性があるため、変更後にrerouteを実行 | 設定が実際に変更された場合 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定更新 | ClusterState.Metadata (Settings) | UPDATE | transient/persistent設定をクラスタメタデータに保存 |
| 設定取得 | ClusterState.Metadata (Settings) | SELECT | 現在のクラスタ設定を取得 |

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

#### ClusterState.Metadata

| 操作 | 項目 | 更新値・取得条件 | 備考 |
|-----|------|-----------------|------|
| UPDATE | transientSettings | 指定された一時設定 | クラスタ再起動で消失 |
| UPDATE | persistentSettings | 指定された永続設定 | クラスタ再起動後も保持 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ActionRequestValidationException | transientとpersistentの両方が空 | 少なくとも一方に設定を指定 |
| - | ClusterBlockException | METADATA_WRITEブロック中（READ_ONLY設定変更以外） | クラスタブロックを解除 |
| - | SettingsException | 互換性モード変更時に全ノードが同一バージョンでない | 全ノードを同一バージョンにアップグレード |
| - | SettingsException | STRICTモード切替時に異種ノードが混在 | ノードタイプを統一 |
| - | IllegalArgumentException | CLUSTER_TOTAL_PRIMARY_SHARDS_PER_NODEが非リモートストアクラスタで指定 | リモートストア有効クラスタでのみ使用 |
| - | OpenSearchException | reroute失敗 | ログを確認し原因を特定 |

### リトライ仕様

クラスタマネージャタスクとしてスロットリングが適用され、リトライが行われる（clusterUpdateSettingTaskKeyで登録）。

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

設定更新はAckedClusterStateUpdateTaskとして原子的に実行される。設定更新とreroute は2つの別々のクラスタ状態更新タスクとして実行される。rerouteは設定変更が全ノードに適用された後に実行される。

## パフォーマンス要件

設定更新はIMEDIATEプライオリティで実行される。rerouteはURGENTプライオリティで実行される。

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

- クラスタ設定管理権限が必要
- セキュリティ関連設定（暗号化キーなど）はこのAPIでは変更できない場合がある
- READ_ONLY設定の変更を許可するため、ブロックの解除にこのAPIが使用される

## 備考

transient設定とpersistent設定の2種類があり、transient設定が優先される。transient設定はクラスタの完全再起動で失われるため、一時的な運用変更に使用し、恒久的な変更にはpersistent設定を使用する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClusterUpdateSettingsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/ClusterUpdateSettingsRequest.java` | transientSettingsとpersistentSettingsの2つのSettingsオブジェクトを保持 |
| 1-2 | ClusterUpdateSettingsResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/ClusterUpdateSettingsResponse.java` | acknowledged + 更新後のtransient/persistent設定 |
| 1-3 | ClusterGetSettingsRequest.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/ClusterGetSettingsRequest.java` | 設定取得リクエスト |
| 1-4 | ClusterGetSettingsResponse.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/ClusterGetSettingsResponse.java` | 設定取得レスポンス |

**読解のコツ**: ClusterUpdateSettingsRequestの**62-76行目**でObjectParserによるJSON解析ロジックを確認。transientとpersistentのキーでSettingsオブジェクトを受け取る。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TransportClusterUpdateSettingsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/TransportClusterUpdateSettingsAction.java` | 設定更新のメイン処理。バリデーション、状態更新、reroute の3段階処理を理解する |

**主要処理フロー**:
- **121-134行目**: checkBlockでMETADATA_WRITEブロックを確認。READ_ONLY設定変更の場合は例外的に許可
- **142-275行目**: clusterManagerOperationで設定更新タスクを発行
- **260-271行目**: executeメソッドでSettingsUpdater.updateSettings()を呼び出し
- **182-251行目**: onAllNodesAcked/onAckTimeoutでrerouteタスクを発行
- **284-296行目**: validateCompatibilityModeSettingRequestで互換性モード変更のバリデーション
- **330-358行目**: validateClusterTotalPrimaryShardsPerNodeSettingの検証

#### Step 3: 設定更新ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SettingsUpdater.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/SettingsUpdater.java` | 実際の設定更新ロジック。ClusterSettingsと連携してバリデーション・更新を実行 |

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

```
TransportClusterUpdateSettingsAction
    |
    +-- checkBlock() → METADATA_WRITEブロック確認
    |
    +-- clusterManagerOperation()
            |
            +-- AckedClusterStateUpdateTask #1 (設定更新)
            |       +-- validateClusterTotalPrimaryShardsPerNodeSetting()
            |       +-- validateCompatibilityModeSettingRequest()
            |       +-- SettingsUpdater.updateSettings()
            |       +-- checkAndFinalizeRemoteStoreMigration()
            |
            +-- onAllNodesAcked() → reroute判定
                    |
                    +-- AckedClusterStateUpdateTask #2 (reroute)
                            +-- AllocationService.reroute()
```

### データフロー図

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

ClusterUpdateSettingsRequest --> TransportClusterUpdateSettingsAction --> ClusterUpdateSettingsResponse
  (transient: {...},               |                                       (acknowledged, transient, persistent)
   persistent: {...})              +-> Validate settings
                                   +-> SettingsUpdater.updateSettings()
                                   +-> ClusterState update
                                   +-> AllocationService.reroute() (if changed)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TransportClusterUpdateSettingsAction.java | `server/src/main/java/org/opensearch/action/admin/cluster/settings/` | ソース | 設定更新トランスポートアクション |
| ClusterUpdateSettingsAction.java | 同上 | ソース | アクション定義 |
| ClusterUpdateSettingsRequest.java | 同上 | ソース | 設定更新リクエスト |
| ClusterUpdateSettingsResponse.java | 同上 | ソース | 設定更新レスポンス |
| SettingsUpdater.java | 同上 | ソース | 設定更新ロジック |
| ClusterGetSettingsRequest.java | 同上 | ソース | 設定取得リクエスト |
| ClusterGetSettingsResponse.java | 同上 | ソース | 設定取得レスポンス |
| ClusterSettings.java | `server/src/main/java/org/opensearch/common/settings/` | ソース | クラスタ設定管理 |
| AllocationService.java | `server/src/main/java/org/opensearch/cluster/routing/allocation/` | ソース | シャード再配置サービス |
