# 機能設計書 95-リモートクラスタ接続

## 概要

本ドキュメントは、OpenSearchにおけるクロスクラスタ検索のためのリモートクラスタ接続機能（RemoteClusterService）の設計を記述する。

### 本機能の処理概要

リモートクラスタ接続機能は、複数のOpenSearchクラスタ間で検索リクエストを横断的に実行するためのクロスクラスタ検索（CCS: Cross-Cluster Search）の基盤を提供する。

**業務上の目的・背景**：大規模な組織では、地理的分散や運用上の理由から複数のOpenSearchクラスタを運用することが一般的である。リモートクラスタ接続により、これらの分散クラスタに対して単一のクエリで横断的な検索を可能にし、データのサイロ化を防ぐ。

**機能の利用シーン**：複数データセンターにまたがるログ分析、異なるチームが運用する別クラスタのデータに対する横断検索、地理的に分散したクラスタへの統合アクセスで使用される。

**主要な処理内容**：
1. リモートクラスタ接続の設定と管理 - クラスタエイリアスを使ったリモートクラスタの登録
2. シードノードへの接続確立 - リモートクラスタのゲートウェイノードへの接続
3. インデックスのグルーピング - クラスタエイリアスプレフィックスによるインデックス振り分け
4. 接続プール管理 - リモートクラスタへの接続の維持とフェイルオーバー
5. skip_unavailable制御 - 利用不可クラスタのスキップ判定

**関連システム・外部連携**：TransportServiceを通じてリモートクラスタとTCP接続を確立する。RemoteClusterConnectionが各リモートクラスタへの接続を管理する。

**権限による制御**：ノードがremote_cluster_clientロールを持つ場合のみリモートクラスタ接続が有効になる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 98 | リモートクラスタ情報 | 主機能 | 設定されたリモートクラスタの情報を返す処理 |

## 機能種別

データ連携（クロスクラスタ通信管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cluster.remote.initial_connect_timeout | TimeValue | No | 初期接続タイムアウト（デフォルト30秒） | 正の値 |
| cluster.remote.node.attr | String | No | リモートクラスタのゲートウェイノード選択属性 | - |
| cluster.remote.connect | Boolean | No | リモートクラスタ接続の有効/無効（非推奨） | デフォルトtrue |
| cluster.remote.{alias}.skip_unavailable | Boolean | No | クラスタ利用不可時のスキップ | デフォルトfalse、動的変更可能 |
| cluster.remote.{alias}.transport.ping_schedule | TimeValue | No | Ping送信間隔 | 動的変更可能 |
| cluster.remote.{alias}.transport.compress | Boolean | No | 通信圧縮の有効/無効 | 動的変更可能 |

### 入力データソース

opensearch.ymlまたはクラスタ設定APIからの動的設定。検索リクエスト内のクラスタエイリアスプレフィックス（例: "remote_cluster:index_name"）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Transport.Connection | Connection | リモートクラスタへの確立された接続 |
| OriginalIndices | Map<String, OriginalIndices> | クラスタ別にグルーピングされたインデックス |
| RemoteClusterInfo | Collection<RemoteConnectionInfo> | リモートクラスタの接続状態情報 |

### 出力先

検索コーディネータ等の上位レイヤーにリモートクラスタ接続を提供する。

## 処理フロー

### 処理シーケンス

```
1. RemoteClusterService初期化
   └─ 設定からリモートクラスタ定義を読み込み
   └─ DiscoveryNode.isRemoteClusterClient()で有効判定
2. listenForUpdates()で設定変更を監視
   └─ クラスタ設定の動的変更に対応
3. 検索リクエスト時にgroupIndices()
   └─ インデックス名をクラスタエイリアスで分類
   └─ "remote:index"形式をパースしてクラスタ別に振り分け
4. ensureConnected()で接続を確保
   └─ RemoteClusterConnectionを通じて接続確立
5. getConnection()で接続取得
   └─ 指定ノードへの接続を返却
```

### フローチャート

