# 機能設計書 123-オートフォースマージ

## 概要

本ドキュメントは、OpenSearchにおける条件に基づく自動的なセグメントフォースマージ機能の設計を記載する。

### 本機能の処理概要

本機能は、インデックスのトランスログ経過時間やセグメント数などの条件を監視し、ノードのリソース状況に基づいて自動的にフォースマージを実行するバックグラウンド機能である。

**業務上の目的・背景**：時系列データのようにホットからウォームに移行するインデックスでは、書き込みが停止した後もセグメントが多数存在し検索パフォーマンスが低下する。手動でのフォースマージは運用負荷が高いため、条件に基づく自動化が求められる。本機能はリモートストアが有効なクラスタのデータノードで、ウォーム候補インデックスに対して自動的にフォースマージを実行する。

**機能の利用シーン**：リモートストア有効環境でのウォームティア移行時のセグメント最適化、書き込み停止後のインデックス自動最適化、運用者の手動介入を不要にするためのバックグラウンド処理として利用される。

**主要な処理内容**：
1. 定期スケジューラによる条件チェックの実行
2. ノードの設定・リソース（CPU、JVM、ディスク）の検証
3. 対象シャードの選定（トランスログ経過時間、セグメント数による判定）
4. 対象シャードに対するフォースマージの非同期実行

**関連システム・外部連携**：MonitorServiceからOS/JVM/ディスクのメトリクスを取得。リモートクラスタ状態設定の確認にRemoteClusterStateServiceの設定を使用。

**権限による制御**：クラスタ設定`cluster.auto_force_merge.enabled`によるオン/オフ制御。ノード設定で各種閾値を制御可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はバックグラウンド処理であり、直接的な画面操作はない |

## 機能種別

バックグラウンド処理（自動最適化）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cluster.auto_force_merge.enabled | boolean | No | 機能の有効/無効（デフォルト: false） | true/false |
| node.auto_force_merge.segment.count | int | No | セグメント数閾値（デフォルト: 1） | 1以上 |
| node.auto_force_merge.merge_delay | TimeValue | No | シャード間の待機時間（デフォルト: 15s） | 1s-60s |
| node.auto_force_merge.scheduler.interval | TimeValue | No | スケジューラ間隔（デフォルト: 30m） | 1s-24h |
| node.auto_force_merge.translog.age | TimeValue | No | トランスログ経過時間閾値（デフォルト: 30m） | 1s-24h |
| node.auto_force_merge.cpu.threshold | double | No | CPU使用率閾値（デフォルト: 75%） | 10-100 |
| node.auto_force_merge.disk.threshold | double | No | ディスク使用率閾値（デフォルト: 85%） | 10-100 |
| node.auto_force_merge.jvm.threshold | double | No | JVMメモリ使用率閾値（デフォルト: 75%） | 10-100 |
| node.auto_force_merge.threads.concurrency_multiplier | int | No | 同時実行倍率（デフォルト: 2） | 2-5 |

### 入力データソース

クラスタ設定、ノード設定、OSメトリクス、JVMメトリクス、ディスクメトリクス

## 出力仕様

### 出力データ

本機能は直接的なAPIレスポンスを返さない。テレメトリメトリクスとして以下を出力する。

| 項目名 | 型 | 説明 |
|--------|-----|------|
| scheduler_execution_time | Histogram | スケジューラ実行時間 |
| merges_triggered | Counter | トリガーされたマージ数 |
| merges_failed | Counter | 失敗したマージ数 |
| segment_count | Counter | マージ前のセグメント数 |
| shard_size | Counter | シャードサイズ |
| shard_merge_latency | Histogram | シャードマージ所要時間 |

### 出力先

テレメトリメトリクス（AutoForceMergeMetrics経由）

## 処理フロー

### 処理シーケンス

```
1. AsyncForceMergeTask定期実行
   └─ ConfigurationValidator.validate()
2. 設定検証
   └─ AutoForceMerge有効、リモートストア有効、データノード確認
3. ウォームノード存在確認
   └─ クラスタにウォームノードが存在するか確認
4. ノードリソース検証
   └─ CPU使用率、JVMメモリ、ディスク使用量、スレッド利用可能性チェック
5. 対象シャード選定
   └─ プライマリシャード、非システムインデックス、状態STARTED
   └─ auto_forcemerge有効、トランスログ経過時間、セグメント数チェック
6. フォースマージ実行
   └─ FORCE_MERGEスレッドプールで非同期実行
   └─ シャード間にmerge_delay分の待機
```

### フローチャート

