インデックス速度の調整

バルクリクエストを使用する

バルクリクエストは、単一ドキュメントのインデックスリクエストよりもはるかに優れたパフォーマンスを発揮します。バルクリクエストの最適なサイズを知るためには、単一ノードで単一シャードを使用してベンチマークを実行する必要があります。最初に100ドキュメントを一度にインデックスし、次に200、次に400など、各ベンチマーク実行でバルクリクエストのドキュメント数を倍増させます。インデックス速度が平坦化し始めたら、データに対するバルクリクエストの最適なサイズに達したことがわかります。もし同点の場合は、ドキュメントが多すぎるよりも少なすぎる方が良いです。バルクリクエストが大きすぎると、同時に多くのリクエストが送信された場合にクラスターにメモリ圧力をかける可能性があるため、パフォーマンスが向上するように見えても、リクエストごとに数十メガバイトを超えないようにすることをお勧めします。

複数のワーカー/スレッドを使用してElasticsearchにデータを送信する

バルクリクエストを送信する単一スレッドでは、Elasticsearchクラスターのインデックス容量を最大限に活用することは難しいです。クラスターのすべてのリソースを使用するためには、複数のスレッドまたはプロセスからデータを送信する必要があります。これにより、クラスターのリソースをより良く活用できるだけでなく、各fsyncのコストを削減するのにも役立ちます。

TOO_MANY_REQUESTS (429)レスポンスコード(EsRejectedExecutionExceptionはJavaクライアントを使用)に注意してください。これは、Elasticsearchが現在のインデックス速度に追いつけないことを示す方法です。これが発生した場合は、再試行する前にインデックスを少し一時停止し、理想的にはランダム化された指数バックオフを使用してください。

バルクリクエストのサイズと同様に、最適なワーカー数はテストによってのみわかります。これは、I/OまたはCPUがクラスターで飽和するまでワーカー数を徐々に増やすことでテストできます。

インデックス速度の調整

初期ロードのためにレプリカを無効にする

Elasticsearchに大量のデータを一度にロードしたい場合、インデックスのindex.number_of_replicas0に設定することでインデックス速度を向上させることが有益です。レプリカがない場合、単一ノードを失うとデータ損失が発生する可能性があるため、初期ロードが問題が発生した場合に再試行できるように、データが他の場所に存在することが重要です。初期ロードが完了したら、index.number_of_replicasを元の値に戻すことができます。

インデックス設定でindex.refresh_intervalが構成されている場合、初期ロード中にそれを解除し、初期ロードが完了したら元の値に戻すことでさらに役立つ可能性があります。

スワッピングを無効にする

オペレーティングシステムがJavaプロセスをスワップアウトしないように、スワッピングを無効にすることを確認してください。

ファイルシステムキャッシュにメモリを割り当てる

ファイルシステムキャッシュは、I/O操作をバッファリングするために使用されます。Elasticsearchを実行しているマシンのメモリの少なくとも半分をファイルシステムキャッシュに割り当てることを確認してください。

自動生成されたIDを使用する

明示的なIDを持つドキュメントをインデックスする際、Elasticsearchは同じシャード内に同じIDのドキュメントが既に存在するかどうかを確認する必要があり、これはコストのかかる操作であり、インデックスが成長するにつれてさらにコストがかかります。自動生成されたIDを使用することで、Elasticsearchはこのチェックをスキップでき、インデックス作成が速くなります。

より高速なハードウェアを使用する

インデックス作成がI/Oに依存している場合、ファイルシステムキャッシュのサイズを増やす(上記を参照)か、より高速なストレージを使用することを検討してください。Elasticsearchは通常、順次書き込みで個別のファイルを作成します。ただし、インデックス作成には複数のファイルを同時に書き込むことが含まれ、ランダムおよび順次読み取りの混合もあるため、SSDドライブは回転ディスクよりもパフォーマンスが向上する傾向があります。

RAID 0アレイを構成して、インデックスを複数のSSDにストライプします。これにより、いずれかのSSDの故障がインデックスを破壊するため、故障のリスクが増加することを忘れないでください。ただし、これは通常、正しいトレードオフです:最大のパフォーマンスのために単一シャードを最適化し、その後、異なるノードにレプリカを追加してノード障害に対する冗長性を確保します。また、インデックスをバックアップするためにスナップショットと復元を使用することもできます。

ローカルストレージとリモートストレージ

直接接続された(ローカル)ストレージは、リモートストレージよりも一般的にパフォーマンスが優れています。これは、適切に構成するのが簡単で、通信オーバーヘッドを回避できるためです。

一部のリモートストレージは、Elasticsearchが課す負荷の下で非常に悪いパフォーマンスを示します。ただし、慎重な調整を行うことで、リモートストレージを使用しても受け入れ可能なパフォーマンスを達成できることがあります。特定のストレージアーキテクチャにコミットする前に、現実的なワークロードでシステムをベンチマークして、調整パラメータの影響を確認してください。期待するパフォーマンスを達成できない場合は、ストレージシステムのベンダーと協力して問題を特定してください。

インデックスバッファサイズ

ノードが重いインデックス作成のみを行っている場合、indices.memory.index_buffer_sizeが重いインデックス作成を行うシャードごとに最大512MBのインデックスバッファを提供するのに十分な大きさであることを確認してください(それ以上は通常、インデックス作成パフォーマンスは向上しません)。Elasticsearchはその設定(Javaヒープのパーセンテージまたは絶対バイトサイズ)を取得し、すべてのアクティブシャードで共有バッファとして使用します。非常にアクティブなシャードは、軽量インデックス作成を行っているシャードよりもこのバッファを自然に多く使用します。

デフォルトは10%で、通常は十分です。たとえば、JVMに10GBのメモリを割り当てると、インデックスバッファに1GBが割り当てられ、重いインデックス作成を行う2つのシャードをホストするのに十分です。

クロスクラスター複製を使用して、検索がインデックスからリソースを奪うのを防ぐ

単一クラスター内では、インデックス作成と検索がリソースを競合する可能性があります。2つのクラスターを設定し、クロスクラスター複製を構成して、1つのクラスターから別のクラスターにデータを複製し、すべての検索をフォロワーインデックスを持つクラスターにルーティングすることで、検索活動がリーダーインデックスをホストするクラスターのインデックス作成からリソースを奪うことはなくなります。

ホットスポッティングを避ける

ホットスポッティングは、ノードリソース、シャード、またはリクエストが均等に分配されていない場合に発生する可能性があります。Elasticsearchはノード間でクラスター状態を同期することで維持するため、継続的にホットスポット化されたノードは全体のクラスター性能を低下させる可能性があります。

追加の最適化

ディスク使用量の調整に関するTune for disk usageで概説された多くの戦略も、インデックス作成の速度を改善します。