# アーキテクチャ設計書

## 概要

本ドキュメントは、OpenSearchプロジェクトのアーキテクチャ設計を記載する。OpenSearchは、Apache Luceneを基盤とした分散型検索・分析エンジンであり、RESTful APIを介してデータのインデックス作成、検索、分析機能を提供する。プラグインアーキテクチャにより高い拡張性を持ち、クラスタ構成によるスケーラビリティと高可用性を実現している。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図](./アーキテクチャ構成図.md) を参照。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| クライアントアプリケーション | REST API (HTTP/HTTPS) | ドキュメントのCRUD操作、検索クエリ実行 |
| OpenSearch Dashboards | REST API (HTTP/HTTPS) | 可視化・管理UI |
| AWS S3 / Azure Blob / GCS | プラグイン経由のHTTPS | スナップショットリポジトリ (repository-s3, repository-azure, repository-gcs) |
| Apache Kafka | プラグイン経由 (ingestion-kafka) | データインジェスチョン |
| AWS Kinesis | プラグイン経由 (ingestion-kinesis) | データインジェスチョン |
| AWS KMS | プラグイン経由 (crypto-kms) | 暗号鍵管理 |
| EC2 / GCE / Azure | プラグイン経由 (discovery-ec2, discovery-gce, discovery-azure-classic) | ノードディスカバリ |
| HDFS | プラグイン経由 (repository-hdfs) | スナップショットリポジトリ |
| OpenTelemetry Collector | プラグイン経由 (telemetry-otel) | テレメトリデータ送信 |

## レイヤー構成

### アーキテクチャスタイル

OpenSearchは **モジュラー・プラグインアーキテクチャ** を採用している。コアサーバーがフレームワークとしての基盤を提供し、多数のプラグインインターフェースを通じて機能拡張を可能にする設計である。内部的には、REST API層、アクション/トランスポート層、インデックス/検索エンジン層、ストレージ層という階層構造を持つ。Guiceによる依存性注入(DI)フレームワークを利用して各モジュールの結合を管理する。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| REST API層 | HTTP経由のリクエスト受付、ルーティング、レスポンス返却 | `RestController`, `BaseRestHandler`, `HttpServerTransport`, `RestChannel` |
| Action/Transport層 | ビジネスロジック実行、ノード間通信、アクション分配 | `ActionModule`, `TransportService`, `TransportAction`, `NodeClient` |
| Cluster管理層 | クラスタ状態管理、ノードディスカバリ、シャード割当 | `ClusterService`, `ClusterModule`, `Coordinator`, `DiscoveryModule` |
| Index/Search層 | ドキュメントのインデックス作成・検索・集計 | `IndicesService`, `IndexService`, `SearchService`, `SearchModule` |
| Storage/Engine層 | Luceneへのデータ永続化、セグメント管理 | `Engine`, `IndexShard`, `Store`, Luceneライブラリ群 |
| Plugin層 | 各種拡張ポイントの提供とプラグインライフサイクル管理 | `PluginsService`, `Plugin`, 各種Plugin Interface |

### レイヤー間の依存関係ルール

- REST API層はAction/Transport層に依存し、`NodeClient`を介してアクションを実行する
- Action/Transport層はIndex/Search層およびCluster管理層に依存する
- Index/Search層はStorage/Engine層(Lucene)に依存する
- Plugin層は全レイヤーに対して拡張ポイントを提供する横断的な層であり、各レイヤーのインターフェースを実装する形で機能追加が行われる
- 下位層が上位層に依存することは原則として禁止されている

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| server (コア) | OpenSearchの中核機能すべて | `server/` |
| client | REST/Java APIクライアント | `client/rest`, `client/rest-high-level`, `client/sniffer` |
| libs | 共有ライブラリ群 | `libs/common`, `libs/core`, `libs/x-content`, `libs/geo`, `libs/compress`, `libs/cli`, `libs/ssl-config`, `libs/telemetry`, `libs/netty4`, `libs/nio`, `libs/plugin-classloader`, `libs/secure-sm`, `libs/agent-sm`, `libs/dissect`, `libs/grok`, `libs/task-commons` |
| modules (バンドルモジュール) | デフォルトで同梱される機能拡張 | `modules/transport-netty4`, `modules/lang-painless`, `modules/ingest-common`, `modules/analysis-common`, `modules/reindex`, `modules/transport-grpc` 等 |
| plugins (オプションプラグイン) | 追加インストール可能な機能拡張 | `plugins/discovery-ec2`, `plugins/repository-s3`, `plugins/analysis-icu`, `plugins/telemetry-otel` 等 |
| sandbox | 実験的機能 | `sandbox/libs`, `sandbox/modules`, `sandbox/plugins` |
| distribution | パッケージング・配布 | `distribution/archives`, `distribution/docker`, `distribution/packages`, `distribution/tools` |
| test | テストフレームワーク | `test/framework`, `test/fixtures` |
| benchmarks | パフォーマンスベンチマーク | `benchmarks/` |
| buildSrc | ビルドツール・Gradleプラグイン | `buildSrc/` (build-tools) |

