高いJVMメモリ圧力

高いJVMメモリ使用はクラスターのパフォーマンスを低下させ、サーキットブレーカーエラーを引き起こす可能性があります。これを防ぐために、ノードのJVMメモリ使用量が85%を一貫して超える場合は、メモリ圧力を軽減するための手段を講じることをお勧めします。

高いJVMメモリ圧力の診断

JVMメモリ圧力の確認

デプロイメントメニューから、Elasticsearchをクリックします。インスタンスの下で、各インスタンスはJVMメモリ圧力インジケーターを表示します。JVMメモリ圧力が75%に達すると、インジケーターは赤色に変わります。

また、ノード統計APIを使用して、各ノードの現在のJVMメモリ圧力を計算することもできます。

Python

  1. resp = client.nodes.stats(
  2. filter_path="nodes.*.jvm.mem.pools.old",
  3. )
  4. print(resp)

Ruby

  1. response = client.nodes.stats(
  2. filter_path: 'nodes.*.jvm.mem.pools.old'
  3. )
  4. puts response

Js

  1. const response = await client.nodes.stats({
  2. filter_path: "nodes.*.jvm.mem.pools.old",
  3. });
  4. console.log(response);

コンソール

  1. GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old

応答を使用してメモリ圧力を次のように計算します:

JVMメモリ圧力 = used_in_bytes / max_in_bytes

各ノードの現在のJVMメモリ圧力を計算するには、ノード統計APIを使用します。

Python

  1. resp = client.nodes.stats(
  2. filter_path="nodes.*.jvm.mem.pools.old",
  3. )
  4. print(resp)

Ruby

  1. response = client.nodes.stats(
  2. filter_path: 'nodes.*.jvm.mem.pools.old'
  3. )
  4. puts response

Js

  1. const response = await client.nodes.stats({
  2. filter_path: "nodes.*.jvm.mem.pools.old",
  3. });
  4. console.log(response);

コンソール

  1. GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old

応答を使用してメモリ圧力を次のように計算します:

JVMメモリ圧力 = used_in_bytes / max_in_bytes

ガベージコレクションログの確認

メモリ使用量が増加すると、ガベージコレクションがより頻繁になり、時間がかかります。ガベージコレクションイベントの頻度と長さをelasticsearch.logで追跡できます。たとえば、次のイベントはElasticsearchが最後の40秒間に50%以上(21秒)をガベージコレクションに費やしたことを示しています。

ログ

  1. [timestamp_short_interval_from_last][INFO ][o.e.m.j.JvmGcMonitorService] [node_id] [gc][number] overhead, spent [21s] collecting in the last [40s]

JVMヒープダンプのキャプチャ

高いJVMメモリ圧力の正確な理由を特定するために、メモリ使用量が高いときにJVMのヒープダンプをキャプチャし、同じ期間をカバーするガベージコレクターログもキャプチャします。

JVMメモリ圧力の軽減

このセクションでは、JVMメモリ圧力を軽減するための一般的な提案をいくつか示します。

シャード数の削減

各シャードはメモリを使用します。ほとんどの場合、小さなセットの大きなシャードは、多くの小さなシャードよりも少ないリソースを使用します。シャード数を減らすためのヒントについては、シャードのサイズを調整するを参照してください。

高コストの検索を避ける

高コストの検索は大量のメモリを使用する可能性があります。クラスター上の高コストの検索をよりよく追跡するために、スローログを有効にします。

高コストの検索は、大きなsize引数を持つ場合や、多くのバケットを持つ集計を使用する場合、または高コストのクエリを含む場合があります。高コストの検索を防ぐために、次の設定変更を検討してください:

Python

  1. resp = client.indices.put_settings(
  2. settings={
  3. "index.max_result_window": 5000
  4. },
  5. )
  6. print(resp)
  7. resp1 = client.cluster.put_settings(
  8. persistent={
  9. "search.max_buckets": 20000,
  10. "search.allow_expensive_queries": False
  11. },
  12. )
  13. print(resp1)

Ruby

  1. response = client.indices.put_settings(
  2. body: {
  3. 'index.max_result_window' => 5000
  4. }
  5. )
  6. puts response
  7. response = client.cluster.put_settings(
  8. body: {
  9. persistent: {
  10. 'search.max_buckets' => 20_000,
  11. 'search.allow_expensive_queries' => false
  12. }
  13. }
  14. )
  15. puts response

Js

  1. const response = await client.indices.putSettings({
  2. settings: {
  3. "index.max_result_window": 5000,
  4. },
  5. });
  6. console.log(response);
  7. const response1 = await client.cluster.putSettings({
  8. persistent: {
  9. "search.max_buckets": 20000,
  10. "search.allow_expensive_queries": false,
  11. },
  12. });
  13. console.log(response1);

コンソール

  1. PUT _settings
  2. {
  3. "index.max_result_window": 5000
  4. }
  5. PUT _cluster/settings
  6. {
  7. "persistent": {
  8. "search.max_buckets": 20000,
  9. "search.allow_expensive_queries": false
  10. }
  11. }

マッピングの爆発を防ぐ

フィールドを多く定義したり、フィールドを深くネストしたりすると、大量のメモリを使用するマッピングの爆発が発生する可能性があります。マッピングの爆発を防ぐために、マッピング制限設定を使用してフィールドマッピングの数を制限します。

バルクリクエストを分散させる

個別のリクエストよりも効率的ですが、大規模なバルクインデックスmulti-searchリクエストは、依然として高いJVMメモリ圧力を引き起こす可能性があります。可能であれば、より小さなリクエストを送信し、それらの間により多くの時間を確保してください。

ノードメモリのアップグレード

重いインデックス作成や検索負荷は、高いJVMメモリ圧力を引き起こす可能性があります。重い作業負荷をより良く処理するために、ノードをアップグレードしてメモリ容量を増やします。