# 機能設計書 57-シャードルーティング

## 概要

本ドキュメントは、OpenSearchにおけるシャードルーティング機能の設計を記述する。シャードルーティングは、検索・取得リクエストを適切なシャードへルーティングする機能である。

### 本機能の処理概要

シャードルーティング機能は、ドキュメントIDやルーティング値に基づいてシャードを特定し、検索・取得リクエストを適切なシャード（プライマリまたはレプリカ）にルーティングする。プリファレンス設定やアダプティブレプリカ選択により、最適なシャードコピーを選択する。

**業務上の目的・背景**：分散検索エンジンにおいて、リクエストを正しいシャードにルーティングすることは基本的な要件である。また、レプリカ間での負荷分散やローカルノード優先などの最適化により、クエリ性能を向上させる。

**機能の利用シーン**：
- ドキュメントの取得（GET API）時のシャード特定
- 検索リクエスト時の対象シャード選択
- プリファレンス設定による特定シャードへのルーティング
- アダプティブレプリカ選択による負荷分散

**主要な処理内容**：
1. Murmur3ハッシュ関数によるシャードID計算
2. プリファレンス設定に基づくシャード選択
3. アダプティブレプリカ選択（ノード統計に基づく最適シャード選択）
4. 重み付きルーティング（ゾーン/アウェアネス属性ベース）

**関連システム・外部連携**：IndexShardRoutingTableと連携してシャードのルーティング情報を取得する。ResponseCollectorServiceと連携してノード統計を収集する。

**権限による制御**：シャードルーティングは内部処理のため、直接的なアクション権限は不要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 検索API | 関連機能 | 検索時のシャードルーティング |
| - | ドキュメント取得API | 関連機能 | 取得時のシャードルーティング |

## 機能種別

内部処理 / ルーティング

## 入力仕様

### プリファレンス設定

| プリファレンス | 説明 |
|--------------|------|
| _local | ローカルノードのシャードを優先 |
| _primary | プライマリシャードのみ |
| _replica | レプリカシャードのみ |
| _primary_first | プライマリ優先、なければレプリカ |
| _replica_first | レプリカ優先、なければプライマリ |
| _only_local | ローカルノードのみ（なければ失敗） |
| _only_nodes:{node_ids} | 指定ノードのみ |
| _prefer_nodes:{node_ids} | 指定ノード優先 |
| _shards:{shard_ids} | 指定シャードのみ |
| _search_replica | 検索レプリカを優先 |
| {custom_value} | カスタム値によるアフィニティ |

### 主要設定パラメータ

| パラメータ名 | 型 | 必須 | 説明 | デフォルト値 |
|-------------|-----|-----|------|-------------|
| cluster.routing.use_adaptive_replica_selection | boolean | No | アダプティブレプリカ選択の有効化 | true |
| cluster.search.ignore_awareness_attributes | boolean | No | アウェアネス属性を無視 | true |
| cluster.routing.weighted.default_weight | double | No | デフォルト重み | 1.0 |
| cluster.routing.weighted.fail_open | boolean | No | フェイルオープン有効化 | true |
| cluster.routing.weighted.strict | boolean | No | 厳密モード | true |

### 入力データソース

- リクエストパラメータ（preference, routing）
- ClusterState
- ResponseCollectorService（ノード統計）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ShardIterator | Iterator | 選択されたシャードのイテレータ |

### 出力先

内部処理（呼び出し元に返却）

## 処理フロー

### 処理シーケンス

```
1. シャードID計算
   └─ Murmur3HashFunction.hash(routing) % numberOfShards
2. IndexShardRoutingTable取得
   └─ ルーティングテーブルからシャード情報取得
3. プリファレンス解析
   └─ Preference列挙型にマッピング
4. シャードイテレータ生成
   └─ プリファレンスに基づくシャード選択
5. アダプティブレプリカ選択（有効時）
   └─ ノード統計に基づく最適シャード選択
```

### フローチャート

```mermaid
flowchart TD
    A[ルーティングリクエスト] --> B[シャードID計算]
    B --> C[IndexShardRoutingTable取得]
    C --> D{プリファレンス指定?}

    D -->|なし| E{アダプティブレプリカ選択?}
    D -->|あり| F[プリファレンス解析]

    E -->|有効| G[ノード統計取得]
    E -->|無効| H[ラウンドロビン選択]

    F --> I{プリファレンスタイプ}
    I -->|_primary| J[プライマリのみ]
    I -->|_replica| K[レプリカのみ]
    I -->|_local| L[ローカル優先]
    I -->|_only_nodes| M[指定ノードのみ]
    I -->|その他| N[対応する選択]

    G --> O[最適シャード選択]
    H --> P[シャードイテレータ返却]
    J --> P
    K --> P
    L --> P
    M --> P
    N --> P
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シャードID計算 | Murmur3ハッシュを使用 | 常時 |
| BR-02 | デフォルト選択 | アダプティブレプリカ選択がデフォルト有効 | preference未指定時 |
| BR-03 | ローカル優先 | _localプリファレンスでローカルノード優先 | _local指定時 |
| BR-04 | 重み付きルーティング | 重み0のノードにはルーティングしない | 重み設定時 |

### 計算ロジック

#### シャードID計算
```
shardId = Math.floorMod(Murmur3HashFunction.hash(routing), numberOfShards)
```

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

読み取り専用操作のため、データベースへの影響なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ShardNotFoundException | 対象シャードが見つからない | インデックス状態を確認 |
| - | NoShardAvailableActionException | 利用可能なシャードなし | クラスタ状態を確認 |

### リトライ仕様

シャードルーティング自体はリトライしない。上位レイヤーでリトライを制御。

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

読み取り専用操作のため、トランザクションは使用しない。

## パフォーマンス要件

- シャードID計算はO(1)の計算量
- アダプティブレプリカ選択ではノード統計の収集オーバーヘッドあり

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

- プリファレンス設定により特定ノードへのルーティングを制御可能
- 重み付きルーティングによりゾーン間のトラフィック制御が可能

## 備考

- OperationRouting.javaがメインのルーティングクラス
- IndexShardRoutingTableがシャードイテレータを生成

---

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

### 推奨読解順序

#### Step 1: メインクラス

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OperationRouting.java | `server/src/main/java/org/opensearch/cluster/routing/OperationRouting.java` | メインのルーティングロジック |
| 1-2 | Preference.java | `server/src/main/java/org/opensearch/cluster/routing/Preference.java` | プリファレンス定義 |

#### Step 2: シャード選択

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IndexShardRoutingTable.java | `server/src/main/java/org/opensearch/cluster/routing/IndexShardRoutingTable.java` | シャードイテレータ生成 |
| 2-2 | Murmur3HashFunction.java | `server/src/main/java/org/opensearch/cluster/routing/Murmur3HashFunction.java` | ハッシュ関数 |

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OperationRouting.java | `server/src/main/java/org/opensearch/cluster/routing/OperationRouting.java` | ソース | メインルーティング |
| IndexShardRoutingTable.java | `server/src/main/java/org/opensearch/cluster/routing/IndexShardRoutingTable.java` | ソース | シャードイテレータ生成 |
| Preference.java | `server/src/main/java/org/opensearch/cluster/routing/Preference.java` | ソース | プリファレンス定義 |
| Murmur3HashFunction.java | `server/src/main/java/org/opensearch/cluster/routing/Murmur3HashFunction.java` | ソース | ハッシュ関数 |
| WeightedRouting.java | `server/src/main/java/org/opensearch/cluster/routing/WeightedRouting.java` | ソース | 重み付きルーティング設定 |
