Amazon OpenSearch Service でのサーキットブレーカーの例外をトラブルシューティングするにはどうすればよいですか?

最終更新日: 2021 年 9 月 1 日

Amazon OpenSearch Service (Amazon Elasticsearch Service の後継サービス) クラスターにデータを送信しようとしています。しかし、データが大きすぎることを示すサーキットブレーカー例外エラーが表示されます。このような問題が発生しているのはなぜですか? これを解決するにはどうすればよいですか?

簡単な説明

リクエストが OpenSearch Service ノードに到達すると、サーキットブレーカーは必要なデータをロードするために必要なメモリ量を見積もります。その後、OpenSearch Service は推定サイズと、設定されたヒープサイズ制限を比較します。データの推定サイズが使用可能なヒープサイズより大きい場合、クエリは終了します。その結果、ノードの過負荷を防ぐために CircuitBreakerException がスローされます。

OpenSearch Service では、JVM OutofMemoryError 例外を防ぐために、次のサーキットブレーカーを使用します。

  • Request
  • Fielddata
  • In flight requests
  • Accounting
  • Parent

注: 各サーキットブレーカーには独自のチューニングニーズがあるため、これらの 5 つのサーキットブレーカーのどれが例外を発生させたかを知ることが重要です。サーキットブレーカの種類の詳細については、Elasticsearch ウェブサイトの Circuit breaker settings をご参照ください。

ノードごとおよびブレーカーごとの現在のメモリ使用量を取得するには、次のコマンドを使用します。

GET _nodes/stats/breaker

また、サーキットブレーカーはベストエフォートベースのメカニズムに過ぎないことにご留意ください。サーキットブレーカーはノードの過負荷に対してある程度の回復性を提供しますが、最終的に OutOfMemoryError を受け取ることになる場合があります。サーキットブレーカーは、明示的に予約されている場合にのみメモリを追跡できるため、正確なメモリ使用量を事前に推定することが常に可能であるとは限りません。例えば、メモリヒープが少量である場合、追跡されていないメモリの相対的なオーバーヘッドが大きくなります。サーキットブレーカとノードの回復性の詳細については、Elasticsearch ウェブサイトの Improving node resiliency with the real memory circuit breaker をご参照ください。

データノードの過負荷を回避するには、高い JVM メモリ負荷のトラブルシューティングのセクションに記載されているヒントに従ってください。

解決方法

サーキットブレーカーの例外

Elasticsearch バージョン 7.x 以降を 16 GB のヒープで使用している場合、サーキットブレーカーの制限に達すると、次のエラーが表示されます。

"error": {
        "root_cause": [
            {
                "type": "circuit_breaking_exception",
                "reason": "[parent] Data too large, data for [<http_request>] would be [16355096754/15.2gb], which is larger than the limit of [16213167308/15gb], real usage: [15283269136/14.2gb], new bytes reserved: [1071827618/1022.1mb]",
               }
      ]
}

この出力例は、処理されるデータが大きすぎて親サーキットブレーカーで処理できないことを示しています。親サーキットブレーカー (サーキットブレーカーの種類の 1 つ) は、クラスターの全体的なメモリ使用量を担当します。親サーキットブレーカーの例外が発生する場合、すべてのサーキットブレーカーで使用されるメモリの合計が、設定された制限を超えています。親ブレーカーは、クラスターが 16 GB の 95% (すなわち、15.2 GB のヒープ) を超えると、例外をスローします。

このロジックは、メモリ使用量の差を計算し、サーキットブレーカー制限を設定することで確認できます。出力例の値を使用して、「[16213167308/15gb] の制限」から「実際の使用量: [15283269136/14.2gb]」を減じます。この計算では、このリクエストを正常に処理するために、約 1.02 GB の予約された新しいバイトのメモリが必要であることがわかります。ただし、この例では、データリクエストがなされた時点でクラスターが使用できる空きメモリヒープは 0.8 GB 未満でした。その結果、サーキットブレーカーがトリップします。

