本番環境でのElasticsearch —展開のベストプラクティス

Elasticsearchは、最新のデータ分析用に高度に最適化された検索エンジンです。

Elasticsearchは、驚くべきリアルタイムの検索および分析エンジンです。 Apache Lucene上に構築されています。配布されており、RESTfulで、使いやすく、可用性が高いです。 Elasticsearchのユースケースには、検索の強化、トランザクションの監視とエラー検出、コンテンツ検出、ログ分析、ファジー検索、イベントデータの集約、データの視覚化が含まれます。 Elasticsearchとその他のElastic Stackは非常に用途が広いことが実証されており、上記のユースケースを見るとわかるように、Elasticsearchを現在の製品に提供し、さらに洞察を追加する方法は複数あります。

ボットメトリックの検索と分析に頻繁に使用し、1日に約10億件のドキュメントのインデックスを作成し、リアルタイムでのデータの視覚化に非常に複雑な集計を使用しています。

ただし、アプリケーションのブートストラップと本番環境での実行と保守はまったく異なります。この記事は、実生活でのこれらの要因の多くをカバーしており、本番環境でElasticsearchを実行するために考慮する必要がある基本的な共通項目です。

メモリ:

ElasticsearchとLuceneはJavaで記述されているため、ヒープスペースとJVMの統計に注意する必要があります。 Elasticsearchで利用できるヒープが多いほど、クエリパフォーマンスを向上させるためにフィルターやその他のキャッシュに使用できるメモリが増えます。ただし、ヒープが多すぎると、ガベージコレクションの一時停止が長くなる可能性があることに注意してください。 JVMが圧縮オブジェクトポインター(圧縮OOP)に使用するカットオフより上にXmxを設定しないでください。正確なカットオフはさまざまですが、32 GB近くです。

一般的な問題は、大きすぎるヒープの構成です。 64 GBのマシンがあります。そして、gollyによって、Elasticsearchに64 GBのメモリすべてを提供したいと考えています。多いほど良い! Elasticsearchにとってヒープは間違いなく重要です。多くのメモリ内データ構造で使用され、高速動作を提供します。しかし、そうは言っても、ヒープの外にあるメモリのもう1つの主要なユーザーがあります:OSファイルキャッシュ

Luceneは、メモリ内のデータ構造をキャッシュするために基盤となるOSを活用するように設計されています。 Luceneセグメントは個別のファイルに保存されます。セグメントは不変であるため、これらのファイルは変更されません。これにより、非常にキャッシュフレンドリーになり、基盤となるOSは、ホットセグメントをメモリに常駐させて、アクセスを高速化します。これらのセグメントには、逆索引(全文検索の場合)とdoc値(集約の場合)の両方が含まれます。 Luceneのパフォーマンスは、OSとのこの相互作用に依存しています。ただし、Elasticsearchのヒープに使用可能なすべてのメモリを割り当てた場合、OSファイルキャッシュの残りはなくなります。これはパフォーマンスに深刻な影響を与える可能性があります。標準的な推奨事項は、使用可能なメモリの50%をElasticsearchヒープに割り当て、残りの50%は空きのままにすることです。未使用になりません。 Luceneは、ファイルキャッシュに残っているものを喜んで消費します。 Elasticsearchヒープは、次の方法で構成できます。

エクスポートES_HEAP_SIZE = 10g

または

ES_JAVA_OPTS = "-Xms10g -Xmx10g" ./bin/elasticsearch

CPU:

Elasticsearchは、集計とフィルターされたクエリをサポートします。複雑なフィルター処理されたクエリ、集中的なインデックス作成、パーコレーション、およびインデックスに対するクエリの実行には重いCPUが必要であるため、適切なものを選択することが重要です。 CPUの仕様と、クエリがJVMで実行される際のJavaでの動作を理解する必要があります。

各プールは多数のスレッドを実行します。これらのスレッドは構成可能で、キューがあります。 Elasticsearchはコアを動的に割り当てるため、非常に具体的な要件がない限り、これを変更することはお勧めしません。

スレッドプールタイプ:

Elasticsearchには3種類のスレッドプールがあります。

  1. キャッシュ:キャッシュされたスレッドプールは、保留中の要求がある場合にスレッドを生成する無制限のスレッドプールです。このスレッドプールは、このプールに送信された要求がブロックまたは拒否されないようにするために使用されます。このスレッドプール内の未使用のスレッドは、キープアライブが期限切れになると終了します(デフォルトは5分)。キャッシュされたスレッドプールは、汎用スレッドプール用に予約されています。
  2. 修正済み:固定スレッドプールは、固定サイズのスレッドを保持して、処理するスレッドを持たない保留中の要求のキュー(オプションで制限されている)で要求を処理します。サイズパラメータはスレッドの数を制御し、デフォルトではコアの数に5を掛けた値になります。
  3. スケーリング:スケーリングスレッドプールは、動的なスレッド数を保持します。この数はワークロードに比例し、1からサイズパラメーターの値まで変化します。

