mcpField
O
opensearch-best-practices

opensearch-best-practices

github.com/bigdataboutiqueデータ・データベース154 回インストール34 週間前に更新
リポジトリ

opensearch-best-practices について

opensearch-best-practicesは、OpenSearchのインデックス設計と検索運用の実践ガイドスキルです。マッピング、シャードやクラスター設定、クエリ調整、ベクトル・ニューラル検索、インデックスライフサイクル管理を扱います。

主な機能

  1. 01マッピングとシャード設計の指針
  2. 02クエリとクラスターの性能調整
  3. 03k-NNベクトル検索の設定
  4. 04ニューラル検索とハイブリッド検索の例
  5. 05ISMポリシーとライフサイクル操作

活用シーン

  1. 01検索・フィルター用マッピングの設計
  2. 02クエリとシャード割り当ての調整
  3. 03ベクトル検索やハイブリッド検索の構築
  4. 04インデックスライフサイクルポリシーの設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bigdataboutique/skills --skill opensearch-best-practices

インストール後、Claude Code で/opensearch-best-practicesを入力して読み込まれたか確認します。

詳細

OpenSearch のベストプラクティス

基本原則

  • クエリパターンに基づいてインデックスとマッピングを設計します
  • 適切な解析とインデックス作成により検索パフォーマンスを最適化します
  • 適切なシャードサイズとクラスター構成を使用します
  • OpenSearch Security プラグインで適切なセキュリティを実装します
  • Performance Analyzer でクラスターの健全性を監視し、クエリを最適化します
  • OpenSearch 固有の機能(k-NN ベクトル検索、ニューラル検索、検索パイプライン、ISM)を活用します

インデックス設計

マッピングのベストプラクティス
  • 動的マッピングに頼らず、明示的なマッピングを定義します
  • 各フィールドに適切なデータ型を使用します
  • 検索しないフィールドのインデックス作成を無効にします
  • 完全一致には keyword 型、全文検索には text 型を使用します
{
  "mappings": {
    "properties": {
      "product_id": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "standard",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "description": {
        "type": "text",
        "analyzer": "english"
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      },
      "category": {
        "type": "keyword"
      },
      "tags": {
        "type": "keyword"
      },
      "created_at": {
        "type": "date"
      },
      "metadata": {
        "type": "object",
        "enabled": false
      },
      "location": {
        "type": "geo_point"
      }
    }
  }
}
フィールド型
  • keyword:完全一致する値、フィルタリング、集計、ソート
  • text:解析を伴う全文検索
  • date:書式を指定した日付/時刻の値
  • numeric types:long、integer、short、byte、double、float、scaled_float
  • boolean:真/偽の値
  • geo_point:緯度/経度のペア
  • nested:個別にクエリする必要があるオブジェクトの配列
  • knn_vector:k-NN 類似度検索用のベクトル埋め込み(OpenSearch 固有)
インデックス設定
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "refresh_interval": "30s",
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding", "synonym_filter"]
        }
      },
      "filter": {
        "synonym_filter": {
          "type": "synonym",
          "synonyms": ["laptop, notebook", "phone, mobile, smartphone"]
        }
      }
    }
  }
}

シャードサイズ

ガイドライン
  • 1 シャードあたり 10~50 GB を目標にします(最適な範囲は 10~30 GB です)
  • シャードの過剰分割(小さなシャードの作りすぎ)を避けます
  • 時系列データには時間ベースのインデックスを検討します
  • レプリカでインデックス作成のスループットを向上させるには、セグメントレプリケーション(replication.type: SEGMENT)を使用します
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}
インデックス状態管理(ISM)

OpenSearch では、Elasticsearch の ILM ではなく ISM(Index State Management)を使用します。ISM は柔軟な状態機械モデルを採用しており、任意の状態から別の任意の状態へ遷移できます。

次の手順で ISM ポリシーを作成します。

