🔍

AWS OpenSearch Serviceドメインサイジング完全ガイド - インフラエンジニアの実践的設計手法

に公開

はじめに

Splunk運用からAWSマネージドサービスへの移行プロジェクトにおいて、AWS OpenSearch Service(旧Amazon Elasticsearch Service)の適切なサイジング設計が課題となりました。

本記事では、実際のプロジェクトで得た知見をもとに、数式に基づく正確なサイジング手法運用を考慮した設計指針を解説します。

OpenSearch Serviceドメインの基本構成

ドメインとは

OpenSearch Serviceにおける「ドメイン」は、OpenSearchクラスターそのものを指します。

ドメイン = OpenSearchクラスター
├── データノード(実際のデータを格納・処理)
├── 専用マスターノード(クラスター管理)
├── UltraWarmノード(低頻度アクセスデータ)
└── コールドストレージ(アーカイブデータ)

ストレージサイジングの数式化

考慮すべき4つの要素

AWS OpenSearch Serviceでは、以下の要素がストレージ使用量に影響します。

要素 影響度 説明
レプリカ数 データ量×(1+n) 可用性とパフォーマンス向上
インデックス化オーバーヘッド +10% 検索最適化のためのデータ構造
OpenSearch Serviceオーバーヘッド -20% 内部オペレーション用予約領域
OS予約スペース -5% Linux rootユーザー用予約

最小ストレージ要件の計算式

これらの要素を統合した計算式:

必要ストレージ = ソースデータ × (1 + レプリカ数) × \frac{1.1}{0.95 × 0.8}

簡略化すると:

必要ストレージ = ソースデータ × (1 + レプリカ数) × 1.45

実際の計算例

# 例:日次ログデータ 50GB、レプリカ1個、30日分保持
source_data_daily = 50  # GB
replica_count = 1
retention_days = 30

# 総ソースデータ
total_source_data = source_data_daily * retention_days  # 1,500 GB

# 必要ストレージ
required_storage = total_source_data * (1 + replica_count) * 1.45
# = 1,500 * 2 * 1.45 = 4,350 GB

シャード設計の実践的アプローチ

用途別推奨シャードサイズ

検索レイテンシ重視(ダッシュボード等)
├── シャードサイズ: 10-30 GiB
├── 理由: 小さいシャード = 高速検索
└── トレードオフ: 管理オーバーヘッド増

ログ分析重視(大量書き込み)
├── シャードサイズ: 30-50 GiB
├── 理由: 大きいシャード = 高スループット
└── トレードオフ: 検索速度低下

プライマリシャード数の決定

プライマリシャード数 = \frac{(ソースデータ + 将来拡張) × 1.1}{目標シャードサイズ}

設計例

# 現在のデータ: 1TB、年間成長率: 50%、3年間運用想定
current_data = 1000  # GB
growth_rate = 0.5
years = 3

# 将来予測データ量
future_data = current_data * (1 + growth_rate) ** years  # 3,375 GB

# ログ分析用途、40GiBシャード設計の場合
target_shard_size = 40  # GiB
primary_shards = (future_data * 1.1) / target_shard_size
# = 3,712.5 / 40 ≈ 93 プライマリシャード

データノード設計の指針

基本的なリソース比率

AWS推奨の基本比率:

ストレージ100GiB : vCPU 2コア : メモリ 8GiB = 1 : 1 : 4

実践的なインスタンス選択

def recommend_instance_type(storage_per_node_gb):
    """ノードあたりストレージ量からインスタンス推奨"""

    # 基本比率: 100GB storage = 2 vCPU = 8GB RAM
    required_vcpu = (storage_per_node_gb / 100) * 2
    required_memory = (storage_per_node_gb / 100) * 8

    # インスタンスタイプマッピング(例)
    if storage_per_node_gb <= 200:
        return "m6g.large"  # 2 vCPU, 8GB RAM
    elif storage_per_node_gb <= 400:
        return "m6g.xlarge"  # 4 vCPU, 16GB RAM
    elif storage_per_node_gb <= 800:
        return "m6g.2xlarge"  # 8 vCPU, 32GB RAM
    else:
        return "m6g.4xlarge"  # 16 vCPU, 64GB RAM

専用マスターノードの設計理論

なぜ3ノード構成なのか

分散システムにおけるクォーラム(過半数)の概念:

マスターノード数: n
クォーラム: ⌊n/2⌋ + 1

n=1: クォーラム=1, 許容障害=0 ❌
n=2: クォーラム=2, 許容障害=0 ❌
n=3: クォーラム=2, 許容障害=1 ✅
n=5: クォーラム=3, 許容障害=2 ✅ (オーバースペック)

