Amazon Elasticsearch Service クラスターのインデックス作成パフォーマンスを向上させるにはどうすればよいですか?

最終更新日: 2020 年 8 月 10 日

Amazon Elasticsearch Service (Amazon ES) のインデックス作成オペレーションを最適化し、取り込みスループットを最大化しようと考えています。これを行うにはどうすればよいですか?

解決方法

取り込み対象であるインデックスのシャードがデータノード間で均等に分散されていることを確認する

次の式を用いて、シャードが均等に分散されていることを確認します。

Number of shards for index = k * (number of data nodes), where k is the number of shards per node

たとえば、インデックスに 24 個のシャードと 8 個のデータノードがある場合、Amazon ES は各ノードに 3 個のシャードを割り当てます。詳細については、Amazon Elasticsearch Service をはじめよう: シャード数の算出方法をご参照ください。

refresh_interval を 60 秒以上に増やす

Amazon ES インデックスを更新して、ドキュメントを検索できるようにします。インデックスを更新するには、インデックス作成スレッドで使用されているのと同じリソースが必要です。

デフォルトの更新間隔は 1 秒に設定されています。更新間隔を長くすることで、データノードの API 呼び出しを少なくできます。現在の更新間隔の長さによっては、更新間隔をより短く、より速くできます。429 エラーを防ぐには、更新間隔を長くすることがベストプラクティスです。

注意: デフォルトの更新間隔は、過去 30 秒間に複数の検索リクエストを受信したインデックスの場合、1 秒です。更新されたデフォルトの間隔の詳細については、Elasticsearch ウェブサイトの _refresh API version 7.x を参照してください。

レプリカ数をゼロに変更する

大量のインデックス作成が予想される場合は、index.number_of_replicas の値を「0」に設定することを検討してください。各レプリカはインデックス作成プロセスを複製します。その結果、レプリカを無効にすると、クラスターのパフォーマンスが向上します。重いインデックス作成が完了したら、レプリケートされたインデックスを再度アクティブ化します。

重要: レプリカが無効状態のときにノードが失敗すると、データが失われる可能性があります。短期間のデータ損失を許容できる場合にのみ、レプリカを無効にします。

最適な一括リクエストサイズを見つけるために試行する

5 MiB~15 MiB の一括リクエストサイズから開始します。その後、インデックス作成のパフォーマンスに改善が見られなくなるまで、徐々にリクエストサイズを増やしていきます。詳細については、Elasticsearch ウェブサイトの Using and sizing bulk requests をご参照ください。

注意: 一部のインスタンスタイプでは、一括リクエストに 10 MiB の制限があります。詳細については、ネットワークの制限をご参照ください。

SSD インスタンスストアボリュームがあるインスタンスタイプを使用する (I3 など)

I3 インスタンスは、ローカルで高速な Memory Express (NVMe) ストレージを提供します。I3 インスタンスでは、汎用 SSD (gp2) を使う Amazon Elastic Block Store (Amazon EBS) ボリュームを使用するインスタンスに比べ、優れた取り込みパフォーマンスを実現しています。詳細については、I3 インスタンスを使用して Amazon Elasticsearch Service でペタバイト規模のクラスターを実行をご参照ください。

レスポンスサイズを削減する

Amazon ES レスポンスのサイズを小さくするには、filter_path パラメータを使用して不要なフィールドを除外します。失敗したリクエストの特定または再試行を行う際に必要となるフィールドを除外しないように注意してください。これらのフィールドは、クライアントごとに異なる場合があります。

次の例では、index-nametype-name、および took のフィールドがレスポンスから除外されています。

curl -X POST "es-endpoint/index-name/type-name/_bulk?pretty&filter_path=-took,-items.index._index,-items.index._type" -H 'Content-Type: application/json' -d'
{ "index" : { "_index" : "test2", "_id" : "1" } }
{ "user" : "testuser" }
{ "update" : {"_id" : "1", "_index" : "test2"} }
{ "doc" : {"user" : "example"} }

詳細については、レスポンスサイズの削減を参照してください。

index.translog.flush_threshold_size の値を大きくする

デフォルトでは、 index.translog.flush_threshold_size は 512 MB に設定されています。つまり、トランスログは、512 MB に達するとフラッシュされることを意味します 。インデックス作成ロードの重みによって、トランスログの頻度が決まります。index.translog.flush_threshold_size の値を増やすことで、トランスログオペレーションをノードが実行する頻度を低くできます。Amazon ES フラッシュはリソースを大量に使用するオペレーションであるため、トランスログの頻度を減らすと、インデックス作成のパフォーマンスが向上します。フラッシュしきい値サイズを増やすことで、Elasticsearch クラスターは (複数の小さいセグメントではなく) いくつかの大きなセグメントを作成します。大きなセグメントはマージされる頻度が低くなり、マージではなくインデックス作成に使用されるスレッドが増えます。

注意: index.translog.flush_threshold_size が増加すると、トランスログが完了するまでにかかる時間も長くなる可能性があります。シャードが失敗した場合、トランスログが大きいため、復旧に時間がかかります。

index.translog.flush_threshold_size の値を増やす前に、次の API オペレーションを呼び出して、最新のフラッシュオペレーションの統計を取得します。

$ curl 'es-endpoint/index-name/_stats/flush?pretty'

es-endpointindex-name をそれぞれの変数に置き換えます。

出力に表示されるフラッシュの数と合計時間を記録しておきます。次の出力例は、124 個のフラッシュがあり、これには 17,690 ミリ秒かかったことを示しています。

"flush" { "total" : 124, "total_time_in_millis" : 17690 }

フラッシュのしきい値サイズを増やすには、次の API オペレーションを呼び出します。

$ curl -XPUT 'es-endpoint/index-name/_settings?pretty' -d '{"index":{"translog.flush_threshold_size" : "1024MB"}}'

この例でのフラッシュのしきい値サイズは、メモリが 32 GB を超えるインスタンスに最適な 1024 MB に設定されています。

注意: Amazon ES ドメインの適切なしきい値サイズを選択します。

_stats API オペレーションを再度実行して、フラッシュアクティビティが変更されたかどうかを確認します。

$ curl 'es-endpoint/index-name/_stats/flush?pretty' 

注意: ベストプラクティスとして、始めは稼働中のインデックスについてのみ index.translog.flush_threshold_size を増やします。結果を確認したら、インデックステンプレートに変更を適用します。


この記事は役に立ちましたか?


請求に関するサポートまたは技術的なサポートが必要ですか?