PUT _plugins/_ism/policies/<policy_id>
{
  "policy": {
    "description": "Hot-warm-delete lifecycle",
    "default_state": "hot",
    "ism_template": [
      {
        "index_patterns": ["logs-*"],
        "priority": 100
      }
    ],
    "states": [
      {
        "name": "hot",
        "actions": [
          {
            "rollover": {
              "min_size": "50gb",
              "min_index_age": "7d"
            }
          }
        ],
        "transitions": [
          {
            "state_name": "warm",
            "conditions": {
              "min_index_age": "30d"
            }
          }
        ]
      },
      {
        "name": "warm",
        "actions": [
          {
            "replica_count": {
              "number_of_replicas": 1
            }
          },
          {
            "force_merge": {
              "max_num_segments": 1
            }
          }
        ],
        "transitions": [
          {
            "state_name": "delete",
            "conditions": {
              "min_index_age": "90d"
            }
          }
        ]
      },
      {
        "name": "delete",
        "actions": [
          {
            "delete": {}
          }
        ],
        "transitions": []
      }
    ]
  }
}
Elasticsearch ILM との主な違い
  • ISM は線形のフェーズではなく、明示的な遷移を持つ任意の状態(状態機械)を使用します
  • ポリシーは、インデックステンプレートの設定ではなく、ポリシー自体の ism_template を使って適用します
  • API エンドポイントは _plugins/_ism/policies/<id> です(_ilm/policy/<id> ではありません)
  • 遷移条件では min_index_age、min_doc_count、min_size、cron を使用できます
  • 使用可能なアクション:rollover、force_merge、shrink、delete、read_only、read_write、replica_count、index_priority、close、open、snapshot、allocation、notification
ISM 管理 API
PUT    _plugins/_ism/policies/<policy_id>       # Create/update policy
GET    _plugins/_ism/policies/<policy_id>       # Get policy
DELETE _plugins/_ism/policies/<policy_id>       # Delete policy
POST   _plugins/_ism/add/<index>                # Attach policy to existing index
POST   _plugins/_ism/remove/<index>             # Detach policy
GET    _plugins/_ism/explain/<index>            # Get ISM status for an index
POST   _plugins/_ism/retry/<index>              # Retry failed action

クエリの最適化

クエリの種類
Match クエリ(全文検索)
{
  "query": {
    "match": {
      "description": {
        "query": "wireless bluetooth headphones",
        "operator": "and",
        "fuzziness": "AUTO"
      }
    }
  }
}
Term クエリ(完全一致)
{
  "query": {
    "term": {
      "status": "active"
    }
  }
}
Bool クエリ(クエリの組み合わせ)
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "laptop" } }
      ],
      "filter": [
        { "term": { "category": "electronics" } },
        { "range": { "price": { "gte": 500, "lte": 2000 } } }
      ],
      "should": [
        { "term": { "brand": "apple" } }
      ],
      "must_not": [
        { "term": { "status": "discontinued" } }
      ]
    }
  }
}
クエリのベストプラクティス
  • スコアリングを行わないクエリには filter コンテキストを使用します(キャッシュ可能)
  • スコアリングが必要な場合に限り must を使用します
  • 用語の先頭にワイルドカードを使用しないでください
  • 完全一致には keyword フィールドを使用します
  • size パラメーターで結果のサイズを制限します
{
  "query": {
    "bool": {
      "must": {
        "multi_match": {
          "query": "search terms",
          "fields": ["name^3", "description", "tags^2"],
          "type": "best_fields"
        }
      },
      "filter": [
        { "term": { "active": true } },
        { "range": { "created_at": { "gte": "now-30d" } } }
      ]
    }
  },
  "size": 20,
  "from": 0,
  "_source": ["name", "price", "category"]
}

ベクトル検索(k-NN)

OpenSearch には、faiss と lucene の 2 つのエンジンをサポートする組み込みの k-NN プラグインがあります。