サーキットブレーカーの例外メッセージは次のように解釈できます。

  • data for [ ] ([ ] のデータ):  クライアントは HTTP リクエストをクラスター内のノードに送信します。OpenSearch Service は、リクエストをローカルで処理するか、別のノードに渡して追加の処理を行います。
  • would be [#] ([#] になります): リクエストが処理された場合のヒープサイズの見え方。
  • limit of [#] ([#] の制限): 現在のサーキットブレーカーの制限。
  • real usage (実際の使用量): JVM ヒープの実際の使用量。
  • new bytes reserved (予約された新しいバイト): リクエストを処理するのに必要な実際のメモリ。

JVM メモリ負荷

サーキットブレーカーの例外は、多くの場合、JVM メモリ負荷が高いことが原因で発生します。JVM メモリ負荷とは、クラスター内のすべてのデータノードに使用されている Java ヒープの割合を指します。Amazon CloudWatch で JVMMemoryPressure メトリクスを確認して、現在の使用量を確認します。

注: データノードの JVM ヒープサイズは、物理メモリ (RAM) の半分のサイズ (最大 32 GB) に設定されます。例えば、物理メモリ (RAM) がノードあたり 128 GB の場合、ヒープサイズは引き続き 32 GB (最大ヒープサイズ) になります。それ以外の場合、ヒープサイズは物理メモリの半分のサイズとして計算されます。

JVM メモリ負荷は、次の原因によって高くなる場合があります。

  • クラスターへのリクエストの数の増加。Amazon CloudWatch で IndexRate および SearchRate メトリクスを確認して、現在の負荷を確認します。
  • 集約、ワイルドカード、およびクエリで広い時間範囲を使用します。
  • ノード間でのシャード割り当ての不均衡、またはクラスター内のシャードが多すぎる。
  • インデックスマッピングの大量実行。
  • fielddata データ構造を使用したデータのクエリ。Fielddata は大量のヒープ領域を消費する場合があり、セグメントの存続期間中はヒープに残ります。その結果、fielddata が使用される場合、JVM メモリ負荷はクラスター上で高いままになります。詳細については、Elasticsearch ウェブサイトの Fielddata をご参照ください。

高い JVM メモリ負荷のトラブルシューティング

高い JVM メモリ負荷を解決するには、次のヒントをお試しください。

  • 特に負荷が高い場合は、クラスターへの着信トラフィックを減らします。
  • クラスターをスケーリングして、ワークロードをサポートするためにより多くの JVM メモリを取得することを検討してください。
  • クラスタースケーリングが不可能な場合は、古いインデックスまたは未使用のインデックスを削除して、シャードの数を減らしてみてください。シャードメタデータはメモリに格納されるため、シャードの数を減らすことで、全体的なメモリ使用量を削減できます。
  • 低速ログを有効にして、障害のあるリクエストを特定します。
    注: [configuration changes] (設定の変更) を有効にする前に、JVM メモリ負荷が 85% 未満であることを確認してください。これにより、既存のリソースに対する追加のオーバーヘッドを回避できます。
  • 検索リクエストとインデックス作成リクエストを最適化し、正しい数のシャードを選択します。インデックス作成とシャードカウントの詳細については、Get started with Amazon OpenSearch Service: How many shards do I need? を参照してください。
  • fielddata を無効化して、使用を避けてください。 デフォルトでは、インデックスマッピングで明示的に別途定義されていない限り、fielddata はテキストフィールドで [false] に設定されます。
  • 再インデックス API を使用するか、インデックステンプレート API を作成または更新して、インデックスのマッピングタイプをキーワードに変更します。テキストフィールドで集計やソートを実行するために、代わりにキーワードタイプを使用できます。
  • フィールドデータの増加を防ぐために、テキストフィールドの集約を避けてください。より多くのフィールドデータを使用すると、より多くのヒープ領域が消費されます。フィールドデータを確認するには、cluster stats API オペレーションを使用します。
  • 次の API コールで fielddata キャッシュをクリアします。
POST /index_name/_cache/clear?fielddata=true (index-level cache)
POST */_cache/clear?fielddata=true (cluster-level cache)

警告: fielddata キャッシュをクリアすると、進行中のクエリが中断される可能性があります。

詳細については、Amazon OpenSearch Service クラスターで高い JVM メモリ負荷をトラブルシューティングするにはどうすればよいですか? を参照してください。


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


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