Elasticsearchは、CPU使用をさまざまなタイプのスレッドプールに分割します。

  • ジェネリック:ディスカバリーやスレッドプールタイプなどの標準操作の場合はキャッシュされます。
  • インデックス:インデックス/削除操作用。スレッドプールの種類が修正されました。
  • 検索:カウント/検索操作。スレッドプールの種類が修正されました。
  • get:get操作用。スレッドプールの種類が修正されました。
  • bulk:バルク索引付けなどのバルク操作用。スレッドプールの種類が修正されました。バルクドキュメントの最適な構成は、クラスター構成によって異なります。これは、複数の値を試すことで特定できます。
  • 浸透:浸透のため。スレッドプールの種類が修正されました。
  • リフレッシュ:リフレッシュ操作用。スレッドプールタイプはスケーリングです。

特定のスレッドプールを変更するには、そのタイプ固有のパラメーターを設定します。

続きを読むhttps://www.elastic.co/guide/en/elasticsearch/reference/2.2/modules-threadpool.html#types

破片サイズ:

シャードは、Elasticsearchがクラスター内でデータを配信する単位です。 Elasticsearchがデータのリバランス時にシャードを移動できる速度。障害発生後、シャードのサイズと数、およびネットワークとディスクのパフォーマンスに依存します。

Elasticsearchでは、各クエリはシャードごとに単一のスレッドで実行されます。ただし、同じシャードに対する複数のクエリおよび集計と同様に、複数のシャードを並行して処理できます。

これは、キャッシングが関与しない場合の最小クエリ遅延は、データ、クエリのタイプ、シャードのサイズに依存することを意味します。多数の小さなシャードを照会すると、シャードごとの処理が高速になりますが、より多くのタスクをキューに入れて順番に処理する必要があるため、少数の大きなシャードを照会するよりも必ずしも高速になるとは限りません。多数の小さな断片があると、複数の同時クエリがある場合、クエリのスループットも低下する可能性があります。

各シャードには、メモリに保持する必要があるデータがあり、ヒープ領域を使用します。これには、データがディスク上のどこに存在するかを定義するために、シャードレベルおよびセグメントレベルで情報を保持するデータ構造が含まれます。これらのデータ構造のサイズは固定されておらず、ユースケースによって異なります。ただし、セグメント関連のオーバーヘッドの1つの重要な特徴は、セグメントのサイズに厳密に比例しないことです。つまり、セグメントが大きいほど、小さいセグメントに比べてデータ量あたりのオーバーヘッドが少なくなります。違いはかなり大きい場合があります。適切な数のシャードを選択するのは複雑です。開始する前に取得できるドキュメントの数がわからないためです。多数のシャードを持つことは、クラスターにとって良いことであり、ひどいことです。インデックスとシャードの管理はマスターノードに過負荷をかける可能性があり、応答しなくなり、奇妙で厄介な動作を引き起こす可能性があります。マスターノードに、クラスターサイズに対処するのに十分なリソースを割り当てます。

悪いことは、シャードの数が不変であり、インデックスの作成時に定義されることです。インデックスが作成されたら、シャードの数を変更する唯一の方法は、インデックスを削除し、再度作成して、インデックスを再作成することです。

複製

Elasticsearchは複製をサポートし、データはデータノード間で複製されるため、ノードが失われてもデータは失われません。デフォルトの複製係数は1ですが、製品の要件に応じて増加させることができます。レプリカが多いほど、データの耐災害性が高まります。レプリカを増やすもう1つの利点は、各ノードがレプリカシャードを保持することです。これにより、レプリカもクエリに使用されるため、クエリのパフォーマンスが向上します。

Elasticsearchが一貫性のために使用する複製式は、

(プライマリ+レプリカの数)/ 2 + 1

割り当ての最適化

製品データ要件に基づいて、データをホットとコールドに分類できます。他のインデックスよりも頻繁にアクセスされるインデックスには、より多くのデータノードを割り当てることができますが、アクセス頻度の低いインデックスには少ないリソースを割り当てることができます。この戦略は、アプリケーションログ(例:ELK)などの時系列データを保存する場合に特に役立ちます。