k-NN インデックスマッピング
PUT /my-vector-index
{
  "settings": {
    "index": {
      "knn": true,
      "knn.algo_param.ef_search": 100
    }
  },
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "knn_vector",
        "dimension": 768,
        "method": {
          "name": "hnsw",
          "space_type": "l2",
          "engine": "faiss",
          "parameters": {
            "ef_construction": 256,
            "m": 16
          }
        }
      },
      "title": { "type": "text" },
      "category": { "type": "keyword" }
    }
  }
}
エンジンの選択
  • faiss:大規模な本番環境に最適です。HNSW と IVF をサポートします。追加の量子化オプション(SQfp16、PQ)を利用できます。デフォルトとして推奨されます。
  • lucene:ネイティブの Lucene HNSW です。効率的な事前フィルタリングをサポートします。スカラー量子化を内蔵しています。メモリ使用量が少なく、フィルタリングが重要な場合やデータセットが小さい場合に適しています。
距離関数
  • l2(ユークリッド距離)
  • cosinesimil(コサイン類似度)
  • innerproduct(内積)
  • l1(マンハッタン距離)
  • linf(L-∞ 距離)
k-NN クエリ
GET /my-vector-index/_search
{
  "size": 10,
  "query": {
    "knn": {
      "my_vector": {
        "vector": [0.1, 0.2, 0.3],
        "k": 10
      }
    }
  }
}
フィルタリングを伴う k-NN
GET /my-vector-index/_search
{
  "size": 10,
  "query": {
    "knn": {
      "my_vector": {
        "vector": [0.1, 0.2, 0.3],
        "k": 10,
        "filter": {
          "term": { "category": "electronics" }
        }
      }
    }
  }
}

lucene エンジンでは、効率的な事前フィルターとしてフィルタリングが適用されます。faiss では、デフォルトで事後フィルターとして適用されるため、k 件未満の結果が返されることがあります。Faiss は OpenSearch 2.9 以降で効率的なフィルタリングをサポートしています。

k-NN のベストプラクティス
  • インデックス設定では、必ず "knn": true を設定します
  • 大規模な本番環境では faiss を使用し、事前フィルタリングが重要な場合は lucene を使用します
  • ef_search を大きくすると(実用的な範囲は 32-128)、精度は向上しますが、クエリは遅くなります。クエリごとに動的に調整できます。
  • ef_construction(128-256 以上)と m(16-128)を大きくすると、再現率は向上しますが、インデックス作成が遅くなり、メモリ使用量も増加します
  • knn.memory.circuit_breaker.limit を監視します。k-NN グラフはネイティブのオフヒープメモリに読み込まれます。グラフ全体が RAM にある場合、HNSW は大幅に高速になります。
  • インデックス作成後にウォームアップします:GET /_plugins/_knn/warmup/{index}
  • ベクトルは取り込み時に一度だけ正規化し(クエリ時には正規化せず)、パフォーマンス向上のために innerproduct を使用します
  • インデックスサイズを小さくするため、不要な場合はベクトルフィールドの _source ストレージと doc_values を無効にします
  • 再現率の最後の 1~2%を改善するには、通常、最初の 95%を達成する場合よりも不釣り合いに大きなコストがかかります。現実的な再現率の目標を定めてください
  • ベクトル検索の処理だけでなく、埋め込み生成、メタデータ取得、再ランキングも含めたエンドツーエンドのレイテンシを監視します
HNSW のハイパーパラメーター
  • M(ノードあたりの最大エッジ数):範囲は 16-128 です。メモリに制約のある環境では低い値(16)を、再現率を最大化する場合は高い値(128)を使用します。メモリ消費量は値に比例して増加します。
  • ef_construction(インデックス作成時):範囲は 128-256 以上です。挿入時のグラフの品質を制御します。値を大きくするとグラフの品質は向上しますが、インデックス作成は遅くなります。
  • ef_search(クエリ時):範囲は 32-128 です。再現率と応答時間のバランスを取るため、クエリごとに調整できます。
