- Authors
- Name
- なぜOpenSearch運用スキルが重要なのか
- 1. プロダクションクラスタアーキテクチャ
- 2. インデックス設計とシャード戦略
- 3. ISM(Index State Management)ライフサイクル管理
- 4. モニタリングとアラート設定
- 5. 障害シナリオと復旧戦略
- 6. AWS OpenSearch Service 運用チェックリスト
- 7. OpenSearch vs Elasticsearch 運用視点比較
- 8. Elasticsearch → OpenSearch マイグレーションチェックリスト
- 9. パフォーマンスチューニングクイックリファレンス
- 10. セキュリティ強化チェックリスト
- まとめ:運用者が覚えるべき7つのこと
- References
なぜOpenSearch運用スキルが重要なのか
OpenSearchはログ分析、全文検索、オブザーバビリティパイプラインのコアエンジンである。クラスタを立ち上げるのは簡単だが、安定的に運用しながらコストを制御するのはまったく別の問題だ。インデックス1つのシャード数を間違えるとクラスタ全体のJVMヒープが不安定になり、ISMポリシーが1つ欠けるとディスクが満杯になって書き込みが停止する。
この記事では、クラスタアーキテクチャ → インデックス設計 → ISMライフサイクル → モニタリング → 障害対応 → セキュリティ → マイグレーションの順序で、運用者が実際のプロダクションで直面する意思決定ポイントを扱う。すべてのAPI例はOpenSearch 2.x基準であり、AWS OpenSearch Serviceでも同様に使用できる。
1. プロダクションクラスタアーキテクチャ
1.1 ノード役割の分離
プロダクションクラスタでは、各ノードタイプの役割を明確に分離することで安定性とパフォーマンスを同時に確保できる。
+------------------------------------------------------------------+
| クライアント / Data Prepper |
| (Ingest Pipeline) |
+------------------------------+-----------------------------------+
|
+--------------------+--------------------+
v v v
+------------+ +------------+ +------------+
| Master-1 | | Master-2 | | Master-3 |
| (AZ-a) | | (AZ-b) | | (AZ-c) |
| 専用マスター | | 専用マスター | | 専用マスター |
+------------+ +------------+ +------------+
| | |
v v v
+------------+ +------------+ +------------+
| Hot-1 | | Hot-2 | | Hot-3 |
| (AZ-a) | | (AZ-b) | | (AZ-c) |
| EBS gp3 | | EBS gp3 | | EBS gp3 |
+------------+ +------------+ +------------+
| | |
v v v
+------------+ +------------+ +------------+
| Warm-1 | | Warm-2 | | Warm-3 |
| UltraWarm | | UltraWarm | | UltraWarm |
| (S3+キャッシュ) | | (S3+キャッシュ) | | (S3+キャッシュ) |
+------------+ +------------+ +------------+
| ノードタイプ | 役割 | 推奨スペック | 配置ルール |
|---|---|---|---|
| 専用マスター | クラスタメタデータ管理、シャード割当 | 最低3台(奇数)、最新世代インスタンス | 必ず3 AZに分散 |
| Hotデータノード | アクティブな読み書き処理 | 高CPU + 高速ストレージ(gp3) | AZ均等分配 |
| Warmデータノード | 読み取り中心、低頻度クエリ | 高ストレージ密度、低CPU | UltraWarm(S3ベース) |
| Coordinatingノード | リクエストルーティング、結果集約 | 高CPU + メモリ、ストレージ最小 | 検索集約ワークロードのみ |
1.2 容量算定公式
プロダクションクラスタサイジングの核心公式である。
必要ストレージ = 日次原本データ
× (1 + レプリカ数)
× 1.1 (インデキシングオーバーヘッド)
× 1.15 (OS予約 + 内部作業余裕)
× 保存期間(日)
例: 日別ログ100 GiB、レプリカ1、30日保存 → 100 × 2 × 1.1 × 1.15 × 30 = 7,590 GiB
ディスク使用率は**最大75%**以内に維持する。75%を超えるとOpenSearchは新しいシャード割当を拒否し始め、85%でread-onlyに切り替わる。
実際のプロビジョニング = 必要ストレージ / 0.75 = 10,120 GiB
2. インデックス設計とシャード戦略
2.1 シャードサイジング基準
シャードサイズはワークロードタイプによって異なる。OpenSearch公式ドキュメントとAWSガイドで推奨される範囲は以下の通りである。
| ワークロード | 推奨シャードサイズ | 根拠 |
|---|---|---|
| 検索レイテンシ重視(EC、オートコンプリート) | 10-30 GiB | レイテンシ最小化、高速リカバリ |
| 書き込み中心 / ログ分析 | 30-50 GiB | 書き込みスループット最大化 |
| 最大推奨上限 | 50 GiB | これ以上はリカバリ・再配置時間が急増 |
プライマリシャード数の計算公式:
プライマリシャード数 ≈ (原本データサイズ + 成長余裕) × 1.1 / 目標シャードサイズ
例: 日別ログ66 GiB、4倍成長見込み、目標シャードサイズ30 GiB
(66 + 198) × 1.1 / 30 ≈ 10 プライマリシャード
2.2 ノードあたりシャード上限
| 制約条件 | 上限 |
|---|---|
| JVMヒープ対比 | ヒープ1 GiBあたり25シャード |
| CPU対比 | シャード1つあたりvCPU 1.5個(初期規模) |
| OpenSearch 2.15以前 | ノードあたり最大1,000シャード |
| OpenSearch 2.17以降 | JVMヒープ16 GiBあたり1,000シャード、ノードあたり最大4,000 |
核心原則: シャード数をデータノード数の倍数に設定し均等分配する。例えばデータノード3台なら、プライマリシャードを3、6、9、12個などに設定する。
2.3 インデックステンプレートとマッピング設計
例1:Composable Index Template
インデックステンプレートですべての新しいインデックスの設定とマッピングを一貫して管理する。dynamic: strictで予期しないフィールドの追加(マッピング爆発)を防ぐことが核心である。
PUT _index_template/app-logs-template
{
"index_patterns": ["app-logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s",
"index.translog.flush_threshold_size": "1024mb",
"index.codec": "zstd_no_dict",
"plugins.index_state_management.rollover_alias": "app-logs-write"
},
"mappings": {
"dynamic": "strict",
"properties": {
"@timestamp": { "type": "date" },
"level": { "type": "keyword" },
"message": { "type": "text", "analyzer": "standard" },
"service": { "type": "keyword" },
"trace_id": { "type": "keyword" },
"span_id": { "type": "keyword" },
"host": { "type": "keyword" },
"duration_ms": { "type": "float" },
"http_status": { "type": "short" },
"request_path":{ "type": "keyword" },
"user_id": { "type": "keyword" },
"metadata": {
"type": "object",
"enabled": false
}
}
}
},
"composed_of": ["common-settings"],
"priority": 200
}
設定ポイント解説:
refresh_interval: 30s— デフォルトの1秒から増やしてCPU/IO負荷を削減する。リアルタイム検索が不要なログワークロードに適している。translog.flush_threshold_size: 1024mb— JVMヒープの25%水準に設定しflush頻度を下げる。dynamic: strict— 定義していないフィールドが入るとインデキシングを拒否する。マッピング爆発防止の核心である。index.codec: zstd_no_dict— OpenSearch 2.9以降で使用可能なzstd圧縮。デフォルトLZ4対比25-30%のストレージ削減。metadata.enabled: false— 検索しないネストオブジェクトはインデキシングを無効化してリソースを節約する。
2.4 レプリカ戦略
| 構成 | 推奨レプリカ数 | 理由 |
|---|---|---|
| シングルAZ | 1 | ノード障害時のデータ保護 |
| Multi-AZ(2 AZ) | 1 | AZ障害時に別AZでサービス |
| Multi-AZ with Standby(3 AZ) | 2 | AZ障害時も100%データ可用 |
| 大量バルクインデキシング中 | 0(一時的) | インデキシング速度最大化後に復元 |
レプリカ0作戦パターン: 初期大量ロード時にレプリカを0に設定し、完了後に戻すとインデキシング速度が最大2倍向上する。
// インデキシング前:レプリカを無効化
PUT my-bulk-index/_settings
{ "index.number_of_replicas": 0 }
// インデキシング完了後:レプリカを復元
PUT my-bulk-index/_settings
{ "index.number_of_replicas": 1 }
2.5 Data Stream vs 従来のインデックスパターン
OpenSearch 2.6以降ではData Streamをサポートしている。従来のRollover + Aliasパターンと比較すると以下の通りである。
| 項目 | Rollover + Alias | Data Stream |
|---|---|---|
| 初期設定 | 初期インデックス + alias手動作成 | インデックステンプレートのみ登録 |
| 書き込み対象 | write alias | data stream名を直接使用 |
| バッキングインデックス名 | app-logs-000001 | .ds-app-logs-000001 |
| 削除 | インデックス単位 | DELETE _data_stream/app-logs |
| 推奨ワークロード | 汎用 | 時系列(append-only)専用 |
3. ISM(Index State Management)ライフサイクル管理
ISMはOpenSearchのインデックスライフサイクル自動化エンジンである。ElasticsearchのILMに相当し、Hot → Warm → Cold → Deleteのフローを自動的に処理する。
3.1 Hot-Warm-Cold-Delete 全体ポリシー
例2:ISM全ライフサイクルポリシー
PUT _plugins/_ism/policies/app-log-lifecycle
{
"policy": {
"description": "アプリログインデックスライフサイクル:hot → warm → cold → delete",
"default_state": "hot",
"states": [
{
"name": "hot",
"actions": [
{
"rollover": {
"min_size": "30gb",
"min_index_age": "1d",
"min_doc_count": 10000000
}
}
],
"transitions": [
{ "state_name": "warm", "conditions": { "min_index_age": "3d" } }
]
},
{
"name": "warm",
"actions": [
{ "replica_count": { "number_of_replicas": 1 } },
{ "force_merge": { "max_num_segments": 1 } },
{ "allocation": {
"require": { "temp": "warm" },
"wait_for": true
}
}
],
"transitions": [
{ "state_name": "cold", "conditions": { "min_index_age": "30d" } }
]
},
{
"name": "cold",
"actions": [
{ "replica_count": { "number_of_replicas": 0 } },
{ "read_only": {} }
],
"transitions": [
{ "state_name": "delete", "conditions": { "min_index_age": "90d" } }
]
},
{
"name": "delete",
"actions": [
{
"notification": {
"destination": {
"slack": { "url": "https://hooks.slack.com/services/T.../B.../xxx" }
},
"message_template": {
"source": "インデックス {{ctx.index}} が保持ポリシー(90日)に従い削除されます。"
}
}
},
{ "delete": {} }
],
"transitions": []
}
],
"ism_template": [
{ "index_patterns": ["app-logs-*"], "priority": 100 }
]
}
}
運用ポイント:
- ISMチェック周期のデフォルト値は5分である。
plugins.index_state_management.job_intervalで調整可能。 ism_templateフィールドを設定すると、パターンに一致する新しいインデックスに自動的にポリシーが適用される。- rollover条件(
min_size、min_index_age、min_doc_count)はOR条件である — 1つでも満たせばロールオーバーが実行される。 allocation.require.temp: warm— シャードをnode.attr.temp=warm属性のノードに移動させる。- force_merge後はそのインデックスへの書き込みを行ってはならない。
3.2 ISM運用コマンド
# ポリシー実行状態の確認(特定インデックス)
GET _plugins/_ism/explain/app-logs-000001
# 既存インデックスにポリシーを適用
POST _plugins/_ism/add/old-logs-2025-*
{ "policy_id": "app-log-lifecycle" }
# ポリシーバージョンの更新(管理中のインデックスに新ポリシーを適用)
POST _plugins/_ism/change_policy/app-logs-*
{
"policy_id": "app-log-lifecycle-v2",
"state": "warm"
}
# 失敗したISM操作のリトライ
POST _plugins/_ism/retry/app-logs-000003
# 特定インデックスからISMポリシーを除去
POST _plugins/_ism/remove/app-logs-000005
3.3 Rollover + Alias パターンの実践構成
例3:Rollover Alias初期設定と運用フロー
時系列インデックス運用の標準パターンである。書き込みaliasが常に最新インデックスを指し、ISM rolloverが新しいインデックスを作成・切り替える。
// ステップ1:初期インデックス作成 + alias設定
PUT app-logs-000001
{
"aliases": {
"app-logs-write": { "is_write_index": true },
"app-logs-read": {}
}
}
// ステップ2:ISMポリシーのrolloverアクションが自動的に処理
// → app-logs-000002を作成
// → app-logs-write aliasを000002に移動
// → 000001のis_write_indexをfalseに変更
// 読み取りは常にread aliasで(全履歴対象)
GET app-logs-read/_search
{
"query": {
"bool": {
"must": [
{ "match": { "level": "ERROR" } },
{ "range": { "@timestamp": { "gte": "now-1h" } } }
]
}
},
"sort": [{ "@timestamp": "desc" }],
"size": 100
}
// 書き込みは常にwrite aliasで
POST app-logs-write/_doc
{
"@timestamp": "2026-03-04T10:00:00Z",
"level": "ERROR",
"service": "payment-api",
"message": "決済ゲートウェイタイムアウト発生",
"trace_id": "abc123",
"duration_ms": 30500,
"http_status": 504
}
alias状態の確認:
# 現在のwrite indexを確認
GET _alias/app-logs-write
# 全alias構造を確認
GET _cat/aliases/app-logs-*?v&h=alias,index,is_write_index
4. モニタリングとアラート設定
4.1 必須モニタリング指標としきい値
| カテゴリ | 指標 | しきい値 | 深刻度 |
|---|---|---|---|
| クラスタ状態 | ClusterStatus.red | 1以上(1分、1回) | Critical |
| クラスタ状態 | ClusterStatus.yellow | 1以上(1分、5連続) | Warning |
| 書き込み阻止 | ClusterIndexWritesBlocked | 1以上(5分、1回) | Critical |
| ノード数 | Nodes | 想定ノード数未満(1日、1回) | Critical |
| ディスク空き | FreeStorageSpace | ノードストレージの25%以下 | Warning |
| JVMヒープ | JVMMemoryPressure | 95%以上(1分、3連続) | Critical |
| Old Gen JVM | OldGenJVMMemoryPressure | 80%以上(1分、3連続) | Warning |
| CPU使用率 | CPUUtilization | 80%以上(15分、3連続) | Warning |
| マスターCPU | MasterCPUUtilization | 50%以上(15分、3連続) | Warning |
| 書き込みスレッドプール | ThreadpoolWriteRejected | 1以上(SUM、差分) | Warning |
| 検索スレッドプール | ThreadpoolSearchRejected | 1以上(SUM、差分) | Warning |
| スナップショット失敗 | AutomatedSnapshotFailure | 1以上(1分、1回) | Critical |
4.2 クラスタ状態チェックAPI
例4:総合クラスタヘルスチェックコマンド集
# クラスタ全体の状態(green/yellow/red)
GET _cluster/health
# インデックス別の状態確認
GET _cluster/health?level=indices
# ノード別のJVM、CPU、ディスク詳細
GET _nodes/stats/jvm,os,fs
# ホットスレッドの確認(高CPU原因分析)
GET _nodes/hot_threads
# スレッドプール状態(待機、拒否数の確認)
GET _cat/thread_pool?v&h=node_name,name,active,queue,rejected
# シャード配置状況
GET _cat/shards?v&h=index,shard,prirep,state,docs,store,node&s=state
# 未割当シャードの原因分析
GET _cluster/allocation/explain
{
"index": "app-logs-000003",
"shard": 0,
"primary": true
}
# インデックス別サイズとドキュメント数
GET _cat/indices?v&h=index,health,pri,rep,docs.count,store.size&s=store.size:desc
# ノード別ディスク使用量
GET _cat/allocation?v&h=node,shards,disk.used,disk.avail,disk.percent
# 保留中のタスクを確認
GET _cat/pending_tasks?v
4.3 Slow Logでボトルネッククエリを発見する
PUT app-logs-*/_settings
{
"index.search.slowlog.threshold.query.warn": "10s",
"index.search.slowlog.threshold.query.info": "5s",
"index.search.slowlog.threshold.fetch.warn": "5s",
"index.indexing.slowlog.threshold.index.warn": "10s",
"index.indexing.slowlog.threshold.index.info": "5s"
}
warnレベルを10秒、infoレベルを5秒に設定すると、10秒以上かかるクエリは即座にアラート対象となる。このログをOpenSearch DashboardsのDiscoverで分析するか、別のインデックスに収集してトレンドを追跡する。
4.4 OpenSearchアラート(Alerting)設定
例5:クラスタ状態モニター + Slackアラート
POST _plugins/_alerting/monitors
{
"type": "monitor",
"name": "Cluster Red Status Alert",
"monitor_type": "query_level_monitor",
"enabled": true,
"schedule": {
"period": { "interval": 1, "unit": "MINUTES" }
},
"inputs": [
{
"search": {
"indices": [".opensearch-sap-log-types-config"],
"query": {
"size": 0,
"query": {
"match_all": {}
}
}
}
}
],
"triggers": [
{
"query_level_trigger": {
"name": "Cluster Status Red",
"severity": "1",
"condition": {
"script": {
"source": "ctx.results[0].hits.total.value >= 0",
"lang": "painless"
}
},
"actions": [
{
"name": "Notify Slack",
"destination_id": "slack-destination-id",
"message_template": {
"source": "クラスタ状態がREDです。\nクラスタ:{{ctx.monitor.name}}\n時刻:{{ctx.periodEnd}}\n即座の確認が必要です。"
},
"throttle_enabled": true,
"throttle": { "value": 10, "unit": "MINUTES" }
}
]
}
}
]
}
実践ティップ: 実際の運用では、_cluster/health APIを定期的に呼び出す外部モニタリング(Prometheus + Grafana、Datadogなど)がより安定的である。OpenSearch自体のアラートはクラスタが不安定な時に一緒に動作しない可能性がある。
5. 障害シナリオと復旧戦略
5.1 主要障害タイプ別対応
| 障害 | 原因 | 影響 | 即時対応 |
|---|---|---|---|
| Redクラスタ | プライマリシャード未割当 | データ損失リスク、該当インデックス書き込み失敗 | _cluster/allocation/explainで原因分析 |
| Yellowクラスタ | レプリカ未割当 | 二重化崩壊、ノード障害時データ損失 | ノード追加またはレプリカ数調整 |
| ディスクフル | ストレージ不足 | ClusterBlockException、全書き込み阻止 | 古いインデックス削除、ISMポリシー点検 |
| JVM OOM | ヒープ圧力 95%超 | ノードクラッシュ、連鎖障害 | 重いクエリをkill、キャッシュクリア |
| Split Brain | マスターノード3台未満 + ネットワーク分離 | データ不整合 | 専用マスターノード3台(3 AZ)構成必須 |
| AZ障害 | AWSインフラ問題 | レプリカ不足時データ損失 | Multi-AZ + レプリカ2構成 |
| マッピング爆発 | dynamic mapping + 非定型フィールド | ヒープ急増、インデキシング遅延 | dynamic: strictまたはdynamic: falseに切替 |
5.2 ディスクフル緊急復旧
クラスタがread-onlyに切り替わった場合、以下の順序で復旧する。
# 1. 最も大きいインデックスを確認
GET _cat/indices?v&h=index,store.size&s=store.size:desc&format=json
# 2. 古い不要なインデックスを削除
DELETE old-logs-2024-*
# 3. read-onlyブロックを解除(全インデックス)
PUT _all/_settings
{
"index.blocks.read_only_allow_delete": null
}
# 4. クラスタレベルのブロックを解除
PUT _cluster/settings
{
"persistent": {
"cluster.blocks.read_only": false
}
}
# 5. クラスタ状態を確認
GET _cluster/health
ディスク使用率が85%を超えると、OpenSearchは自動的にインデックスをread-onlyに切り替える。このしきい値は
cluster.routing.allocation.disk.watermark.flood_stage設定で調整可能だが、根本的にディスクを確保するのが正解である。
5.3 スナップショットと復旧
例6:S3スナップショットリポジトリ登録と復元
// S3リポジトリ登録
PUT _snapshot/s3-backup
{
"type": "s3",
"settings": {
"bucket": "my-opensearch-snapshots",
"base_path": "daily",
"region": "ap-northeast-2",
"server_side_encryption": true,
"role_arn": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
}
}
// 手動スナップショット作成
PUT _snapshot/s3-backup/snapshot-2026-03-04
{
"indices": "app-logs-*",
"ignore_unavailable": true,
"include_global_state": false
}
// スナップショット状態の確認
GET _snapshot/s3-backup/snapshot-2026-03-04/_status
// 特定インデックスのみ復元(名前変更で既存インデックスとの衝突を回避)
POST _snapshot/s3-backup/snapshot-2026-03-04/_restore
{
"indices": "app-logs-000001,app-logs-000002",
"ignore_unavailable": true,
"include_global_state": false,
"rename_pattern": "(.+)",
"rename_replacement": "$1_restored",
"index_settings": {
"index.number_of_replicas": 0
}
}
// 復元完了後にレプリカを復元
PUT app-logs-000001_restored/_settings
{ "index.number_of_replicas": 1 }
include_global_state: falseに設定してセキュリティインデックス(.opendistro_security)との衝突を避ける。常にこのオプションを使用すること。
5.4 DR戦略比較
| 戦略 | RTO | RPO | コスト | 複雑度 |
|---|---|---|---|---|
| スナップショット/復元 | 数時間 | 最後のスナップショット以降 | 低い | 低い |
| Cross-Cluster Replication | 数分 | 1分未満の遅延 | 高い(2倍のクラスタ) | 中 |
| 二重送信(Active-Active) | ほぼ0 | ほぼ0 | 高い(2倍のクラスタ + ルーティング) | 高い |
CCRの注意事項: レプリケーションが12時間以上一時停止するとresumeが不可能である。停止後は最初からやり直す必要がある。
6. AWS OpenSearch Service 運用チェックリスト
6.1 インスタンスタイプの選択
| 用途 | 推奨インスタンス | 備考 |
|---|---|---|
| 小規模プロダクション | r6g.large | データ + マスター兼用可能 |
| 汎用プロダクション | r6g.xlarge 〜 r6g.2xlarge | 価格対性能バランス |
| ログ分析(大容量) | im4gn.* | vCPU対比高ストレージ密度 |
| インデキシング集約 | OR1インスタンス | 価格対性能30%向上(2024+) |
| 専用マスター | 3台 × 3 AZ | 最新世代、常に奇数構成 |
| プロダクション禁止 | t2.*、t3.small | バーストクレジット消耗時CPUスロットリング |
6.2 ストレージティアの活用
| ティア | 用途 | バックエンド | コスト(相対) |
|---|---|---|---|
| Hot | アクティブな読み書き | EBS(gp3推奨) | 100% |
| UltraWarm | 読み取り専用、低頻度クエリ | S3 + キャッシュ | 約40% |
| Cold | アーカイブ、オンデマンド分析 | S3 | $0.024/GiB/月 |
- UltraWarmは約2.5 TiB以上でコスト効率的になる。
- EBSはgp3を使用する — gp2対比9.6%安く、バーストクレジットの心配がない。
6.3 コスト最適化戦略
- ISMによる自動削除 — 保持期間を過ぎたインデックスを自動的にクリーンアップする。
- インデックスロールアップ — 細分化されたデータを集約した後にUltraWarm/Coldへ移動する。
- リザーブドインスタンス — 14日以上安定運用後に購入。1年前払いなし約30%削減、3年全額前払い約50%削減。
- 未使用インデックスの削除 — メンテナンス作業(スナップショットなど)時にもリソースを消費する。
- Auto-Tuneの有効化 — JVM、キューサイズ、キャッシュを自動最適化する。
7. OpenSearch vs Elasticsearch 運用視点比較
| 項目 | OpenSearch | Elasticsearch |
|---|---|---|
| ライセンス | Apache 2.0(完全オープンソース) | SSPL + Elastic License(7.11以降) |
| セキュリティ | 無料内蔵(RBAC、FGAC、監査ログ) | 有料(Platinum+) |
| アラート | 無料プラグイン(Alerting) | Watcher(有料) |
| 異常検知 | 無料プラグイン | ML(有料Platinum+) |
| ライフサイクル管理 | ISM(Index State Management) | ILM(Index Lifecycle Management) |
| SQLサポート | 無料プラグイン + PPL | 有料機能 |
| マネージドサービス | AWS OpenSearch Service | Elastic Cloud(マルチクラウド) |
| ベクトル検索 | k-NNプラグイン(FAISS、nmslib、Lucene) | ネイティブ統合(8.x HNSW) |
| クラウド | AWS中心 | AWS、GCP、Azureサポート |
| リリースサイクル | 約3ヶ月マイナーリリース | 約2週間パッチ、約4ヶ月マイナー |
選択基準のまとめ:
- OpenSearch:AWSインフラ中心、コスト重視、オープンソースライセンス必須、ログ/オブザーバビリティワークロード
- Elasticsearch:Elastic APM/SIEM必要、マルチクラウドデプロイメント、ベクトル検索・RAG重視、Elasticエコシステム(Kibana、Beats、Logstash)活用
8. Elasticsearch → OpenSearch マイグレーションチェックリスト
8.1 マイグレーション方法比較
| 方法 | ダウンタイム | 適合状況 | 複雑度 |
|---|---|---|---|
| スナップショット/復元 | データサイズに比例 | シンプルなマイグレーション、小規模 | 低い |
| ローリングアップグレード | 最小 | ES 6.8-7.10.2 → OS 1.x | 中 |
| Remote Reindex | なし(ライブ) | バージョン間移動、マッピング変更必要時 | 中 |
| Migration Assistant | ほぼなし | 大規模クラスタ、多段階バージョン移動 | 低い(自動化) |
8.2 マイグレーション前チェックリスト
- バージョン互換性確認 — OpenSearch 1.xはES 7.10.2ベース。ES 7.11+(SSPL)ではスナップショット/reindexが必要
- プラグイン互換性監査 — サードパーティプラグインがOpenSearchでサポートされているか確認
- APIパス変更 —
_opendistro/→_plugins/(セキュリティ、アラート、ISMなど全プラグインAPI) - クライアントライブラリの置換 —
elasticsearch-py→opensearch-py、elasticsearch-js→opensearch-js - Kibana → OpenSearch Dashboards 参照名の全数変更
- 全スナップショットバックアップ — マイグレーション開始前に必須
- 機能等価性検証 — 使用中の機能がOpenSearchに存在するか確認(公式互換性マトリクス参照)
- パフォーマンスベンチマーク — 同一クエリセットで既存環境と新環境を比較測定
- ロールバック計画の策定 — マイグレーション失敗時に元のクラスタに戻る手順を文書化
- セキュリティ設定のマイグレーション —
securityadmin.shまたはAPIでロール/ユーザー/テナントを再作成
8.3 Remote Reindex 実践例
例7:リモートクラスタからのライブReindex
POST _reindex
{
"source": {
"remote": {
"host": "https://old-es-cluster:9200",
"username": "admin",
"password": "********",
"socket_timeout": "60m",
"connect_timeout": "30s"
},
"index": "app-logs-2025-*",
"size": 5000,
"query": {
"range": {
"@timestamp": {
"gte": "2025-01-01",
"lt": "2026-01-01"
}
}
}
},
"dest": {
"index": "app-logs-migrated"
},
"conflicts": "proceed"
}
注意:
reindex.remote.allowlist設定にソースホストを登録する必要がある。- 大規模マイグレーションは
wait_for_completion=falseで非同期実行し、GET _tasks/{task_id}で進捗をモニタリングする。 size: 5000は1回のフェッチで取得するscrollサイズである。ネットワーク帯域幅に応じて調整する。
8.4 APIパス変更表
| Elasticsearch / Open Distro | OpenSearch |
|---|---|
_opendistro/_security/ | _plugins/_security/ |
_opendistro/_alerting/ | _plugins/_alerting/ |
_opendistro/_ism/ | _plugins/_ism/ |
_opendistro/_anomaly_detection/ | _plugins/_anomaly_detection/ |
_opendistro/_sql/ | _plugins/_sql/ |
_opendistro/_ppl/ | _plugins/_ppl/ |
_opendistro/_knn/ | _plugins/_knn/ |
9. パフォーマンスチューニングクイックリファレンス
| 設定 | デフォルト | 推奨値 | 効果 |
|---|---|---|---|
index.refresh_interval | 1s | 30s以上(ログ) | CPU/IO削減、検索可視性の遅延 |
index.translog.flush_threshold_size | 512 MiB | JVMヒープの25% | flush頻度の減少 |
index.merge.policy | tiered | log_byte_size(時系列) | @timestamp範囲クエリ性能の改善 |
index.codec | LZ4 | zstd_no_dict | ディスク25-30%削減 |
| バルクリクエストサイズ | — | 5-15 MiB | 5 MiBから開始、性能が頭打ちになるまで増加 |
| バルクバッチ数 | — | 5,000-10,000 docs/_bulk | 単件呼び出し対比劇的なスループット向上 |
indices.memory.index_buffer_size | 10% | 10-15% | インデキシング集約時のバッファ拡大 |
search.max_buckets | 65535 | ワークロードに依存 | 集約クエリの安全制限 |
バルクインデキシング最適化スクリプト:
from opensearchpy import OpenSearch, helpers
client = OpenSearch(
hosts=[{"host": "opensearch-node", "port": 9200}],
http_auth=("admin", "admin"),
use_ssl=True,
verify_certs=False,
)
def generate_actions(file_path):
"""ログファイルを読んで_bulkアクションに変換"""
import json
with open(file_path) as f:
for line in f:
doc = json.loads(line)
yield {
"_index": "app-logs-write",
"_source": doc,
}
success, errors = helpers.bulk(
client,
generate_actions("/var/log/app/events.jsonl"),
chunk_size=5000,
max_retries=3,
request_timeout=60,
)
print(f"Indexed: {success}, Errors: {len(errors)}")
10. セキュリティ強化チェックリスト
| 項目 | 設定 | 備考 |
|---|---|---|
| 通信暗号化 | TLS 1.2以上必須 | ノード間、クライアント間ともに |
| 認証 | SAML / OIDC / Internal DB | AWSはCognitoまたはSAML連携 |
| FGAC | インデックス・フィールド・ドキュメントレベルのアクセス制御 | _plugins/_security/api/roles |
| 監査ログ | 読み書きアクセス記録 | コンプライアンス要件時に必須 |
| IPベースアクセス制御 | VPC + Security Group | パブリックエンドポイント使用禁止 |
| APIキー管理 | 定期的なローテーション | 90日周期推奨 |
まとめ:運用者が覚えるべき7つのこと
- シャードサイズは30-50 GiBを基準に — 小さすぎるとメタデータオーバーヘッド、大きすぎるとリカバリ遅延。
- ISMは先制的に設定 — ディスクが満杯になってから作るのではなく、インデックス作成と同時に適用する。
- モニタリングは階層的に — クラスタ状態 → JVM/CPU → スレッドプール拒否 → スローログの順序で把握する。
- 専用マスターノード3台は交渉不可 — Split Brainを根本的に遮断する唯一の方法である。
- スナップショットは毎日、復元テストは四半期ごとに — 復元を実際に行っていないバックアップはバックアップではない。
- dynamic: strictはデフォルト — マッピング爆発は予防のみが答えである。事後対応はreindexのみ。
- ディスクウォーターマークを常に監視 — 75%で警告、85%でread-only。ISM自動削除が唯一のセーフティネットである。
References
- OpenSearch - Choosing the number of shards (AWS)
- OpenSearch - Operational best practices (AWS)
- OpenSearch - Index State Management
- OpenSearch - ISM Policies
- OpenSearch - Index templates
- OpenSearch - Data streams
- OpenSearch - Tuning for indexing speed
- OpenSearch - Alerting
- OpenSearch - Security configuration
- AWS - Recommended CloudWatch alarms for OpenSearch
- AWS - Sizing OpenSearch Service domains
- AWS - Multi-tier storage for OpenSearch
- AWS - Cross-cluster replication
- AWS - Migrating to Amazon OpenSearch Service
- OpenSearch - Migrate or upgrade
- OpenSearch - Remote reindex
- Benchmarking OpenSearch and Elasticsearch - Trail of Bits (2025)