### パッケージ構造

```
server/src/main/java/org/opensearch/
├── action/          # アクション定義とトランスポートアクション実装
│   └── admin/       # クラスタ管理・インデックス管理アクション
├── bootstrap/       # ノード起動・BootstrapCheck
├── cluster/         # クラスタ状態・メタデータ・ルーティング管理
│   ├── coordination/ # Raft的合意アルゴリズム (Coordinator)
│   ├── metadata/    # インデックス・テンプレートメタデータ
│   ├── routing/     # シャードルーティング・割当
│   └── service/     # ClusterService
├── common/          # 共通ユーティリティ・設定管理・DI(Guice)
├── crypto/          # 暗号化ハンドラ
├── discovery/       # ノードディスカバリ
├── env/             # 環境設定・ノード環境
├── extensions/      # 拡張機能マネージャ
├── gateway/         # ゲートウェイ(クラスタ状態永続化)
│   └── remote/      # リモートクラスタ状態管理
├── http/            # HTTP/HTTPSサーバー
├── identity/        # 認証・認可 (IdentityService)
├── index/           # インデックス管理
│   ├── analysis/    # テキスト解析
│   ├── codec/       # Luceneコーデック
│   ├── engine/      # インデックスエンジン
│   ├── mapper/      # フィールドマッピング
│   └── store/       # ストア (ローカル/リモート)
├── indices/         # インデックス群管理 (IndicesService)
├── ingest/          # インジェストパイプライン
├── lucene/          # Luceneユーティリティ
├── monitor/         # JVM/OS/FS監視
├── node/            # ノードライフサイクル (Node.java)
├── persistent/      # 永続タスク
├── plugins/         # プラグインシステム
├── ratelimitting/   # レート制限・アドミッション制御
├── repositories/    # スナップショットリポジトリ
├── rest/            # REST APIハンドラ
│   └── action/      # 個別REST APIアクション
├── script/          # スクリプティングエンジン
├── search/          # 検索エンジン
│   ├── aggregations/ # 集計機能
│   ├── pipeline/    # 検索パイプライン
│   ├── fetch/       # Fetchフェーズ
│   └── query/       # Queryフェーズ
├── snapshots/       # スナップショット管理
├── tasks/           # タスク管理
├── telemetry/       # テレメトリ
├── threadpool/      # スレッドプール管理
├── transport/       # ノード間通信 (TCP)
└── wlm/             # ワークロード管理
```

### コンポーネント依存関係

主要コンポーネント間の依存関係は以下の通りである。