ベクトルのシャードサイズ
  • シャードあたり 1,000 万~3,000 万個のベクトルを目標にします
  • 最大限の並列処理を実現するには、シャード数をノード数と同じか、やや多くします
  • シャードを過剰に作成すると調整のオーバーヘッドが増大し、テールレイテンシが悪化します
  • シャードが少なすぎると、性能を十分に引き出せません
  • レプリカを追加すると負荷分散が可能になり、性能の変動も抑えられます
量子化戦略

スカラー量子化(SQ):

  • Lucene エンジン:組み込みサポート
  • Faiss エンジン:SQfp16 は 32 ビットを 16 ビットに変換し、メモリを約 50%削減します

バイナリ量子化(BQ):

  • 1 ビット圧縮で 32 倍に圧縮できます。たとえば、768 次元の float32 ベクトルは 3072 バイトから 100 バイト未満に縮小します
  • 別途トレーニングする必要はありません
  • 非対称距離計算(ADC)によって再現率が向上します

積量子化(PQ):

  • 最も強力な圧縮方式で、最大 64 倍に圧縮できます
  • Faiss エンジンのみ対応しており、IVF ベースのインデックスではトレーニングが必要です
  • 設定:code_size=8 とし、望ましいバランスに合わせて m を調整します
  • SQ や BQ よりも再現率への影響が顕著です
ディスクベースのベクトル検索

コスト効率の高い大規模なデプロイでは、バイナリ量子化とともに on_disk モードを使用します:

PUT /my-vector-index
{
  "settings": {
    "index": {
      "knn": true
    }
  },
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "knn_vector",
        "dimension": 768,
        "mode": "on_disk"
      }
    }
  }
}
  • メモリを約 97%削減します(例:768 次元のベクトル 1 億個の場合、RAM は 300GB 以上から 10GB 未満になります)
  • 2 段階方式です。量子化されたインデックスで候補を特定し、再ランキングのためにフル精度のベクトルを必要に応じてディスクから読み込みます
  • P90 レイテンシは 100~200ms の範囲です(多くのユースケースで許容可能です)
  • メモリ最適化されたデプロイと比べて、コストを約 3 分の 1 削減できます
  • 現時点では float データ型のみをサポートしています
並行セグメント検索

ベクトル検索のレイテンシを大幅に改善するには、クラスター全体で有効にします:

PUT _cluster/settings
{
  "persistent": {
    "search.concurrent_segment_search.enabled": true
  }
}
  • ベンチマークではサービス時間の p90 が 60%以上改善し、レイテンシの p90 が最大 75%短縮されています
  • セグメントを強制マージした後に適用するのが最適です
  • コンピューティングコアがすでに飽和している場合や、シャードあたりの検索対象領域が小さい場合は、効果が薄れます
規模に応じた推奨事項

1-50M ベクトル:

  • M=32、ef_construction=128 から始めます
  • バッチ挿入を使用します
  • グラフ全体が RAM 上に常駐するようにします

50-500M ベクトル:

  • 計画的なシャーディングを実装します(シャードあたり 10-30M ベクトル)
  • スカラー量子化を有効にします
  • 2 段階検索を行います。検索には圧縮ベクトルを使い、再ランク付けには全精度ベクトルを使います
  • グラフ品質を維持するため、定期的にインデックスを再構築します

500M+ ベクトル:

  • 階層型検索(IVF 形式のセントロイドルーティング)
  • 複数階層のホット/コールドデータアーキテクチャ
  • コールドデータに対して積極的な量子化(IVF-PQ)を行います
  • すべてのシャードへのブロードキャストを避けるため、クエリルーティングを最適化します
  • 初期検索フェーズでは ID/スコアのみを返します