マスターノード容量設計

クラスターサイズ 推奨マスターインスタンス 最大サポート
小規模 (10ノード未満) m6g.medium 30ノード、15Kシャード
中規模 (30ノード未満) m6g.large 60ノード、30Kシャード
大規模 (100ノード未満) m6g.xlarge 120ノード、60Kシャード
超大規模 m6g.2xlarge+ 240+ノード、120K+シャード

ストレージ階層設計

階層化ストレージ戦略

ホットデータ (0-7日)
├── データノード: SSD
├── アクセス頻度: 高
└── レスポンス要件: 100ms以下

ウォームデータ (8-90日)
├── UltraWarm: S3 + キャッシュ
├── アクセス頻度: 中
└── レスポンス要件: 1秒以下

コールドデータ (91日-)
├── コールドストレージ: S3のみ
├── アクセス頻度: 低
└── レスポンス要件: 分単位OK

UltraWarm設計のポイント

def calculate_ultrawarm_nodes(warm_data_gb, shard_size_gb=50):
    """UltraWarmノード数計算"""

    # シャード数計算
    total_shards = warm_data_gb / shard_size_gb

    # AZ考慮(マルチAZの場合、AZ数の倍数必要)
    availability_zones = 3  # マルチAZ想定

    # ノード数(各AZに均等配置)
    nodes_per_az = max(1, total_shards / 10)  # 1ノードあたり10シャード想定
    total_nodes = nodes_per_az * availability_zones

    return int(total_nodes)

実際の設計フロー

実際のプロジェクトでの設計手順を、具体例を使って説明します。

例:Webアプリケーションログの検索基盤構築

要件

  • 日次ログ量: 100GB
  • 保持期間: 90日間
  • 検索レスポンス: 100ms以下
  • 可用性: 99.9%
  • 成長予測: 年30%増、3年間運用

ステップ1: 総データ量の算出

基本データ量 = 100GB × 90日 = 9,000GB

ステップ2: 必要ストレージの計算

必要ストレージ = 9,000GB × (1 + 1レプリカ) × 1.45 = 26,100GB
成長予測込み = 26,100GB × 1.3³ = 57,285GB ≈ 57TB

ステップ3: シャード設計

検索レスポンス重視のため、シャードサイズは20GBに設定:

プライマリシャード数 = 57,000GB ÷ 20GB = 2,850個

ステップ4: ノード構成の決定

データノード

  • ノードあたりストレージ: 1TB(管理しやすいサイズ)
  • 必要ノード数: 57TB ÷ 1TB = 57ノード
  • インスタンスタイプ: m6g.xlarge(4vCPU, 16GB RAM)

マスターノード

  • ノード数: 3個(高可用性)
  • インスタンスタイプ: m6g.medium(1vCPU, 4GB RAM)

ストレージ階層

  • ホット(0-30日): データノード
  • ウォーム(31-90日): UltraWarm 15ノード

運用監視のポイント

重要なメトリクス

ストレージ使用率
├── データノード: 80%以下推奨
├── 警告閾値: 85%
└── 緊急閾値: 90%

シャード健全性
├── シャードサイズ: 目標範囲内
├── 未割り当てシャード: 0個
└── シャード移動: 最小限

クラスター状態
├── ステータス: Green維持
├── マスター切り替え: 異常な頻度でない
└── ノード離脱: 計画的のみ

自動化スクリプト例

import boto3

def monitor_opensearch_capacity(domain_name):
    """OpenSearchドメインの容量監視"""

    client = boto3.client('opensearch')

    # ドメイン情報取得
    response = client.describe_domain(DomainName=domain_name)

    # ストレージ使用率計算
    storage_used = response['DomainStatus']['EBSOptions']['VolumeSize']
    # 実際の使用量は CloudWatch メトリクスから取得が必要

    return {
        'domain': domain_name,
        'storage_provisioned': storage_used,
        'node_count': response['DomainStatus']['ClusterConfig']['InstanceCount']
    }

まとめ

AWS OpenSearch Serviceの適切なサイジングには、以下の要素の理解が重要です:

  1. 数学的アプローチ: 1.45倍の係数を用いた正確な容量計算
  2. 用途別最適化: 検索重視vs分析重視のシャード設計
  3. 可用性設計: 3ノードマスター構成による高可用性
  4. 階層化戦略: ホット・ウォーム・コールドの適切な使い分け

特にインフラエンジニアとして重要なのは、将来の成長を見込んだ設計運用コストとのバランスです。

これらの手法を活用することで、要件を満たしつつコスト効率の良いOpenSearchクラスターを構築できます。

参考資料

Discussion