Amazon OpenSearch Service での検索または書き込み拒否を解決するにはどうすればよいですか。

最終更新日: 2021 年 10 月 19 日

Amazon OpenSearch Service (Amazon Elasticsearch Service の後継サービス) クラスターに検索リクエストまたは書き込みリクエストを送信すると、そのリクエストが拒否されます。この原因は何でしょうか?

簡単な説明

OpenSearch Service クラスターでデータの書き込みまたは検索を実行すると、次のように HTTP 429 エラー、または es_rejected_execution_exception が表示されることがあります。

error":"elastic: Error 429 (Too Many Requests): rejected execution of org.elasticsearch.transport.TransportService$7@b25fff4 on 
EsThreadPoolExecutor[bulk, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@768d4a66[Running, 
pool size = 2, active threads = 2, queued tasks = 200, completed tasks = 820898]] [type=es_rejected_execution_exception]"

Reason={"type":"es_rejected_execution_exception","reason":"rejected execution of org.elasticsearch.transport.TcpTransport$RequestHandler@3ad6b683 on EsThreadPoolExecutor[search, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@bef81a5[Running, pool size = 25, active threads = 23, queued tasks = 1000, completed tasks = 440066695]]"

HTTP 429 エラーまたは es_rejected_execution_exception には、次に示す変数が起因していることが考えられます。

  • データノードのインスタンスタイプと検索もしくは書き込みの制限
  • インスタンスメトリクスの高い値
  • アクティブスレッドとキュースレッド

HTTP 429 エラーは、クラスターへの検索および書き込みリクエストが原因で発生する場合があります。拒否は、クラスターの 1 つもしくは複数のノードから発生することもあります。

注: Elasticsearch のバージョンが異なると、_index API の呼び出しを処理するために異なるスレッドプールが使用されます。Elasticsearch バージョン 1.5 および 2.3 では、インデックススレッドプールが使用されます。Elasticsearch バージョン 5.x、6.0、および 6.2 では、一括スレッドプールが使用されます。Elasticsearch バージョン 6.3 以降では、書き込みスレッドプールが使用されます。詳細については、Elasticsearch ウェブサイトの「Thread Pool」を参照してください。

解決方法

データノードのインスタンスタイプと検索もしくは書き込みの制限

データノードインスタンスタイプでは、固定の仮想 CPU (vCPUs) を使用しています。vCPU 数を数式に含めることで、検索または書き込みの同時オペレーションを取得し、キューに入る前にノードを実行できるようにします。アクティブなスレッドがいっぱいになると、そのスレッドはキューにオーバーフローし、最終的に拒否されます。vCPUs とノードタイプの関係の詳細については、「Amazon OpenSearch Service の料金」を参照してください。

さらに、実行できるノードあたりの検索数または書き込み数にも、制限があります。この制限は、スレッドプールの定義と Elasticsearch のバージョン数に基づいて決定されます。詳細については、Elasticsearch ウェブサイトの「Thread Pool」を参照してください。

例えば、Elasticsearch クラスター (バージョン 7.4) 内の 5 つのノードに対して、R5.2xlarge ノードタイプを選択している場合には、8 つの vCPUs を持つことになります。

検索リクエストでアクティブにすることのできる最大スレッド数は、次の式を使用して計算します。

int ((# of available_processors * 3) / 2) + 1

書き込みリクエストでアクティブにすることのできる最大のスレッド数は、次の式を使用して計算します。

int (# of available_processors)

したがって、R5.2xlarge ノードで実行できる検索オペレーションの数は、最大で 13 個だということがわかります。

(8 VCPUs * 3) / 2 + 1 = 13 operations

R5.2xlarge ノードでは、最大 8 個の書き込みオペレーションを実行できます。

8 VCPUs = 8 operations

5 つのノードを持つ OpenSearch Service クラスターでは、最大 65 個の検索オペレーションを実行できます。

5 nodes * 13 = 65 operations

5 つのノードを持つ OpenSearch Service クラスターでは、最大 40 個の書き込みオペレーションを実行できます。

5 nodes * 8 = 40 operations

インスタンスメトリクスの高い値

429 例外をトラブルシューティングするには、自分のクラスターの次の Amazon CloudWatch メトリクスを確認してください。

  • IndexingRate: 1 分あたりのインデックス作成処理の回数です。2 つのドキュメントの追加と 2 回の更新を行う 1 回の _bulk API 呼び出しは、4 回のオペレーションとしてカウントされ、1 つ以上のノードに分散する可能性があります。そのインデックスに 1 つ以上のレプリカがある場合、クラスター内のそれらのノードでも合計 4 つのインデックス作成オペレーションが記録されます。ドキュメントの削除は、IndexingRate メトリクスではカウントされません。
  • SearchRate: データノード上のすべてのシャードでの、1 分あたりの検索リクエストの合計数です。_検索 API の 1 回の呼び出しに対し、多数のシャードから結果が返されることがあります。1 つのノードに 5 つの異なるシャードがある場合、クライアントが 1 つのリクエストしか実行しなかった場合でも、ノードからはこのメトリクスに対して「5」がレポートされます。
  • CoordinatingWriteRejected: 調整中のノードで発生した拒否の総数です。これらの拒否は、OpenSearch Service のスタートアップ以降に蓄積されたインデックス作成のプレッシャーが原因で発生します。
  • PrimaryWriteRejected: プライマリシャードで発生した拒否の総数です。これらの拒否は、前回の OpenSearch Service のスタートアップ以降に蓄積されたインデックス作成のプレッシャーが原因で発生します。
  • ReplicaWriteRejected: インデックス作成のプレッシャーが原因でレプリカシャードで発生した拒否の総数です。これらの拒否は、前回の OpenSearch Service のスタートアップ以降に蓄積されたインデックス作成のプレッシャーが原因で発生します。
  • ThreadpoolWriteQueue: 書き込みスレッドプール内のキューに入れられたタスクの数です。このメトリックは、CPU 使用率が高いか、インデックス作成の同時実行性が高いことが原因でリクエストが拒否されているかどうかを示します。
  • ThreadpoolWriteRejected: 書き込みスレッドプールで拒否されたタスクの数です。
    注:OpenSearch Service バージョン 7.9 では、デフォルトの書き込みキューサイズが 200 から 10,000 に増加しました。その結果、このメトリクスは、OpenSearch Service からの拒否を示す唯一の指標ではなくなりました。バージョン 7.9 以降で拒否をモニタリングするには、CoordinatingWriteRejectedPrimaryWriteRejected、および ReplicaWriteRejected メトリクスを使用します。詳細については、「UltraWarm メトリクス」を参照してください。
  • ThreadpoolSearchQueue: 検索スレッドプール内のキューに入れられたタスクの数です。キューサイズが一貫して高く示される場合は、クラスターのスケーリングを検討してください。検索キューの最大サイズは 1,000 です。
  • ThreadpoolSearchRejected: 検索スレッドプールで拒否されたタスクの数です。この数値が継続的に増加する場合は、クラスターのスケーリングを検討してください。

注: 表示されるスレッドプールのメトリクスにより、IndexingRateSearchRate について知ることができます。

Amazon CloudWatch による OpenSearch Service クラスターのモニタリングの詳細については、「インスタントメトリクス」を参照してください。

アクティブスレッドとキュースレッド

CPU が不足しているか、リクエストの同時実行性が高い場合、キューがすぐにいっぱいになって HTTP 429 エラーが発生することがあります。キュースレッドを監視するには、Amazon CloudWatch で、ThreadpoolSearchQueue および ThreadpoolWriteQueue メトリックスをチェックします。

アクティブスレッドとキュースレッドでの、検索に対する拒否を確認するには、次のコマンドを使用します。

GET /_cat/thread_pool/search?v&h=id,name,active,queue,rejected,completed

アクティブスレッドとキュースレッドでの書き込みに対する拒否を確認するには、「search」の部分を「write」で置き換えます。出力される rejectedcompleted の値は、累積のノードカウンタであり、新しいノードが起動されるときにリセットされます。詳細については、Elasticsearch ウェブサイトにある「cat thread pool API」の「Example with explicit columns」のセクションを参照してください。

注: 各ノードにある一括キューで、使用中の Elasticsearch バージョンに応じて、50~200 のリクエストを保持できます。キューが満杯の状態では、新しいリクエストは拒否されます。詳細については、Elasticsearch ウェブサイトの「Thread Pool」を参照してください。

検索および書き込み拒否エラーのサンプル

検索拒否

検索拒否エラーは、アクティブなスレッドがビジー状態で、キュー内のタスクが最大量まで到達したことを示します。その結果、検索リクエストが拒否される可能性があります。OpenSearch Service ログを設定して、これらのエラーメッセージを検索低速ログに表示することができます。

注: 余分なオーバーヘッドを避けるために、低速ログのしきい値は余裕のある量に設定します。例えば、ほとんどのクエリが 11 秒かかり、しきい値が「10」に設定されている場合には、OpenSearch Service のログの書き込みに時間がかかります。このオーバーヘッドを回避するには、低速ログのしきい値を 20 秒に設定します。これで、(11 秒を超える時間がかかる) 低速クエリのごく一部だけがログに記録されるようになります。

検索低速ログを Amazon CloudWatch にプッシュするようにクラスターを設定したら、低速ログ生成のための特定のしきい値を設定します。次の HTTP POST コールを使用して、低速ログ生成の特定のしきい値を設定できます。

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.search.slowlog.threshold.query.<level>":"10s"}'

書き込み拒否

書き込み拒否としての 429 エラーメッセージは、一括キューエラーを示します。es_rejected_execution_exception[bulk] は、キューがいっぱいであること、および新しいリクエストが拒否されたことを示します。この一括キューのエラーが発生するのは、クラスターに対するリクエスト数が一括キューのサイズ (threadpool.bulk.queue_size) を超えた場合です。各ノードの一括キューは、使用している Elasticsearch のバージョンに応じて、50~200 のリクエストを保持できます。

OpenSearch Service ログを設定して、これらのエラーメッセージをインデックス低速ログに表示することができます。

注: 余分なオーバーヘッドを避けるために、低速ログのしきい値は余裕のある量に設定します。例えば、ほとんどのクエリが 11 秒かかり、しきい値が「10」に設定されている場合には、OpenSearch Service がログを書き込むのに追加時間がかかります。このオーバーヘッドを回避するには、低速ログのしきい値を 20 秒に設定します。これで、(11 秒を超える時間がかかる) 低速クエリのごく一部だけがログに記録されるようになります。

検索低速ログを Amazon CloudWatch にプッシュするようにクラスターを設定したら、低速ログ生成のための特定のしきい値を設定します。低速ログ生成のための特定のしきい値を設定するには、次の HTTP POST コールを使用します。

curl -XPUT http://<your domain’s endpoint>/index/_settings -d '{"index.indexing.slowlog.threshold.query.<level>":"10s"}'

書き込み拒否のためのベストプラクティス

書き込み拒否を軽減するベストプラクティスをいくつか挙げます。

  • ドキュメントのインデックス作成を高速化すると、書き込みキューがキャパシティー上限に達する可能性が低くなります。
  • ワークロードと必要なパフォーマンスに応じて、バルクサイズを調整します。詳細については、Elasticsearch ウェブサイトの「Tune for indexing speed」 を参照してください。
  • アプリケーションロジックに指数関数的な再試行ロジックを追加します。指数関数的な再試行ロジックにより、失敗したリクエストが自動的に再試行されます。
    注: クラスターで継続的にリクエストの同時実行性が高い場合には、指数関数的な再試行ロジックは 429 エラーの解決には役立ちません。トラフィックが突然または時折急増する場合は、このベストプラクティスを組み込みます。
  • Logstash からデータを取り込む場合は、ワーカーの数とバルクサイズを調整します。バルクサイズを 3~5 MB に設定するのがベストプラクティスです。

インデックス作成パフォーマンスのチューニングの詳細については、「Amazon OpenSearch Service クラスターのインデックスパフォーマンスを向上させる方法 」を参照してください。

検索拒否に関するベストプラクティス

検索拒否を軽減するベストプラクティスをいくつか挙げます。

  • より大きなインスタンスタイプに切り替えます。OpenSearch Service は、より高速に検索結果を得るために、ファイルシステムキャッシュに大きく依存しています。検索リクエストの各ノード上のスレッドプール内のスレッド数は、int((# of available_processors * 3) / 2) + 1 に等しくなります。検索リクエストを処理するために、さらに多くのスレッドを取得するには、より多くの vCPU があるインスタンスに切り替えます。
  • 特定のインデックスや、妥当なしきい値を持つすべてのインデックスについて、低速ログを検索できるようにします。実行に時間がかかっているクエリを確認し、クエリの検索パフォーマンス戦略を実装します。詳細については、Elasticsearch ウェブサイトの「Troubleshooting Elasticsearch searches, for beginners」、または「Advanced tuning: Finding and fixing slow Elasticsearch queries」を参照してください。

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


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