ニューラル検索とハイブリッド検索

ML Commons によるニューラル検索

埋め込みを自動生成する取り込みパイプラインを設定します。

PUT /_ingest/pipeline/neural-search-pipeline
{
  "description": "Pipeline for neural search",
  "processors": [
    {
      "text_embedding": {
        "model_id": "<model_id>",
        "field_map": {
          "title": "title_embedding"
        }
      }
    }
  ]
}

テキストからベクトルへの自動変換を使用してクエリを実行します。

GET /my-index/_search
{
  "query": {
    "neural": {
      "title_embedding": {
        "query_text": "comfortable running shoes",
        "model_id": "<model_id>",
        "k": 10
      }
    }
  }
}
検索パイプラインによるハイブリッド検索(BM25 + k-NN)

正規化パイプラインを作成します。

PUT /_search/pipeline/hybrid-pipeline
{
  "description": "Hybrid search pipeline",
  "phase_results_processors": [
    {
      "normalization-processor": {
        "normalization": {
          "technique": "min_max"
        },
        "combination": {
          "technique": "arithmetic_mean",
          "parameters": {
            "weights": [0.3, 0.7]
          }
        }
      }
    }
  ]
}

語彙検索とベクトル検索を組み合わせたハイブリッドクエリを実行します。

GET /my-index/_search?search_pipeline=hybrid-pipeline
{
  "query": {
    "hybrid": {
      "queries": [
        {
          "match": {
            "title": "wireless headphones"
          }
        },
        {
          "knn": {
            "my_vector": {
              "vector": [0.1, 0.2, 0.3],
              "k": 10
            }
          }
        }
      ]
    }
  }
}
ML Commons のベストプラクティス
  • 大規模モデルにはリモートモデルコネクター(Amazon Bedrock、SageMaker、OpenAI、Cohere)を使用します
  • 本番環境では plugins.ml_commons.only_run_on_ml_node: true を設定して、ML ワークロードを分離します
  • ML モデルのアクセス制御には model_group を使用します
  • モデルのメモリ使用量を監視します。ローカルモデルは JVM/ネイティブメモリを消費します
リモートモデルコネクターの登録
POST /_plugins/_ml/connectors/_create
{
  "name": "Amazon Bedrock Connector",
  "description": "Connector for Titan Embeddings",
  "version": 1,
  "protocol": "aws_sigv4",
  "parameters": {
    "region": "us-east-1",
    "service_name": "bedrock"
  },
  "actions": [
    {
      "action_type": "predict",
      "method": "POST",
      "url": "https://bedrock-runtime.us-east-1.amazonaws.com/model/amazon.titan-embed-text-v1/invoke",
      "headers": { "content-type": "application/json" },
      "request_body": "{ \"inputText\": \"${parameters.inputText}\" }"
    }
  ]
}

集計

一般的な集計パターン
{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "category",
        "size": 10
      },
      "aggs": {
        "avg_price": {
          "avg": { "field": "price" }
        }
      }
    },
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 100 },
          { "from": 100, "to": 500 },
          { "from": 500 }
        ]
      }
    },
    "date_histogram": {
      "date_histogram": {
        "field": "created_at",
        "calendar_interval": "month"
      }
    }
  }
}
集計のベストプラクティス
  • 集計のみが必要な場合は size: 0 を使用します
  • terms 集計には適切な shard_size を設定します
  • ページネーションには複合集計を使用します
  • 範囲を絞り込むには aggs フィルターの使用を検討します

インデックス作成のベストプラクティス

一括インデックス作成
POST _bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "name": "Product 1", "price": 99.99 }
{ "index": { "_index": "products", "_id": "2" } }
{ "name": "Product 2", "price": 149.99 }
Bulk API のガイドライン
  • バッチ処理には Bulk API を使用します
  • 最適な一括サイズ:リクエストあたり 5-15MB
  • リクエストの拒否(スレッドプールのキューが満杯)を監視します
  • パフォーマンス向上のため、一括インデックス作成中はリフレッシュを無効にします