- `Node` は全てのモジュール（`ActionModule`, `ClusterModule`, `IndicesModule`, `SearchModule`, `NetworkModule`, `DiscoveryModule`, `GatewayModule`, `RepositoriesModule`, `SettingsModule`, `ScriptModule`, `AnalysisModule`, `TelemetryModule`, `CacheModule`）を初期化し、Guice Injectorを通じてコンポーネントをワイヤリングする (`server/src/main/java/org/opensearch/node/Node.java` 行494)
- `ActionModule` はREST APIハンドラとTransportActionの登録を管理する (`server/src/main/java/org/opensearch/action/ActionModule.java`)
- `TransportService` は `Transport`（実体はNetty4Transport等）を利用してノード間通信を行う (`server/src/main/java/org/opensearch/transport/TransportService.java`)
- `ClusterService` はクラスタ状態の管理と更新通知を担う (`server/src/main/java/org/opensearch/cluster/service/`)
- `IndicesService` は複数の `IndexService` を管理し、各IndexServiceは `IndexShard` を管理する

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| 全文検索エンジン | Apache Lucene | Lucene Bundles (server/build.gradle 行80) | コアインデックス・検索エンジン。セグメントベースの転置インデックスによる全文検索 |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| 内蔵キャッシュ (OpenSearch) | - | ノードクエリキャッシュ、リクエストキャッシュ、フィールドデータキャッシュ | 設定依存 |
| Ehcache (プラグイン) | プラグイン依存 | ディスクベースキャッシュ (cache-ehcache プラグイン) | 設定依存 |
| CacheModule | - | キャッシュプラグインの統合管理 (`common/cache/module/CacheModule`) | - |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| 該当なし (内蔵トランスポート) | - | ノード間通信はカスタムTCPプロトコルで実装。外部MQとの連携はIngestion系プラグインで対応 |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Apache Lucene | server/build.gradle で管理 | 転置インデックス、BKDツリー、KNNベクトル検索等のコアデータ構造と検索アルゴリズム |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| Netty 4 | modules/transport-netty4 | HTTP/TCPサーバー・クライアント実装。非同期I/O |
| Google Guice | server内蔵 (`common/inject/`) | 依存性注入フレームワーク |
| Log4j 2 | server/build.gradle 行98-100 | ロギングフレームワーク |
| JNA (Java Native Access) | server/build.gradle 行109 | OS固有機能（mlockall等）へのアクセス |
| Google Protobuf | server/build.gradle 行119 | シリアライズ (gRPCトランスポート等) |
| Project Reactor | server/build.gradle 行115-116 | リアクティブストリーム処理 |
| T-Digest / HdrHistogram | server/build.gradle 行89-91 | パーセンタイル集計 |
| Spatial4j / JTS | server/build.gradle 行94-95 | 地理空間検索 |
| Joda-Time | server/build.gradle 行86 | 日時処理（レガシー互換） |
| RoaringBitmap | server/build.gradle 行123 | ビットマップベースの集合演算 |
| Apache Arrow | libs/arrow, plugins/arrow-flight-rpc | カラムナーデータフォーマット・Flight RPC |

## データフロー

### リクエスト処理の流れ

OpenSearchにおけるRESTリクエストの処理フローは以下の通りである。

1. **HTTP受信**: クライアントからのHTTPリクエストを `HttpServerTransport`（実体は`Netty4HttpServerTransport`）が受信する (`server/src/main/java/org/opensearch/http/AbstractHttpServerTransport.java`)
2. **REST ルーティング**: `RestController` がリクエストURIとHTTPメソッドに基づいて適切な `RestHandler` にルーティングする。`PathTrie` によるURL解決が行われる (`server/src/main/java/org/opensearch/rest/RestController.java`)
3. **RestHandler処理**: 該当する `BaseRestHandler` のサブクラスがリクエストをパースし、内部の `ActionRequest` オブジェクトを構築する
4. **NodeClient実行**: `NodeClient` が `ActionType` に対応する `TransportAction` を検索し、実行する (`server/src/main/java/org/opensearch/transport/client/node/NodeClient.java`)
5. **TransportAction実行**: コーディネーティングノード上で `TransportAction` が実行される。必要に応じて `TransportService` を介してデータノードに処理を分散する
6. **ノード間通信**: `TransportService` が `Transport`（Netty4Transport）を使用してTCPベースのカスタムプロトコルで対象ノードと通信する
7. **Index/Search処理**: データノード上で `IndicesService` -> `IndexService` -> `IndexShard` -> Lucene `Engine` を経由してデータの読み書きが行われる
8. **レスポンス集約・返却**: 各ノードからのレスポンスがコーディネーティングノードで集約され、`RestChannel` を介してHTTPレスポンスとしてクライアントに返却される

### 非同期処理の流れ

1. **スレッドプール**: `ThreadPool` クラスが複数の専用スレッドプール（`generic`, `search`, `write`, `get`, `management`, `flush`, `refresh` 等）を管理する (`server/src/main/java/org/opensearch/threadpool/ThreadPool.java`)
2. **永続タスク**: `PersistentTasksService` がクラスタ全体で永続的に実行されるタスクを管理する (`server/src/main/java/org/opensearch/persistent/`)
3. **インジェストパイプライン**: `IngestService` がドキュメントインデックス前にパイプラインプロセッサを順次実行する (`server/src/main/java/org/opensearch/ingest/IngestService.java`)
4. **検索パイプライン**: `SearchPipelineService` がリクエスト変換・レスポンス変換を行う (`server/src/main/java/org/opensearch/search/pipeline/SearchPipelineService.java`)
5. **セグメントマージ**: Luceneのバックグラウンドスレッドがセグメントマージを実行する
6. **リモートストア同期**: `RemoteStoreNodeService` がセグメントデータをリモートストレージに非同期でアップロードする

### データ永続化の流れ

