はじめに

検索基盤グループに所属する齊藤です。

検索基盤グループは2022年に発足した組織です。検索精度改善や機械学習モデルの開発とそれを活用した検索機能の実装、さらには技術的負債を解消するための基盤システムの刷新まで、幅広い技術領域の取り組みを推進しています。

「ビズリーチ」では、Elasticsearchの運用基盤として、Elastic社が提供するマネージドサービス「Elastic Cloud」を採用しています。クラウドプロバイダーは主にAWSを利用しているため、本記事もその環境を前提としています。

Elastic Cloudは高可用性やスケーラビリティに優れる一方、インスタンス選定などには独自のノウハウが求められます。ここで紹介する最適化の考え方はその特性を踏まえたものですが、基本的な原則はセルフホスティング環境にも応用できるはずです。

Elasticsearchは非常に強力な検索・分析エンジンですが、その運用、特に大規模環境や多様なユースケースを単一クラスターで賄っている場合には、様々な課題に直面することがあります。

本記事では、私たちが運用していたモノリシックなElasticsearchクラスターが抱えていた問題点と、それを解決するために実施した「クラスター分割」のアプローチ、そしてその結果得られた多くのメリットについて解説します。

モノリシックなクラスターが抱えていた課題

かつて、多くの機能を単一のElasticsearchクラスター(モノリスクラスター)で運用しており、当初は I/O Optimization タイプのインスタンスを利用し、様々な検索ニーズに対応していました。

モノリシックなElasticsearchクラスター構成
旧構成図

このクラスターでは、主に以下のような機能を提供していました。

これらの機能はデータ量、クエリの特性、スループットなどがそれぞれ異なっていましたが、全てが同じリソースを共有していたのです。

機能 データ量 クエリの特性 スループット
レジュメ検索 複雑
求人検索 普通
メッセージ検索 シンプル
新着通知バッチ 複雑かつPercolator利用

単一クラスターでの運用は、初期構築こそシンプルですが、規模の拡大や機能の多様化に伴い、以下のような多くの課題が顕在化してきました。

  1. キャパシティプランニングの困難さ:
    • 特定の機能の負荷が予測しづらく、クラスター全体の適切なリソース(CPU、メモリ、ストレージ)を見積もることが困難でした。
    • 結果として、過剰なリソースを割り当てるか、逆にリソース不足による性能劣化のリスクを抱えることになりました。
  2. メトリクス監視の複雑化:
    • クラスター全体のメトリクス(CPU使用率、JVMヒープ使用率、検索/インデックスレイテンシなど)を監視しても、どの機能がボトルネックになっているのか特定するのが困難でした。
    • 問題発生時の原因究明に時間がかかりました。
  3. ノイジーネイバー問題:
    • 特定のインデックスに対する負荷(例えば、大量データのインデックス処理や複雑な検索が頻発するなど)が急増すると、他の全く関係ない機能のパフォーマンスまで低下させてしまう、いわゆる「ノイジーネイバー問題」が頻繁に発生していました。
    • ある機能のためのメンテナンスが、他の機能のサービスレベルに影響を与えることもありました。
  4. バージョンアップの重荷:
    • Elasticsearchのバージョンアップを行う際、影響範囲が先ほど挙げた機能全体に及ぶため、全ての機能に対する事前調査、テスト、互換性確認が必要となり、膨大なコストと時間がかかりました。
    • 結果として、セキュリティパッチの適用や新機能の利用が遅れがちになり、バージョンが古いまま放置されるリスクも高まっていました。

これらの課題は、サービスの安定性、開発・運用効率、コスト最適化の観点から無視できないものとなっていました。

課題への対処:機能ごとのクラスター分割

これら課題を解消するため、私たちはモノリスクラスターを機能ごとに分割するというアプローチを選択しました。

機能別に分割されたElasticsearchクラスター構成
新構成図

分割にあたっては、単にクラスターを分けるだけでなく、各機能の特性(データ量、クエリの複雑さ、更新頻度、求められる性能要件など)を再評価し、それぞれに最適なインスタンスタイプ (Optimization Type) を選択し直しました。

Optimization Typeの基礎と選定指針

Elastic Cloudの「ハードウェアプロファイル」は、特性に合わせてCPU・メモリ・ストレージのバランスを最適化した、インスタンスのテンプレートです。 また、m6gd や r6gd といったプロファイル名は、その実体であるAWSのEC2インスタンスファミリーに直接対応しています。そのため、名前を見ればそのインスタンスがどういう特性を持つかを判断できます。

選定の原則

Elastic Cloudのプロファイルは随時更新されますが、選定時には次の2点を押さえておくと安全です。

  1. ボトルネックを特定する
    • お使いの環境の主要なボトルネックが「CPU・メモリ・ストレージ」のどれかを明確にする。最適なプロファイル選定の第一指針になります。
  2. ARM系の互換性を確認する
    • c6gdやr6gdなどのGravitonプロファイルはコスト効率に優れますが、アプリケーションやプラグインがARMアーキテクチャに対応しているか事前に確認する。

参考: Selecting the right configuration (Elastic Cloud) / AWS EC2 Instance Types

最適なリソース配分:分割パターンの詳細

機能特性に合わせて、主に以下の3つのパターンでクラスターを設計しました。

パターン1: クエリが複雑(データ量中くらい) - バランス型

パターン2: データ量膨大(クエリはシンプル) - ストレージ特化型

パターン3: Percolator利用 - コンピューティング特化型