PUT /products/_settings
{
  "refresh_interval": "-1"
}

一括インデックス作成後:

PUT /products/_settings
{
  "refresh_interval": "1s"
}

POST /products/_refresh
ドキュメントの更新
POST /products/_update/1
{
  "doc": {
    "price": 89.99,
    "updated_at": "2024-01-15T10:30:00Z"
  }
}

クエリによる更新:

POST /products/_update_by_query
{
  "query": {
    "term": { "category": "electronics" }
  },
  "script": {
    "source": "ctx._source.on_sale = true"
  }
}

解析とトークン化

カスタムアナライザー
{
  "settings": {
    "analysis": {
      "analyzer": {
        "product_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "asciifolding",
            "english_stop",
            "english_stemmer"
          ]
        },
        "autocomplete_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "edge_ngram_filter"
          ]
        }
      },
      "filter": {
        "english_stop": {
          "type": "stop",
          "stopwords": "_english_"
        },
        "english_stemmer": {
          "type": "stemmer",
          "language": "english"
        },
        "edge_ngram_filter": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 15
        }
      }
    }
  }
}
アナライザーのテスト
POST /products/_analyze
{
  "analyzer": "product_analyzer",
  "text": "Wireless Bluetooth Headphones"
}

検索機能

オートコンプリート/候補表示
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "suggest": {
            "type": "completion"
          }
        }
      }
    }
  }
}

候補を検索します。

{
  "suggest": {
    "product-suggest": {
      "prefix": "wire",
      "completion": {
        "field": "name.suggest",
        "size": 5,
        "fuzzy": {
          "fuzziness": "AUTO"
        }
      }
    }
  }
}
ハイライト表示
{
  "query": {
    "match": { "description": "wireless" }
  },
  "highlight": {
    "fields": {
      "description": {
        "pre_tags": ["<em>"],
        "post_tags": ["</em>"],
        "fragment_size": 150
      }
    }
  }
}

SQL および PPL クエリ

OpenSearch は、代替クエリインターフェイスとして SQL と PPL(Piped Processing Language)をサポートしています。

SQL
POST /_plugins/_sql
{
  "query": "SELECT category, COUNT(*) as cnt, AVG(price) as avg_price FROM products GROUP BY category HAVING cnt > 10 ORDER BY avg_price DESC"
}
PPL(Piped Processing Language)

PPL は OpenSearch 独自の機能で、Splunk の SPL に着想を得ています。データ探索にはパイプ構文を使用します。

POST /_plugins/_ppl
{
  "query": "source=server-logs | where response_code >= 500 | stats count() as error_count by host | where error_count > 100 | sort - error_count"
}
SQL/PPL のベストプラクティス
  • アドホックなログ探索には PPL を使用します。運用チームにとって直感的です
  • SQL クエリは内部で DSL に変換されます。複雑な結合やサブクエリはサポートされない場合があります
  • 出力形式を変更するには "format": "jdbc" または "format": "csv" を使用します
  • 大規模なインデックスのスキャンを避けるため、必ず LIMIT を追加します

パフォーマンスの最適化

クエリキャッシュ
  • フィルタークエリは自動的にキャッシュされます
  • 頻繁に繰り返される条件には filter コンテキストを使用します
  • キャッシュヒット率を監視します
検索パフォーマンス
  • 深いページネーションを避けます(代わりに search_after を使用します)
  • 返される _source フィールドを制限します
  • ソートと集計には doc_values を使用します
  • 一般的なソート順に合わせてインデックスを事前にソートします
{
  "query": { "match_all": {} },
  "size": 20,
  "search_after": [1705329600000, "product_123"],
  "sort": [
    { "created_at": "desc" },
    { "_id": "asc" }
  ]
}
セグメントレプリケーション