1. **ドキュメント書き込み**: クライアントからのインデックスリクエストはプライマリシャードに転送され、`InternalEngine` を通じてLuceneにドキュメントが書き込まれる
2. **Translog**: 書き込みは同時にトランザクションログ (`Translog`) に記録され、クラッシュリカバリに使用される
3. **Refresh**: 定期的な `refresh` 操作により、Luceneの `IndexWriter` から `IndexSearcher` が再オープンされ、新しいドキュメントが検索可能になる
4. **Flush**: `flush` 操作によりLuceneセグメントがディスクにコミットされ、Translogがクリアされる
5. **レプリカ同期**: プライマリシャードからレプリカシャードへの同期は、ドキュメントベースレプリケーションまたはセグメントレプリケーション (`SegmentReplicationSourceService`, `SegmentReplicationTargetService`) で行われる
6. **スナップショット**: `SnapshotsService` / `SnapshotShardsService` がLuceneセグメントファイルをリモートリポジトリにバックアップする

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| IdentityPlugin インターフェース | `server/src/main/java/org/opensearch/plugins/IdentityPlugin.java` | 認証・認可の拡張ポイント |
| IdentityService | `server/src/main/java/org/opensearch/identity/IdentityService.java` | IdentityPluginの統合管理。プラグイン未設定時は `NoopIdentityPlugin` を使用 |
| Subject / TokenManager | `server/src/main/java/org/opensearch/identity/Subject.java`, `tokens/TokenManager.java` | ユーザーサブジェクトとトークン管理の抽象化 |
| SecureTransportSettingsProvider | `server/src/main/java/org/opensearch/plugins/SecureTransportSettingsProvider.java` | TLS/SSL設定のプラグイン提供 |
| Security Plugin (外部) | 別リポジトリ (opensearch-security) | 本格的な認証・認可・監査ログ機能。`gradle/security-setup.gradle` で連携 (build.gradle 行75-78) |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | Log4j 2 (`LogManager.getLogger()`) | ファイル (`logs/` ディレクトリ) |
| 監査ログ | Security Plugin経由 | プラグイン設定に依存 |
| アクセスログ | `HttpTracer` (`server/src/main/java/org/opensearch/http/HttpTracer.java`) | アプリケーションログ |
| スローログ | `IndexingSlowLog`, `SearchRequestSlowLog` | 専用ログファイル |
| 非推奨機能警告 | `DeprecationLogger` | レスポンスヘッダ + ログ |
| テレメトリ | `TelemetryModule`, `TracerFactory`, `MetricsRegistryFactory` | OpenTelemetry Collector (telemetry-otelプラグイン経由) |

### エラーハンドリング

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| RESTリクエストエラー | `RestController` でキャッチし `BytesRestResponse` で返却 | HTTP 4xx/5xx + JSON |
| トランスポートエラー | `TransportException` 系例外 (`RemoteTransportException`, `ConnectTransportException` 等) | ノード間通信でのエラー伝播 |
| インデックスエラー | `OpenSearchException` 系例外 | HTTP 4xx/5xx + JSON (reason含む) |
| サーキットブレーカー | `HierarchyCircuitBreakerService` (`indices/breaker/`) | HTTP 429 (TOO_MANY_REQUESTS) |
| アドミッション制御 | `AdmissionControlService` / `AdmissionControlTransportInterceptor` | リクエスト拒否 (429) |
| 検索バックプレッシャー | `SearchBackpressureService` | タスクキャンセル |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| ドキュメント単位 | Lucene `IndexWriter` + Translog | ドキュメントレベルの楽観的排他制御 (バージョニング) |
| バルク操作 | 個別ドキュメント単位のアトミック性 | バルク全体のアトミック性は保証されない |
| クラスタ状態更新 | Raft的合意プロトコル (Coordinator) | クラスタ状態の順序保証 |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| プラグインアーキテクチャ | システム全体 | `Plugin` 基底クラスと `ActionPlugin`, `SearchPlugin` 等のインターフェースによる拡張 (`server/src/main/java/org/opensearch/plugins/Plugin.java` 行94) |
| 依存性注入 (DI) | ノード初期化 | Google Guice による `ModulesBuilder` と `Injector` (`server/src/main/java/org/opensearch/node/Node.java`) |
| イベント駆動 | クラスタ状態管理 | `ClusterStateListener`, `ClusterStateApplier` によるクラスタ状態変更の通知 |
| 分散コンピューティング | 検索・インデックス | Scatter-Gather パターンによる分散検索 (`SearchPhaseController`, `SearchTransportService`) |
| 不変性 | クラスタ状態 | `ClusterState` は不変オブジェクトとして設計され、更新時には新しいインスタンスが生成される |
| SPI (Service Provider Interface) | Lucene拡張 | `SPIClassIterator` によるLucene SPI の動的ロード (`server/src/main/java/org/opensearch/lucene/`) |
| PublicApi アノテーション | API安定性管理 | `@PublicApi(since = "1.0.0")` による公開API明示 (`common/annotation/PublicApi.java`) |

