# バッチ設計書 16-ResourceUsageCollectorService

## 概要

本ドキュメントは、ノードのリソース使用状況を定期的に収集するバッチ処理「ResourceUsageCollectorService」の設計仕様を記載する。

### 本バッチの処理概要

ResourceUsageCollectorServiceは、ローカルノードのCPU・メモリ・IO使用率をNodeResourceUsageTrackerから定期的に取得し、ノードリソース使用統計（nodeIdToResourceUsageStats）として蓄積するバッチ処理である。コーディネータノードがスロットリングやランキングに利用するための統計情報を提供する。

**業務上の目的・背景**：OpenSearchクラスタでは、各ノードのリソース使用状況を把握することが、検索リクエストのルーティング最適化やバックプレッシャー制御に不可欠である。本バッチはローカルノードのリソース使用統計を1秒間隔で収集し、コーディネータノードが各ノードのリソース状況を把握できるようにする。これにより、過負荷のノードへのリクエスト集中を防ぎ、クラスタ全体のパフォーマンスと安定性を向上させる。

**バッチの実行タイミング**：固定間隔1000ミリ秒（1秒）で定期実行。doStart()時にscheduleWithFixedDelayで開始される。

**主要な処理内容**：
1. nodeResourceUsageTracker.isReady()でトラッカーの準備完了を確認
2. clusterService.isStateInitialised()でクラスタ状態の初期化完了を確認
3. ローカルノードIDを取得
4. NodeResourceUsageTrackerからCPU使用率、メモリ使用率、IO使用統計を取得
5. collectNodeResourceUsageStats()でnodeIdToResourceUsageStatsマップに登録

**前後の処理との関連**：NodeResourceUsageTracker（No.17 AbstractAverageUsageTrackerの具体実装群）がリソース使用量の移動平均を計算し、本バッチがそれを収集する。収集された統計はNodeStatsレスポンスに含まれ、InternalClusterInfoService（No.18）でクラスタ全体の情報として集約される。また、ClusterStateListenerを実装しており、ノード離脱時に該当ノードの統計を削除する。

**影響範囲**：各ノードのリソース使用統計の収集に影響。収集データはノード統計API、検索バックプレッシャー、ワークロードグループ管理で使用される。

## バッチ種別

リソース監視 / 統計収集

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 定期実行（1000ミリ秒=1秒間隔、固定） |
| 実行時刻 | ノード起動後、1秒間隔で繰り返し実行 |
| 実行曜日 | 該当なし（常時） |
| 実行日 | 該当なし（常時） |
| トリガー | ThreadPool.scheduleWithFixedDelay（Names.GENERIC） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| NodeResourceUsageTrackerが準備完了であること | isReady()がtrueを返すこと |
| クラスタ状態が初期化済みであること | clusterService.isStateInitialised()がtrueであること |

### 実行可否判定

collectLocalNodeResourceUsageStats()メソッド内で、nodeResourceUsageTracker.isReady()とclusterService.isStateInitialised()の両方がtrueの場合にのみ統計を収集する。条件を満たさない場合は何もしない（スキップ）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| REFRESH_INTERVAL_IN_MILLIS | long | - | 1000 | リフレッシュ間隔（コード内固定値） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| NodeResourceUsageTracker | API呼び出し | CPU・メモリ・IO使用率の移動平均 |
| ClusterService | API呼び出し | クラスタ状態、ローカルノードID |
| System.currentTimeMillis() | JVM内部API | タイムスタンプ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| nodeIdToResourceUsageStats | ConcurrentMap<String, NodeResourceUsageStats> | ノードID別リソース使用統計 |

### 出力ファイル仕様

ファイル出力はなし。

## 処理フロー

### 処理シーケンス

```
1. スケジュールされたラムダが実行
   └─ collectLocalNodeResourceUsageStats()を呼び出し
2. 事前条件チェック
   ├─ nodeResourceUsageTracker.isReady() の確認
   └─ clusterService.isStateInitialised() の確認
3. 条件を満たす場合
   ├─ ローカルノードIDを取得
   ├─ 現在時刻をタイムスタンプとして取得
   ├─ メモリ使用率を取得
   ├─ CPU使用率を取得
   ├─ IO使用統計を取得
   └─ collectNodeResourceUsageStats()でマップに登録/更新
4. マップの登録/更新
   ├─ 新規ノード: 新しいNodeResourceUsageStatsを作成
   └─ 既存ノード: 既存オブジェクトのフィールドを更新
```

### フローチャート

```mermaid
flowchart TD
    A[スケジュール実行] --> B[collectLocalNodeResourceUsageStats]
    B --> C{isReady AND isStateInitialised?}
    C -->|No| D[スキップ]
    C -->|Yes| E[ローカルノードID取得]
    E --> F[CPU/メモリ/IO使用率取得]
    F --> G[nodeIdToResourceUsageStats更新]
    G --> H[処理完了]
    D --> H
```

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

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

本バッチはデータベース操作を行わない。インメモリのConcurrentMapの操作のみを行う。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | Exception | collectLocalNodeResourceUsageStats()の例外 | 警告ログ"failure in ResourceUsageCollectorService"を出力し処理継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 明示的なリトライなし（定期実行により自動再試行） |
| リトライ間隔 | 1秒（固定） |
| リトライ対象エラー | すべてのException |

### 障害時対応

例外発生時は警告ログが出力され、次回実行で自動的に再試行される。統計が更新されない場合、コーディネータノードは古いデータを使用するか、該当ノードの統計がない状態で動作する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（ConcurrentMap.computeで原子的に更新） |
| コミットタイミング | 即時 |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | ローカルノード1件（リモートノードはノード統計レスポンスで更新） |
| 目標処理時間 | マイクロ秒単位 |
| メモリ使用量上限 | クラスタノード数 x NodeResourceUsageStatsオブジェクトサイズ |

## 排他制御

nodeIdToResourceUsageStatsはConcurrentMapで実装されており、スレッドセーフに操作される。collectNodeResourceUsageStats()ではConcurrentMap.compute()を使用して原子的に更新を行う。ClusterStateListenerのclusterChanged()は別スレッドから呼ばれるが、ConcurrentMapにより安全にノード削除が可能。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 警告ログ | 例外発生時 | "failure in ResourceUsageCollectorService" + 例外詳細 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| リソース使用統計の更新頻度 | 1秒間隔 | ノード統計API |
| CPU使用率 | アプリケーション依存 | ノード統計API |
| メモリ使用率 | アプリケーション依存 | ノード統計API |

## 備考

- 実装ファイル: `server/src/main/java/org/opensearch/node/ResourceUsageCollectorService.java`
- AbstractLifecycleComponentを継承し、ClusterStateListenerを実装している
- リフレッシュ間隔（1000ミリ秒）はコード内にハードコードされた定数であり、設定ファイルからの変更はできない
- リモートノードのリソース使用統計はInternalClusterInfoServiceのNodesStatsリクエストのレスポンスとして収集される
- ノード離脱時はclusterChanged()イベントでnodeIdToResourceUsageStatsから削除される