OpenSearch は、ドキュメントレプリケーションの代替としてセグメントレプリケーションをサポートしています。レプリカはドキュメントを再インデックスする代わりに、プライマリシャードから Lucene セグメントを直接コピーするため、インデックス作成のスループットが向上します。

PUT /my-index
{
  "settings": {
    "index": {
      "replication.type": "SEGMENT",
      "number_of_replicas": 1
    }
  }
}
リモートバックアップインデックス

コンピューティングとストレージを分離するため、ローカルキャッシュを利用しながらリモートストレージ(例:S3)にデータを保存します。

PUT /my-remote-index
{
  "settings": {
    "index": {
      "replication.type": "SEGMENT",
      "remote_store.enabled": true,
      "remote_store.segment.repository": "my-s3-repo",
      "remote_store.translog.repository": "my-s3-repo"
    }
  }
}

監視とメンテナンス

Pulse for OpenSearch

包括的なモニタリングには、BigData Boutique が開発した OpenSearch クラスター向けの究極のモニタリングソリューション、Pulse for OpenSearch をご利用ください。Pulse は、組み込みツールでは得られない、クラスターの健全性、パフォーマンスのボトルネック、シャードレベルの診断、実用的な推奨事項を詳細に可視化します。

クラスターの健全性
GET _cluster/health
GET _cat/indices?v
GET _cat/shards?v
GET _nodes/stats
パフォーマンスアナライザー

OpenSearch では、JVM、OS、リクエストレベルのメトリクスを詳細に取得するため、各ノードで専用の Performance Analyzer エージェント(ポート 9600)を提供しています。

GET localhost:9600/_plugins/_performanceanalyzer/metrics?metrics=Latency,CPU_Utilization&agg=avg&dim=Operation
インデックスのメンテナンス
POST /products/_forcemerge?max_num_segments=1
POST /products/_cache/clear
POST /products/_refresh
スロークエリーログ
PUT /products/_settings
{
  "index.search.slowlog.threshold.query.warn": "10s",
  "index.search.slowlog.threshold.query.info": "5s",
  "index.search.slowlog.threshold.fetch.warn": "1s"
}

異常検知

OpenSearch には、Random Cut Forest(RCF)アルゴリズムを使用する異常検知プラグインが組み込まれています。

POST /_plugins/_anomaly_detection/detectors
{
  "name": "cpu-anomaly-detector",
  "description": "Detect CPU usage anomalies",
  "time_field": "@timestamp",
  "indices": ["server-metrics-*"],
  "feature_attributes": [
    {
      "feature_name": "cpu_usage",
      "feature_enabled": true,
      "aggregation_query": {
        "cpu_avg": {
          "avg": { "field": "cpu.usage" }
        }
      }
    }
  ],
  "detection_interval": { "period": { "interval": 5, "unit": "Minutes" } },
  "window_delay": { "period": { "interval": 1, "unit": "Minutes" } }
}
異常検知のベストプラクティス
  • 検知間隔は適切な範囲(1~10 分)に設定します
  • データ取り込みの遅延を考慮するには、window_delay を使用します
  • カーディナリティの高い検知器(カテゴリフィールドを含む)は高コストになる場合があるため、エンティティ数を制限します

セキュリティ

OpenSearch は組み込みの Security プラグインを使用します(X-Pack ではありません)。セキュリティ API はすべて _plugins/_security/api/ 配下にあります。