これは、定期的にインデックスを異なるノードに移動するcronjobを実行することで実現できます。

ホットノードは、クラスター内のすべてのインデックス作成を実行するデータノードの一種です。これらは一般に最も頻繁にクエリされる傾向があるため、最新のインデックスも保持します。インデックス作成はCPUおよびIOを集中的に使用する操作であるため、これらのサーバーは強力であり、接続されたSSDストレージによってバックアップされる必要があります。高可用性のために、最低3つのホットノードを実行することをお勧めします。ただし、収集およびクエリする最近のデータの量によっては、パフォーマンスの目標を達成するためにこの数を増やす必要があります。

ウォームノードは、頻繁にクエリされる可能性が低い大量の読み取り専用インデックスを処理するように設計されたデータノードの一種です。これらのインデックスは読み取り専用であるため、ウォームノードはSSDの代わりに大きな接続ディスク(通常は回転ディスク)を使用する傾向があります。ホットノードの場合と同様に、高可用性のために最低3つのウォームノードをお勧めします。前と同様に、パフォーマンス要件を満たすために大量のデータには追加のノードが必要になる可能性があることに注意してください。また、CPUとメモリの構成では、多くの場合、ホットノードの構成をミラー化する必要があることに注意してください。これは、実稼働環境で発生するものと同様のクエリでテストすることによってのみ判断できます。

ホットノードとウォームノードの詳細については、こちらを参照してください。

適応できるもう1つの戦略は、インデックスをs3にアーカイブし、それらのインデックスからデータが必要になったときに復元することです。詳細については、こちらをご覧ください。

ノードトポロジ:

Elasticsearchノードは、マスターノード、データノード、クライアントノードの3つのカテゴリに分類できます。

  1. マスターノード:マスターノードは、インデックス/シャードを保存しないため、データノードでもない場合、小さくすることができます。その責任は、詳細なクラスター状態を保存し、インデックス/シャードメタデータルックアップでデータと他のノードを支援することです。 Elasticsearchには、スプリットブレインの問題を回避するために複数のマスターノードが必要です。
  2. データノード:データノードは、実際のインデックスデータの保存/クエリを担当します。
  3. クライアントノード:クライアントノードは、インデックス作成と検索のプロキシとして使用されます。集約が頻繁に使用される場合、これを強くお勧めします。これらは、データにもマスターにも適格ではない特別なElasticSearchノードです。クライアントノードはクラスターに対応しているため、スマートロードバランサーとして機能できます。クエリをクライアントノードに送信すると、各データノードからクエリ結果に対する応答を収集するという高価なタスクを引き受けることができます。

これらの設定を各ノードのelasticsearch.ymlファイルに追加します。

マスターノード:node.master:true node.data:false
データノード:node.master:false node.data:true
クライアントノード:node.master:false node.data:false

トラブルシューティングのヒント:

Elasticsearchのパフォーマンスは、インストールされているマシンに大きく依存します。 CPU、メモリ使用量、ディスクI / Oは、各Elasticsearchノードの基本的なオペレーティングシステムメトリックです。 CPU使用率が急上昇した場合は、Java仮想マシン(JVM)メトリックを調べることをお勧めします。次の例では、スパイクの理由は、ガベージコレクションアクティビティの増加です。

  1. ヒープのプレッシャー:高いメモリプレッシャーは、クラスターのパフォーマンスに対して2つの方法で機能します。これらのCPUサイクルは、ガベージコレクションが有効な場合のユーザーリクエストの処理には使用できません。その結果、システムのリソースがますます制約されるにつれて、ユーザー要求の応答時間が長くなります。メモリの負荷が上昇し続け、100%近くに達すると、より積極的な形式のガベージコレクションが使用され、クラスターの応答時間が劇的に影響を受けます。 Index Response Timesメトリックは、高いメモリ負荷がパフォーマンスに大きな影響を与えることを示しています。
  2. JVMの非ヒープメモリが増加し、ページキャッシュ用のメモリを使い果たし、カーネルレベルのOOMリーピングを引き起こす可能性があります。
  3. スプリットブレインの問題を避けてください。スプリットブレインは、クラスターが分割されるシナリオです。たとえば、6ノードのクラスターがあるとします。 2つのノードがクラスターから切断されますが、それらはまだお互いを見ることができます。これらの2つのノードは、別のクラスターを作成します。彼らは彼ら自身の中から新しいマスターを選出するでしょう。同じ名前の2つのクラスターがあり、1つは4ノード、もう1つは2ノードです。それぞれにマスターノードもあります。これは、ESクラスターのスプリットブレイン問題と呼ばれるものです。これを回避するには、ESパラメーターdiscovery.zen.minimum_master_nodesをノード数の半分+ 1に設定します。
  4. Elasticsearchはストレージデバイスを頻繁に使用するため、ディスクI / Oを監視することで、この基本的なニーズを確実に満たすことができます。ディスクI / Oの削減には多くの理由があり、多くの種類の問題を予測するための重要なメトリックと考えられています。インデックス作成の有効性とクエリパフォーマンスを確認するのに適したメトリックです。読み取りおよび書き込み操作を分析すると、特定のユースケースでシステムが最も必要とするものが直接示されます。ディスクI / Oのオペレーティングシステム設定は、他のすべての最適化の基本であり、ディスクI / Oを調整することで潜在的な問題を回避できます。それでもディスクI / Oが十分でない場合は、シャードの数とサイズの最適化、マージの調整、遅いディスクの交換、SSDへの移動、ノードの追加などの対策をI / Oの原因に応じて評価する必要がありますボトルネック。
  5. 検索に依存するアプリケーションの場合、ユーザーエクスペリエンスは検索要求の待機時間と非常に相関しています。構築されたクエリ、Elasticsearchクラスターの不適切な構成、JVMメモリとガベージコレクションの問題、ディスクIOなど、クエリのパフォーマンスに影響を与える可能性のあるものが多数あります。クエリ待機時間は、ユーザーに直接影響を与える指標なので、必ずアラートを発行してください。
  6. Elasticsearchのほとんどのフィルターはデフォルトでキャッシュされます。つまり、フィルターされたクエリの最初の実行中に、Elasticsearchはフィルターに一致するドキュメントを検索し、その情報を使用して「ビットセット」と呼ばれる構造を構築します。ビットセットに保存されるデータには、ドキュメント識別子と、特定のドキュメントがフィルターに一致するかどうかが含まれます。同じフィルターを持つクエリの後続の実行は、ビットセットに保存された情報を再利用するため、I / O操作とCPUサイクルを節約することでクエリの実行を高速化します。クエリでフィルターを使用することをお勧めします。詳細については、こちらを参照してください。
  7. 更新時間とマージ時間は、インデックス作成のパフォーマンスに密接に関連しており、クラスター全体のパフォーマンスにも影響します。更新時間は、Luceneインデックス(シャード)のファイル操作の数とともに増加します。
  8. スロークエリのログ記録を有効にすると、どのクエリが低速で、改善するために何ができるか、特にワイルドカードクエリに役立ちます。
  9. ulimitサイズを増やして、最大ファイルを許可します。
  10. OSが未使用のアプリケーションメモリをスワップアウトすることを決定すると、ElasticSearchのパフォーマンスが低下する可能性があります。 OSレベル設定を設定するか、ElasticSearch config bootstrap.mlockallで以下を設定して、スワップを無効にします。true
  11. ワイルドカードクエリによるすべてのインデックスの削除を無効にします。誰かがすべてのインデックス(*または_all)でDELETE操作を発行しないようにするには、action.destructive_requires_nameをtrueに設定します。

最後に、メトリックを見るのに役立つURLのリストを以下に示します。

  • / _cluster / health?pretty:クラスターヘルスインジケーター用。
  • / _status?pretty:すべてのインデックスに関するすべての情報。
  • / _nodes?pretty:ノードに関するすべての情報。
  • / _cat / master?pretty:マスターノード用。
  • / _stats?pretty:シャード割り当ての場合、統計情報にインデックスを付けます。
  • / _nodes / stats?pretty:個々のノードの統計情報には、ノードのjvm、http、ioの統計情報が含まれます。

Elasticsearchのメトリック集計は、Datadog、TICKなどのほとんどのシステム監視ツールでサポートされています。このようなツールを使用することをお勧めします。Elasticsearchを継続的に監視するには、漏斗を作成することを強くお勧めします。

結論:

Elasticsearchは、分散型フルテキスト検索および分析エンジンであり、サイズに関係なく、複数のテナントが前例のない速度でデータセット全体を検索できるようにします。全文検索機能に加えて、ElasticSearchは分析システムと分散データベースを兼ねています。 ElasticSearchには、開始するのに最適なデフォルトがあります。ただし、最初の実験段階を過ぎたら、ニーズに合わせて設定を微調整するために時間を費やす必要があります。クラスターがニーズを満たすように構成されていることを確認するために、公式のドキュメントと共に構成を後で再検討することをお勧めします。