```mermaid
flowchart TD
    A[AsyncForceMergeTask起動] --> B{設定検証}
    B -->|無効/条件未達| C[スキップ]
    B -->|有効| D{ウォームノード存在?}
    D -->|No| C
    D -->|Yes| E{ノードリソースOK?}
    E -->|No| C
    E -->|Yes| F[対象シャード選定]
    F --> G{フォースマージ対象あり?}
    G -->|No| H[処理完了]
    G -->|Yes| I[非同期フォースマージ実行]
    I --> J[merge_delay待機]
    J --> K{次のシャードあり?}
    K -->|Yes| E
    K -->|No| H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | リモートストア必須 | リモートクラスタ状態が有効でないと動作しない | 常時 |
| BR-002 | データノード限定 | データノード（非ウォームノード）でのみ実行 | 常時 |
| BR-003 | ウォームノード必須 | クラスタにウォームノードが1つ以上存在する必要がある | 常時 |
| BR-004 | プライマリシャードのみ | フォースマージはプライマリシャードに対してのみ実行 | 常時 |
| BR-005 | システムインデックス除外 | "."で始まるインデックスは対象外 | 常時 |
| BR-006 | 同時実行数制限 | max(1, allocatedProcessors/8) * concurrencyMultiplier | 常時 |

### 計算ロジック

- 最大同時マージ数 = max(1, allocatedProcessors / 8) * concurrencyMultiplier
- シャードソート順: トランスログのearliest_last_modified_ageの昇順（最も古いものから優先）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| フォースマージ | Luceneセグメント | UPDATE | 複数セグメントを1つに統合 |

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

Luceneレベルでセグメントの統合（マージ）が行われる。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | マージ失敗 | フォースマージ中の例外 | mergesFailed メトリクスをインクリメントし、ログ出力 |
| InterruptedException | 割り込み | シャード間待機中の割り込み | ループを中断してログ出力 |

### リトライ仕様

個別シャードのマージ失敗はログとメトリクスに記録され、次回のスケジューラ実行時に再試行される。

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

Luceneレベルのマージ操作。アトミックなセグメント切り替えはLuceneが管理する。

## パフォーマンス要件

FORCE_MERGEスレッドプール（固定、allocatedProcessors/8スレッド）で実行。CPU/JVM/ディスクの閾値チェックにより、リソース逼迫時は自動的にスキップされる。

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

クラスタ設定変更権限が必要。ノードレベル設定はopensearch.ymlで管理。

## 備考

本機能はexperimental/internalとして位置づけられている。

---

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

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

### 推奨読解順序

#### Step 1: 設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ForceMergeManagerSettings.java | `server/src/main/java/org/opensearch/index/autoforcemerge/ForceMergeManagerSettings.java` | 全設定項目の定義とデフォルト値。動的設定更新の仕組み |

**主要処理フロー**:
- **40-45行目**: AUTO_FORCE_MERGE_SETTING（有効/無効）
- **50-56行目**: SEGMENT_COUNT_FOR_AUTO_FORCE_MERGE（セグメント数閾値=1）
- **61-68行目**: MERGE_DELAY_BETWEEN_SHARDS（15秒）
- **73-80行目**: SCHEDULER_INTERVAL（30分）
- **85-92行目**: TRANSLOG_AGE（30分）
- **97-128行目**: CPU/Disk/JVM閾値
- **133-140行目**: CONCURRENCY_MULTIPLIER（2）

#### Step 2: メインクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AutoForceMergeManager.java | `server/src/main/java/org/opensearch/index/autoforcemerge/AutoForceMergeManager.java` | ライフサイクル管理、3段階バリデーション、フォースマージ実行 |

**主要処理フロー**:
- **98-107行目**: doStart()でタスク・バリデータ・リソーストラッカー初期化
- **127-141行目**: triggerForceMerge()がメインのトリガーロジック
- **166-181行目**: executeForceMergeOnShards()でシャード単位の実行ループ
- **183-230行目**: executeForceMergeForShard()でFORCE_MERGEスレッドプールでの非同期実行
- **243-256行目**: getShardsBasedOnSorting()で対象シャードのフィルタリングとソート
- **285-339行目**: ConfigurationValidator内部クラスで設定検証
- **346-428行目**: NodeValidator内部クラスでリソースチェック
- **435-475行目**: ShardValidator内部クラスでシャード条件チェック

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

```
AutoForceMergeManager (AbstractLifecycleComponent)
    |
    +-- AsyncForceMergeTask (定期タスク)
    |       |
    |       +-- ConfigurationValidator.validate()
    |       +-- triggerForceMerge()
    |               |
    |               +-- isValidForForceMerge()
    |               |       +-- ConfigurationValidator.hasWarmNodes()
    |               |       +-- NodeValidator.validate()
    |               |
    |               +-- executeForceMergeOnShards()
    |                       +-- getShardsBasedOnSorting()
    |                       |       +-- ShardValidator.validate()
    |                       +-- executeForceMergeForShard()
    |                               +-- IndexShard.forceMerge()
    |
    +-- ForceMergeManagerSettings (設定管理)
    +-- ResourceTrackerProvider.ResourceTrackers (リソース監視)
    +-- AutoForceMergeMetrics (メトリクス)
```

### データフロー図

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

クラスタ設定      -->  ConfigurationValidator  -->  有効/無効判定
OSメトリクス      -->  NodeValidator           -->  リソースチェック
JVMメトリクス     -->  NodeValidator           -->  リソースチェック
ディスクメトリクス -->  NodeValidator           -->  リソースチェック
シャード情報      -->  ShardValidator          -->  対象シャード選定
                      IndexShard.forceMerge() -->  テレメトリメトリクス
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AutoForceMergeManager.java | `server/src/main/java/org/opensearch/index/autoforcemerge/` | ソース | メイン管理クラス |
| ForceMergeManagerSettings.java | 同上 | ソース | 設定管理 |
| AutoForceMergeMetrics.java | 同上 | ソース | テレメトリメトリクス |
| ResourceTrackerProvider.java | 同上 | ソース | リソース監視ヘルパー |