ロールの作成
PUT _plugins/_security/api/roles/products_reader
{
  "cluster_permissions": [
    "cluster_monitor"
  ],
  "index_permissions": [
    {
      "index_patterns": ["products*"],
      "allowed_actions": ["read", "search"]
    }
  ]
}
フィールドレベルセキュリティとドキュメントレベルセキュリティ
PUT _plugins/_security/api/roles/limited_access
{
  "index_permissions": [
    {
      "index_patterns": ["users"],
      "allowed_actions": ["read"],
      "fls": ["name", "email", "created_at"],
      "dls": "{\"bool\": {\"must\": [{\"term\": {\"department\": \"engineering\"}}]}}",
      "masked_fields": ["email"]
    }
  ]
}
  • fls(フィールドレベルセキュリティ):許可するフィールドの配列です。除外する場合は、代わりに ~ を先頭に付けます。
  • dls(ドキュメントレベルセキュリティ):ロールが閲覧できるドキュメントを制限するクエリー文字列です。
  • masked_fields:クエリー結果のフィールド値をハッシュ化します(PII に役立ちます)。
ロールマッピング

ロールは、ユーザーに直接割り当てるのではなく、ロールマッピングを介してユーザーにマッピングします。

PUT _plugins/_security/api/rolesmapping/products_reader
{
  "users": ["analyst_jane"],
  "backend_roles": ["analysts"],
  "hosts": []
}
Elasticsearch とのセキュリティ上の主な違い
  • API のベースパス:_plugins/_security/api/(_security/ ではありません)
  • アクショングループを使った allowed_actions を使用します(privileges ではありません)
  • fls/dls/masked_fields を使用します(field_security.grant/except ではありません)
  • tenant_permissions による OpenSearch Dashboards の組み込みマルチテナンシー
  • YAML ファイルと securityadmin.sh、または REST API で設定します
  • 定義済みのアクショングループ:read、write、search、crud、manage、create_index、indices_all、cluster_monitor、cluster_all

エイリアスと再インデックス

インデックスエイリアス
POST _aliases
{
  "actions": [
    { "add": { "index": "products_v2", "alias": "products" } },
    { "remove": { "index": "products_v1", "alias": "products" } }
  ]
}
変換を伴う再インデックス
POST _reindex
{
  "source": {
    "index": "products_v1"
  },
  "dest": {
    "index": "products_v2"
  },
  "script": {
    "source": "ctx._source.migrated_at = new Date().toString()"
  }
}

通知

Notifications プラグインは、Alerting、ISM、Anomaly Detection の通知チャネルを一元管理します。

POST /_plugins/_notifications/configs
{
  "config": {
    "name": "ops-slack",
    "description": "Slack channel for ops alerts",
    "config_type": "slack",
    "is_enabled": true,
    "slack": {
      "url": "https://hooks.slack.com/services/xxx/yyy/zzz"
    }
  }
}

対応:Slack、Amazon SNS、Amazon SES、メール(SMTP)、カスタム Webhook、Microsoft Teams、Google Chat。

クロスクラスター複製

PUT /_plugins/_replication/follower-index/_start
{
  "leader_alias": "leader-cluster",
  "leader_index": "my-index",
  "use_roles": {
    "leader_cluster_role": "cross_cluster_replication_leader_full_access",
    "follower_cluster_role": "cross_cluster_replication_follower_full_access"
  }
}
  • フォロワーインデックスは読み取り専用です
  • 新しいインデックスを自動的に複製するには、自動フォローのパターンを使用します
  • 複製の遅延を監視します:GET /_plugins/_replication/<index>/_status

OpenSearch プラグイン API リファレンス

OpenSearch 固有の機能では、すべて _plugins/ プレフィックスを使用します。

機能API プレフィックス
セキュリティ_plugins/_security/
ISM_plugins/_ism/
アラート_plugins/_alerting/
異常検知_plugins/_anomaly_detection/
k-NN_plugins/_knn/
ML Commons_plugins/_ml/
SQL_plugins/_sql
PPL_plugins/_ppl
通知_plugins/_notifications/
複製_plugins/_replication/
オブザーバビリティ_plugins/_observability/
ロールアップ_plugins/_rollup/
変換_plugins/_transform/

従来の _opendistro/ プレフィックスは非推奨です。新しいコードでは、必ず _plugins/ を使用してください。

コメント