現代アプリケーションの進化に伴い、リアルタイムデータ処理と取得ニーズが増加しているため、スケーラビリティも重要です。Elasticsearchは、データを大規模なセットで効率的に処理し、高速クエリを処理するのに非常に優れたオープンソースの分散型検索および分析エンジンの1つです。ただし、Elasticsearchを効果的にスケーリングするプロセスは微妙であり、その背後にあるアーキテクチャとパフォーマンスのトレードオフを正しく理解する必要があります。
Elasticsearchの分散性により、水平方向にスケーリングすることができますが、これによりデータの分散方法やクエリの提供方法に関する複雑さが増します。Elasticsearchをスケーリングする際の理論的な課題の1つは、その固有の分散性です。ほとんどの実用的なシナリオでは、スタンドアロンノード上の読み取りは常にシャーディングされたクラスタ上の読み取りよりも優れたパフォーマンスを発揮します。これは、シャーディングされたクラスタでは、データの所有権が複数のノードに分散されているためです。つまり、すべてのクエリは複数のリクエストを異なるノードに送信し、結果を協調ノードで集約し、結果を返す必要があります。この追加のネットワークオーバーヘッドにより、データアクセスが直接的である単一ノードアーキテクチャと比較して、レイテンシが増加する可能性があります。
この点において、シャーディングされたクラスタは、Elasticsearchを大規模データセット、高トラフィック、およびほぼリアルタイムのインデックス作成にスケーリングするための基本です。データをノード間で分散させるバランスとクエリのレイテンシを低く保つことの微妙なバランスを理解することが、最適なパフォーマンスを実現するための重要なポイントです。さらに、この記事では、Elasticsearchのスケーラビリティの理論的側面、クラスタパフォーマンスの最適化の実践的戦略、および実世界での展開経験から得られた教訓について取り上げます。
Swooのライブストリーミングおよびゲームアプリでは、Elasticsearchがすべての検索機能の基盤となっており、ユーザーの成長とともにうまく機能していました。並行ユーザー数が150,000を超えた瞬間、検索ページが時折失敗し始め、Elasticsearchクラスタにボトルネックがあることは明らかでした。これはライブゲーム環境にとって受け入れがたい状況となり、一連の最適化を行うことになり、最終的には検索とホームページの両方の体験が安定しました。
スケーラビリティのためのElasticsearchアーキテクチャの理解
Elasticsearchはネイティブに分散アーキテクチャをサポートしており、システムは非常にスケーラブルですが、同時に従来の単一ノードソリューションと比較してより複雑です。Elasticsearchはデータをインデックスに分割し、各インデックスはさらにシャードに分割されます。シャードはElasticsearchにおけるデータストレージおよびインデックス作成の基本単位です。システムは検索操作をクラスタの複数のノードに分散し、並列化します。
典型的なクラスタには、検索クエリを実行するデータのサブセットをホストする複数のデータノードが含まれます。デフォルトでは、Elasticsearchはデータをノード間で自動的に分散できるため、各ノードはクエリ負荷の一部のみを実行します。このようにして、Elasticsearchは水平にスケールします:ノードを追加することで、ますます多くのデータを処理し、ますます多くのリクエストに応えることができます。
スケーラビリティとクエリパフォーマンスのトレードオフは、もちろん、Elasticsearchクラスタを設計する際に考慮すべき最も重要な要素の1つです。特に、高い書き込みスループットと低い読み取りレイテンシを必要とするアプリケーションでは、そのような課題に対処するために、クラスタの注意深い構成と最適化技術の組み合わせが求められます。
要するに、Swooのケースでは、Elasticsearchクラスタにはいくつかのデータノードと3つの専用マスターノードがありました。各ノードは8コアCPUと16 GB RAMで動作し、主にリアルタイムのインデックス作成とゲームイベントの瞬時の検索を目的としています。高い同時性で作業しているため、ノード間のレイテンシを最小限に抑えるために、非常に大きなネットワーク帯域幅を割り当てる必要があります。
スケーリング戦略の計画
言い換えれば、Elasticsearchを効果的にスケーリングするには、現在のパフォーマンスメトリクスの分析、ボトルネックの設定、およびスケーラビリティに関する明確な目標が必要です。たとえば、クエリのレイテンシ、スループット、およびクラスタの健康状態を監視し、クラスタの制限を理解することが重要です。ホットシャード、CPUのスパイク、およびメモリの問題を特定することで、最適化のためのロードマップを作成できます。
Elasticsearchのスケーリングにおいて注意が必要なもう一つの重要な活動はキャパシティプランニングです。ディスク使用量、トラフィックのパターン、データの保持要件を見積もることで、クラスターが適切にサイズ設定されていることを確認できます。一般的に言えば、水平スケーリング(クラスターへのノードの追加)が、データとトラフィックの量が増加する際の最良のアプローチです。しかし、この場合、縦のスケーリング-個々のノードのリソースをアップグレードすること-が効果的である可能性もあります。
私たちの予測では、アクティブユーザーが毎月約10-15%成長し、各ユーザーがゲームを使用する過程でかなりの量のイベントデータを生成することが示されました。これに基づいて、クラスターが同時クエリの健康的な増加を維持し、インデックスされたドキュメントのボリュームが増加することを期待しました。したがって、データノードを追加して水平にスケーリングするか、現在のノードをアップグレードして垂直にスケーリングするかが、この増加に対してより適切であるかを分析しました。
コアスケーリング技術
Elasticsearchの最適化には、システムの異なる側面をターゲットにしたいくつかの戦略が含まれます。これらの中で、最も効果的な技術には、データの取り込み最適化、シャード管理、メモリ使用量の最適化が含まれます。
焦点はデータの取り込みです。Elasticsearchはネイティブで大規模なドキュメントのバッチを一度に送信できる大容量インデックスをサポートしています。これによりオーバーヘッドが削減され、一般的にインデックス処理が迅速化されます。次に、リフレッシュ間隔を微調整することでデータの迅速な取り込みに大きな影響を与えるかもしれません。1秒のデフォルトリフレッシュ間隔を10秒などの高い値にオーバーライドすることで、クラスターに頻繁なリフレッシュのストレスが軽減され、書き込みが速くなります。
Elasticsearchの拡張性機能を構成する主要な理由には、シャード管理などがあります。Elasticsearchはシャーディングを介して水平方向にスケーリングできますが、不適切なシャードサイズ設定は実際にパフォーマンスの低下につながります。シャード数が高すぎるか低すぎると、インデックス速度やクエリパフォーマンスが低下します。最適なパフォーマンスを実現するためにはバランスが重要です。
もちろん、Elasticsearchのスケーリングにおいてメモリ管理も非常に重要な要素です。JVMヒープサイズの最適化、フィールドデータキャッシュの設定、およびクエリキャッシュの有効化により、リソースの消費を削減し、クエリのパフォーマンスを向上させることができます。適切なメモリ使用と適切なキャッシュ設定は、メモリ不足エラーを防ぎ、ガベージコレクションのオーバーヘッドを最小限に抑えることができます。
Elasticsearchへの負荷が増大した要因の1つは、リアルタイムゲームデータの連続的な取り込みにありました。私たちはBulk APIを介してドキュメントのバッチ処理を最適化しました。特定のピーク負荷時には、バッチサイズをさらに増やしたり、リフレッシュ期間を延ばすことで、ほぼリアルタイムのインデックス作成と一般的なクラスタの安定性との適切なトレードオフを実現できました。
高度なスケーリングソリューション
規模が大きくなると、Elasticsearchはより高度なテクニックが必要になります。その中でも、クエリの最適化が際立ちます。シャード数を最小限に抑える効率的なクエリを書くことで、クエリのレイテンシを大幅に削減することができます。たとえば、顧客IDや製品カテゴリなどのキーを使用してクエリを特定のシャードにルーティングするカスタムルーティングを行うことができます。これにより、Elasticsearchはすべてのシャードを検索する必要がなくなり、時間とリソースの消費が削減されます。
ILM(Index Lifecycle Management)は、データセットが経時的に変化するにつれてElasticsearchを微調整するための素晴らしい機能です。ホット-ウォーム-コールドアーキテクチャをスケーリングすることで、古いデータを遅い、安価なストレージに移動させながら、より関連性の高いデータを高速でアクセス可能なストレージに保持することができます。クラスタが成長してもクラスタのパフォーマンスを維持できます。
Elasticsearchのスケーラビリティに関する最終的な議論トピックは、ハードウェアの考慮事項です。クラスタが成長するにつれて、ハードウェアが増加した負荷に適切に対応できるようにする必要があります。ノードが効率的に動作するために、CPU、メモリ、およびディスクI/Oが適切に供給されていることを確認する必要があります。特に高速なデータアクセス速度が必要とされるインデックス作成や検索操作には、SSDやNVMeドライブがパフォーマンスを大幅に向上させます。
新しいインデックスにデフォルトのシャード数だけを割り当てると、ホットスポットの問題に直面することがわかりました。ゲームプラットフォームからのリアルタイムの大量の更新がある場合、複数の小さなシャードに再分散されたヘビーライトのインデックスに適切にレプリカを調整することで、シャードが過負荷にならない絶妙なバランスを見つけました。
理論的な洞察と最適化のトレードオフ
上記の実践的な最適化に加えて、Elasticsearchのスケーリングに関するいくつかの興味深い理論的考察があります。1つの重要な洞察には、分散システム内でのスケーラビリティとクエリパフォーマンスのトレードオフが関わっています。特に、シャード化されたクラスタは水平方向にスケーラブルですが、複数のノードからの結果を結合する必要があるため、クエリのオーバーヘッドが増加します。これは、データがローカルマシンに存在し、クエリを他のノードに“通信”することなく実行できる単一ノードとは対照的です。このトレードオフを理解することは、パフォーマンスとスケーラビリティをバランスさせる必要があるElasticsearchクラスタを設計する際に重要です。
もう1つのより理論的なElasticsearchのスケーリングの側面は、データの局所性の概念です。関連するシャードデータをホストしているローカルノードに対してのみクエリを実行でき、preference=local
クエリパラメータを使用することができます。これにより、クロスノード間の通信が最小限に抑えられ、クエリの遅延が低減されます。これは、データ複製と負荷分散から生じる課題を軽減することができます。ElasticsearchのAdaptive Replica Selectionアルゴリズムは、現在の状況下で最適なレプリカノードを選択することでクエリの実行を最適化しようとします。ただし、これがクエリの実効性をもたらすとは限りません。
私たちの環境で経験した最初の障害波は、高いJVMヒープ圧に関連しています。 Elasticsearchサーバーは最初は最小のヒープ割り当てで稼働しており、高いクエリ負荷の下でかなり頻繁なガベージコレクションサイクルが発生していました。私たちはJVMの調整によってこれを解決しました。特に、最小ヒープサイズと最大ヒープサイズを8GBに合わせることで、Elasticsearchにクエリを処理する十分な余地を与え、ヒープを過度に負荷をかけずに処理できるようにしました。
一般的な落とし穴と解決策
もちろん、Elasticsearchのスケーリングには課題があります。避けたい一般的な間違いには、適切なシャードのサイズ設定、モニタリングの不足、キャッシュへの過度な依存、適切なインデックスライフサイクル管理の不使用があります。これらは、積極的な構成チューニングによって早期に診断されれば、多くの時間とリソースを節約できます。
主な落とし穴の1つは、Elasticsearchのデフォルト設定を調整しなかったことでした。メモリの割り当てやシャードの管理に関して、デフォルトは中程度のトラフィック条件下では問題なく機能しましたが、ピーク時のトラフィックではダウンしました。私たちの修正策は多層的でした。ヒープの割り当ての見直し、ホットなインデックスの複製、繰り返しクエリのための短期キャッシングを行いました。これにより、クラスタ全体での繰り返しの障害を防ぎ、タイムアウトが非常に大幅に削減されました。
実装ガイド
Elasticsearchのスケーリングには、計画、テスト、展開、その後のメンテナンスが必要です。良い慣行、構成テンプレート、本番環境に新しい変更を展開する前にクラスターを徹底的にテストすることで、長期にわたって安定したクラスターに問題なくスケーリングすることができます。
- JVMパラメータを微調整します。ElasticsearchサーバーごとにXmsとXmxをそれぞれ8GBに設定し、システムメモリとヒープ要件のバランスを取りました。
- シャード分散の最適化。大規模なインデックスをより小さなサイズのシャードに分割してホットスポットを防ぎ、最もアクティブなインデックスのレプリカのスケーリングを行いました。これによりクエリトラフィックがクラスタ全体に均等に分配されることを確認しました。
- 短いTTLキャッシュの有効化。ホームページで頻繁に使用される静的クエリに1秒のキャッシュウィンドウを適用し、これによりリアルタイムの応答性を損なうことなく、Elasticsearchへの繰り返しリクエストの負荷が大幅に軽減されることを確認しました。
- モニタリングと継続的な改善。Kibanaを使用し、シャードの健全性、JVMのパフォーマンス、クエリの待ち時間をリアルタイムで観察するためのカスタムダッシュボードを作成しました。これらのメトリクスに基づいて、継続的な微調整が行われました。
先を見据えた計画やテックスタックの拡張
さらに、成長に備えて、ホット・ウォーム・コールドのインデックスライフサイクルの管理を検討し、より頻繁にアクセスされないデータを安価なノードに移動させつつ、リアルタイムのインデックス作成とクエリに上位ハードウェアを維持します。また、異常なクエリのスパイクや遅延がユーザーエクスペリエンスに影響を与える前に、事前に検出するための高度なモニタリングソリューションやAI駆動の異常検出を検討しています。
結論
Elasticsearchのスケーリングには、アーキテクチャの理解、慎重な計画、およびベストプラクティスの実施が必要です。 Elasticsearchはシャーディングを通じて水平方向にスケーリングされますが、最適なパフォーマンスを実現するためにはいくつかの課題を把握する必要があります。 Elasticsearchクラスターの高いスケーラビリティとパフォーマンスを確保するためには、適切なデータ取り込み、シャード管理、メモリ使用、およびクエリの最適化が重要です。
一方、SolrからElasticsearchへの移行が必要であった場合、純粋に技術的な問題だけでなく、分散システムに実際に隠れている理論的な難しさを理解することが重要でした。このような慎重な調整と創造的な問題解決により、クエリのパフォーマンスを向上させることで、大規模なマルチベンダーシングルElasticsearchクラスターを育成し、1日に数百万のクエリを受信することができます。 Elasticsearch展開をスケーリングする際には、理論的要素と実践的要素が組み合わさり、長期的な成功を確保します。
Source:
https://dzone.com/articles/how-to-scale-elasticsearch-to-solve-scalability-issues