```mermaid
flowchart TD
    A[検索リクエスト受信] --> B{CCS有効?}
    B -->|Yes| C[groupIndices]
    B -->|No| D[ローカルクラスタのみ]
    C --> E[クラスタエイリアスで振り分け]
    E --> F{リモートクラスタ?}
    F -->|Yes| G[ensureConnected]
    F -->|No| D
    G --> H{接続成功?}
    H -->|Yes| I[getConnection]
    H -->|No| J{skip_unavailable?}
    J -->|Yes| K[スキップ]
    J -->|No| L[エラー]
    I --> M[リモートクエリ実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-95-01 | ロール要件 | remote_cluster_clientロールが必要 | リモートクラスタ接続時 |
| BR-95-02 | クラスタエイリアス構文 | "alias:index"形式でリモートインデックスを指定 | CCS検索時 |
| BR-95-03 | skip_unavailable | trueの場合、利用不可クラスタをエラーとせずスキップ | リモートクラスタ接続失敗時 |
| BR-95-04 | 接続タイムアウト | 初期接続は30秒でタイムアウト（デフォルト） | 初回接続時 |
| BR-95-05 | ゲートウェイノード選択 | node.attr指定時、該当属性を持つノードのみ接続先候補 | node.attr設定時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし（通信管理のみ） |

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NoSuchRemoteClusterException | 接続エラー | 未登録のクラスタエイリアスを指定 | 正しいクラスタエイリアスを使用 |
| IllegalArgumentException | 設定エラー | remote_cluster_clientロールのないノードで接続試行 | ノードロールを確認 |
| ConnectTransportException | 接続エラー | リモートクラスタへの接続タイムアウト | ネットワーク設定を確認、skip_unavailableの検討 |

### リトライ仕様

RemoteClusterConnectionが内部的に接続リトライを管理する。

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

トランザクション管理は不要。リモートクラスタ接続は接続プール管理のみ。

## パフォーマンス要件

- リモートクラスタへの接続は永続的に保持され、リクエスト毎の接続確立コストを回避
- Ping送信で接続の健全性を監視
- 通信圧縮オプションにより帯域幅を節約可能

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

- TLS/SSLによるクラスタ間通信の暗号化
- ゲートウェイノードのフィルタリングにより接続先ノードを限定可能
- remote_cluster_clientロールによるアクセス制御

## 備考

- cluster.remote.connectは非推奨（Deprecated）設定
- クロスクラスタ検索では "cluster_alias:index_name" 構文を使用
- LOCAL_CLUSTER_GROUP_KEY（空文字列）はローカルクラスタを表す

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RemoteClusterAware.java | `server/src/main/java/org/opensearch/transport/RemoteClusterAware.java` | RemoteClusterServiceの基底クラス、クラスタエイリアス解析 |
| 1-2 | RemoteClusterConnection.java | `server/src/main/java/org/opensearch/transport/RemoteClusterConnection.java` | 個別リモートクラスタへの接続管理 |

**読解のコツ**: RemoteClusterAwareのgroupClusterIndices()メソッドがインデックス名のクラスタ振り分けロジックの核心。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RemoteClusterService.java | `server/src/main/java/org/opensearch/transport/RemoteClusterService.java` | メインクラス |

**主要処理フロー**:
1. **80行目**: RemoteClusterService定義 - RemoteClusterAwareを継承、Closeableを実装
2. **87-91行目**: REMOTE_INITIAL_CONNECTION_TIMEOUT_SETTING - 30秒デフォルト
3. **99-101行目**: REMOTE_NODE_ATTRIBUTE - ゲートウェイノード属性フィルタ
4. **109-114行目**: ENABLE_REMOTE_CLUSTERS - 有効/無効設定（非推奨）
5. **116-120行目**: REMOTE_CLUSTER_SKIP_UNAVAILABLE - Affix設定
6. **155-159行目**: コンストラクタ - enabled判定
7. **172-190行目**: groupIndices() - インデックスのクラスタ振り分け
8. **212-214行目**: getConnection() - リモートノードへの接続取得

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

```
RemoteClusterService
    |
    +-- groupIndices(indicesOptions, indices, indexExists)
    |    +-- isCrossClusterSearchEnabled()
    |    +-- groupClusterIndices()  [RemoteClusterAware]
    |
    +-- ensureConnected(clusterAlias, listener)
    |    +-- getRemoteClusterConnection(cluster)
    |    +-- RemoteClusterConnection.ensureConnected()
    |
    +-- getConnection(node, cluster)
    |    +-- getRemoteClusterConnection(cluster)
    |    +-- RemoteClusterConnection.getConnection(node)
    |
    +-- isSkipUnavailable(clusterAlias)
         +-- getRemoteClusterConnection(cluster)
         +-- RemoteClusterConnection.isSkipUnavailable()
```

### データフロー図

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

検索リクエスト ──────> RemoteClusterService ──────> Transport.Connection
  "remote:index"      groupIndices()                     |
                      ensureConnected()             リモートクラスタ
                      getConnection()               検索結果
                           |
                      RemoteClusterConnection
                           |
                      TransportService
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RemoteClusterService.java | `server/src/main/java/org/opensearch/transport/RemoteClusterService.java` | ソース | リモートクラスタ接続のメインサービス |
| RemoteClusterAware.java | `server/src/main/java/org/opensearch/transport/RemoteClusterAware.java` | ソース | クラスタエイリアス解析の基底クラス |
| RemoteClusterConnection.java | `server/src/main/java/org/opensearch/transport/RemoteClusterConnection.java` | ソース | 個別リモートクラスタへの接続管理 |
| RemoteConnectionInfo.java | `server/src/main/java/org/opensearch/transport/RemoteConnectionInfo.java` | ソース | リモート接続情報 |
| NoSuchRemoteClusterException.java | `server/src/main/java/org/opensearch/transport/NoSuchRemoteClusterException.java` | ソース | 未登録クラスタ例外 |
| TransportService.java | `server/src/main/java/org/opensearch/transport/TransportService.java` | ソース | トランスポートサービス基盤 |
