Lucene 9.5以降のTieredMergePolicy変更とElasticsearchのインデックスマージ設定の最適化

Lucene 9.5におけるマージポリシーの変更点

Lucene 9.5のリリースにより、`TieredMergePolicy`に関連する重要なデフォルト設定が変更されました。具体的には、削除されたドキュメントの許容比率を定めるパラメータ`index.merge.policy.deletePctAllowed`のデフォルト値が、従来の33%から20%へと引き下げられています。さらに、設定可能な最小値も従来の20%から5%まで拡張されました。この変更は、ユーザーからのフィードバックに基づき、より効率的なストレージ管理を実現するために導入されました。

削除ドキュメント許容率(deletePctAllowed)の役割

Elasticsearchでは、データの削除は即座にディスクから抹消される物理削除ではなく、削除マークを付与する論理削除(ソフトデリート)として処理されます。`deletePctAllowed`は、セグメント内においてこの論理削除されたドキュメントがどの程度の割合まで許容されるかを制御するしきい値です。

この比率を下げることで、マージプロセスが頻繁にトリガーされ、削除マーク付きのドキュメントが早期に物理的に削除されます。結果としてストレージの節約につながりますが、マージ処理はCPU、メモリ、およびI/Oリソースを大量に消費するため、過度な設定は書き込みパフォーマンスの低下を招く可能性があります。逆に、比率を高く設定するとリソース消費は抑えられますが、インデックス内に不要なデータが蓄積し、検索時のフィルタリングコストが増加したり、リフレッシュ操作が遅延したりする原因となります。

設定変更がインデックスに与える影響の検証

実際に1,000万件のドキュメントを含むインデックスを作成し、全件更新を行うことで、このパラメータの挙動を確認します。

まず、インデックスを作成しデータを投入します。

PUT /perf_test_index
{
  "mappings": {
    "properties": {
      "message": { "type": "text" }
    }
  }
}

// データ投入後のドキュメント数確認
GET /perf_test_index/_count
{
  "count": 10000000,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  }
}

次に、`_update_by_query`を使用して全ドキュメントを更新し、論理削除を発生させます。

POST /perf_test_index/_update_by_query?wait_for_completion=false
{
  "query": {
    "match_all": {}
  },
  "script": {
    "source": "ctx._source.message = 'modified_content'"
  }
}

更新タスク完了後、デフォルト設定(33%)での統計情報を確認します。

GET /perf_test_index/_stats
{
  "primaries": {
    "docs": {
      "count": 10000000,
      "deleted": 820000 // 削除ドキュメントの割合は約8.2%
    }
  }
}

続いて、設定値を20%に変更し、再度同様の更新処理を実行します。

PUT /perf_test_index/_settings
{
  "index.merge.policy.deletes_pct_allowed": 20
}

設定変更後の更新処理が完了すると、統計情報は以下のように変化しました。

GET /perf_test_index/_stats
{
  "primaries": {
    "docs": {
      "count": 10000000,
      "deleted": 180000 // 削除ドキュメントの割合は約1.8%に減少
    }
  }
}

この結果から、許容比率を下げることで、マージ処理によって削除ドキュメントがより積極的に排除されていることが確認できます。

コミュニティによるパフォーマンス評価

`deletePctAllowed`の引き下げに対しては、リソース消費の増加を懸念する声もあります。マージスレッドは動的にスケーリングする(SCALINGタイプ)ため、設定が厳しすぎるとCPU負荷が高まる可能性があるためです。しかし、コミュニティで実施されたベンチマークテスト(OpenSearch 2.3環境など)では、興味深い結果が報告されています。テストケースでは、更新処理が全体の50%から80%を占める負荷をかけ、33%設定と20%設定を比較しました。その結果、以下の傾向が観測されました。

  • ストレージ容量: インデックスサイズが有意に削減され、ディスク容量の節約につながりました。例えば、更新率75%のテストでは約19.4GBから17.7GBへと容量が削減されています。
  • 検索パフォーマンス: 削除ドキュメントの減少に伴い、検索レイテンシ(特にP90値)が改善しました。
  • システムリソース: 予想されたCPU使用率の急増は見られず、書き込みスループットやインデキシングレイテンシは同等、あるいはむしろ安定する結果となりました。

これらの検証により、多くのシナリオにおいてデフォルト値を20%にすることは、ストレージ効率と検索性能の向上に寄与し、リソース面でも許容範囲内であることが示唆されています。ただし、大規模な本番環境への適用前には、必ず自環境での負荷テストを行う必要があります。

リソースのアイドル時間を活用した最適化アプローチ

パラメータ調整以外にも、システムリソースに余裕がある時間帯を利用してセグメントを最適化する手法が考案されています。従来のマージポリシーに加え、特定のサイズ以下のセグメントに対して、システムが比較的空闲な状態にあるときにのみ強制的なマージを実行する仕組みです。

このアプローチは、ピーク時のパフォーマンスに影響を与えることなく、日常的な運用の中で断片的なリソースを活用してインデックスをクリーンな状態に保つことを目的としています。これにより、`forcemerge`を手動で実行する運用負荷を軽減しつつ、削除ドキュメントの蓄積を防ぐことが可能になります。

タグ: Elasticsearch lucene Indexing PerformanceTuning MergePolicy

7月14日 21:52 投稿