パターン 用途例 データ量 クエリの特性 主要リソース消費 選択したOptimization Type
パターン1: バランス型 レジュメ検索、求人検索 複雑 CPU・メモリをバランス良く使用 General purpose (ARM)
パターン2: ストレージ特化型 メッセージ検索 シンプル ストレージ容量が重要 Storage optimized (dense)
パターン3: コンピューティング特化型 新着通知バッチ 複雑(Percolator利用) CPU負荷が高い CPU optimized (ARM)

このように、各機能の要求に合わせてリソースを最適化することで、無駄なコストを削減しつつ、必要なパフォーマンスを確保することが可能になりました。

移行プロセス:段階的な切り替え

モノリスクラスターから新クラスターへの移行は、サービス影響を最小限に抑えるため、慎重に段階を踏んで実施しました。

  1. Step 1: 現行データフローの確認
    • まず、既存のモノリスクラスターへのデータ投入・参照の流れを正確に把握しました。
  2. Step 2: 新クラスター作成
    • 各機能に対応する新しいクラスター群を作成しました。
    • ポイント: 全てのクラスターを全環境で同時期に作成することが重要です。Elastic Cloudでは、時期によって利用可能なElasticsearchのバージョンが異なる場合があります。テストの整合性を保つ観点から、バージョンを揃えて同時に作成することを推奨します。コストを最小限に抑えるため、最初は最小スペックで作成し、リリース時期にあわせてスケールアップしました。
      新クラスター作成の手順
      移行手順1
  3. Step 3: データ同期(ダブルライト)開始
    • アプリケーションからのデータ書き込みを、既存のモノリスクラスターと新しい機能別クラスターの両方に行う「ダブルライト」を開始しました。
    • これにより、新旧両方のクラスターでデータの一貫性を保ちます。
      ダブルライト実施の手順
      移行手順2
  4. Step 4: 新クラスターへのデータ同期
    • 過去のデータを、新クラスターへ移行しました。
    • このタイミングで新旧両方のクラスターでデータが完全に同期されます。
  5. Step 5: アプリケーションの参照先切り替え
    • ダブルライトとデータ洗い替えが完了し、新旧クラスターのデータが一致していることを確認した後、アプリケーションのデータ参照先をモノリスクラスターから新しい機能別クラスターへと切り替えました。
    • 機能ごとに段階的に切り替えを実施し、問題発生時の影響範囲を限定しました。
    • ポイント: 参照先の切り替えは機能ごとに段階的にリリースすることが重要です。これにより、万が一障害が発生した際、影響範囲を最小限にとどめることができます。事前に綿密なテストをすることはもちろん重要ですが、影響範囲が膨大になる場合は、障害時の影響範囲と影響時間を最小限に抑えられるフローを選択することも大切です。
      参照先切り替えの手順
      移行手順3
  6. Step 6: 旧クラスターの廃止
    • 移行完了後、モノリスクラスターは不要となり、廃止しました。
      旧クラスター廃止の手順
      移行手順4

クラスター分割の結果:得られたメリット

クラスター分割によって、当初抱えていた課題は解消され、多くのメリットを得られるようになりました。以下に、各課題に対応する形で得られたメリットを説明します。

  1. キャパシティプランニングの困難さの解消:
    • 機能ごとに独立したクラスターとなったことで、各機能の負荷特性に合わせた適切なリソース配分が可能になりました。
    • 各機能に最適なインスタンスタイプを選択できるようになり、過剰なリソース割り当てを避けつつ、必要な性能を確保できるようになりました。
    • 結果として、リソースの無駄を削減し、全体で25%のコスト削減に成功しました。
  2. メトリクス監視の改善:
    • クラスターごとに監視対象が明確になり、どの機能でどれだけの負荷がかかっているかが一目瞭然になりました。
    • CPU、メモリ、レイテンシなどのメトリクスから、ボトルネックの特定やパフォーマンスチューニングが格段に容易になりました。
    • 問題発生時の原因究明が迅速化され、トラブルシューティングの効率が大幅に向上しました。
  3. ノイジーネイバー問題の解消:
    • 機能ごとにクラスターが分離されたことで、ある機能の高負荷や障害が他の機能に影響を与えなくなりました
    • 特定の機能のためのメンテナンスも、他機能のサービスレベルを気にすることなく実施できるようになりました。
    • これにより、システム全体の可用性と信頼性が大幅に向上しました。
  4. バージョンアップの容易化と迅速化:
    • バージョンアップの影響範囲が機能単位に限定されるため、事前調査やテストのスコープが大幅に縮小されました。
    • これにより、より迅速かつ安全にバージョンアップを実施できるようになり、セキュリティパッチの適用や新機能の早期導入が可能になりました。
    • 万が一、バージョンアップ後に問題が発生した場合でも、影響を受けるのはその機能クラスターのみとなり、リスクを限定できます。

これらのメリットは、サービスの安定性向上、運用効率の改善、コスト最適化、そして開発サイクルのスピードアップに大きく貢献しています。モノリスクラスターが抱えていた構造的な課題を根本から解決することで、より持続可能なElasticsearch運用体制を確立することができました。

今後の展望と新たな課題

クラスター分割は多くのメリットをもたらしましたが、一方で新たな側面も考慮する必要があります。

まとめ

Elasticsearchのモノリスクラスター運用は、初期段階では有効な場合もありますが、システムの成長と共に多くの課題を生み出す可能性があります。機能や特性に応じてクラスターを分割することで、以下のような非常に大きなメリットをもたらします。

もしモノリスクラスターの運用に課題を感じているのであれば、クラスター分割は検討に値する強力な選択肢となります。本記事が、Elasticsearch運用改善の一助となれば幸いです。

齊藤 拓希
齊藤 拓希

ビズリーチ事業部のエンジニア。2015年新卒入社。どうやって子どもをエンジニアの沼に引きずり込むか、日々模索中です