### コーディング規約

- **ビルドシステム**: Gradle マルチプロジェクト構成。`opensearch.build` カスタムプラグインによるビルド標準化 (`buildSrc/`)
- **コードフォーマット**: Spotless (com.diffplug.spotless) によるコード整形 (`build.gradle` 行58, `gradle/formatting.gradle`)
- **禁止API**: ForbiddenApis プラグインによる危険なAPI使用の検出 (`gradle/forbidden-dependencies.gradle`)
- **Javadoc**: missing-javadoc チェック (`gradle/missing-javadoc.gradle`, `doc-tools/missing-doclet`)
- **テスト**: JUnit ベースのユニットテスト + `InternalClusterTest` による統合テスト (`test/framework`)
- **FIPS準拠**: FIPS暗号化モードのサポート (`gradle/fips.gradle`, BouncyCastle FIPS)
- **API互換性チェック**: japicmp による API 後方互換性チェック (`server/build.gradle` 行39)
- **ライセンス**: Apache License 2.0。全ソースファイルにSPDXヘッダー必須

## 備考

### プラグインシステムの詳細

OpenSearchのプラグインシステムは以下の構成で成り立つ。

- **Plugin 基底クラス** (`server/src/main/java/org/opensearch/plugins/Plugin.java`): 全プラグインの基底クラス。`createComponents()`, `createGuiceModules()`, `getSettings()` 等のライフサイクルメソッドを提供
- **専用インターフェース群**: `ActionPlugin`, `AnalysisPlugin`, `ClusterPlugin`, `DiscoveryPlugin`, `EnginePlugin`, `IdentityPlugin`, `IndexStorePlugin`, `IngestPlugin`, `MapperPlugin`, `NetworkPlugin`, `RepositoryPlugin`, `ScriptPlugin`, `SearchPlugin`, `SearchPipelinePlugin`, `CachePlugin`, `CircuitBreakerPlugin`, `CryptoPlugin`, `TelemetryPlugin`, `StreamManagerPlugin` 等（全て `server/src/main/java/org/opensearch/plugins/` に定義）
- **PluginsService** (`server/src/main/java/org/opensearch/plugins/PluginsService.java`): プラグインの検出・ロード・初期化を管理。独立したURLClassLoaderでプラグインを隔離する
- **modules と plugins の違い**: `modules/` は配布に同梱されるバンドルモジュール、`plugins/` はユーザーが明示的にインストールするオプションプラグイン。いずれもPluginsServiceにより同じ仕組みでロードされる

### クラスタ管理・ノード間通信

- **Coordinator** (`server/src/main/java/org/opensearch/cluster/coordination/Coordinator.java`): Raft-likeな合意プロトコルによるCluster Manager選出とクラスタ状態パブリッシュを管理
- **DiscoveryModule** (`server/src/main/java/org/opensearch/discovery/DiscoveryModule.java`): ノードディスカバリのプラグインポイント。Zen2ディスカバリがデフォルト
- **TransportService** (`server/src/main/java/org/opensearch/transport/TransportService.java`): ノード間通信の中核。リクエスト送信、レスポンス受信、コネクション管理を担う
- **TcpTransport** (`server/src/main/java/org/opensearch/transport/TcpTransport.java`): TCPベースのトランスポート実装の基底クラス
- **Netty4Transport** (`modules/transport-netty4/src/main/java/org/opensearch/transport/netty4/Netty4Transport.java`): Netty4によるTCPトランスポート実装
- **gRPCトランスポート** (`modules/transport-grpc/`): 実験的なgRPCベースのトランスポート

### ノード役割

OpenSearchノードは以下の役割を持つことができる。

- **cluster_manager**: クラスタ状態の管理・更新
- **data**: データの格納・検索処理
- **ingest**: インジェストパイプラインの実行
- **coordinating**: リクエストルーティング（デフォルトで全ノード）
- **remote_cluster_client**: クロスクラスタ検索
- **warm**: ウォームノード（検索キャッシュ用）
