高いJVMメモリ圧力
高いJVMメモリ使用はクラスターのパフォーマンスを低下させ、サーキットブレーカーエラーを引き起こす可能性があります。これを防ぐために、ノードのJVMメモリ使用量が85%を一貫して超える場合は、メモリ圧力を軽減するための手段を講じることをお勧めします。
高いJVMメモリ圧力の診断
JVMメモリ圧力の確認
デプロイメントメニューから、Elasticsearchをクリックします。インスタンスの下で、各インスタンスはJVMメモリ圧力インジケーターを表示します。JVMメモリ圧力が75%に達すると、インジケーターは赤色に変わります。
また、ノード統計APIを使用して、各ノードの現在のJVMメモリ圧力を計算することもできます。
Python
resp = client.nodes.stats(
filter_path="nodes.*.jvm.mem.pools.old",
)
print(resp)
Ruby
response = client.nodes.stats(
filter_path: 'nodes.*.jvm.mem.pools.old'
)
puts response
Js
const response = await client.nodes.stats({
filter_path: "nodes.*.jvm.mem.pools.old",
});
console.log(response);
コンソール
GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
応答を使用してメモリ圧力を次のように計算します:
JVMメモリ圧力 = used_in_bytes
/ max_in_bytes
各ノードの現在のJVMメモリ圧力を計算するには、ノード統計APIを使用します。
Python
resp = client.nodes.stats(
filter_path="nodes.*.jvm.mem.pools.old",
)
print(resp)
Ruby
response = client.nodes.stats(
filter_path: 'nodes.*.jvm.mem.pools.old'
)
puts response
Js
const response = await client.nodes.stats({
filter_path: "nodes.*.jvm.mem.pools.old",
});
console.log(response);
コンソール
GET _nodes/stats?filter_path=nodes.*.jvm.mem.pools.old
応答を使用してメモリ圧力を次のように計算します:
JVMメモリ圧力 = used_in_bytes
/ max_in_bytes
ガベージコレクションログの確認
メモリ使用量が増加すると、ガベージコレクションがより頻繁になり、時間がかかります。ガベージコレクションイベントの頻度と長さをelasticsearch.log
で追跡できます。たとえば、次のイベントはElasticsearchが最後の40秒間に50%以上(21秒)をガベージコレクションに費やしたことを示しています。
ログ
[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
引数を持つ場合や、多くのバケットを持つ集計を使用する場合、または高コストのクエリを含む場合があります。高コストの検索を防ぐために、次の設定変更を検討してください:
index.max_result_window
インデックス設定を使用してsize
制限を下げます。- search.max_bucketsクラスター設定を使用して、許可される最大集計バケット数を減少させます。
search.allow_expensive_queries
クラスター設定を使用して高コストのクエリを無効にします。search.default_search_timeout
クラスター設定を使用してデフォルトの検索タイムアウトを設定します。
Python
resp = client.indices.put_settings(
settings={
"index.max_result_window": 5000
},
)
print(resp)
resp1 = client.cluster.put_settings(
persistent={
"search.max_buckets": 20000,
"search.allow_expensive_queries": False
},
)
print(resp1)
Ruby
response = client.indices.put_settings(
body: {
'index.max_result_window' => 5000
}
)
puts response
response = client.cluster.put_settings(
body: {
persistent: {
'search.max_buckets' => 20_000,
'search.allow_expensive_queries' => false
}
}
)
puts response
Js
const response = await client.indices.putSettings({
settings: {
"index.max_result_window": 5000,
},
});
console.log(response);
const response1 = await client.cluster.putSettings({
persistent: {
"search.max_buckets": 20000,
"search.allow_expensive_queries": false,
},
});
console.log(response1);
コンソール
PUT _settings
{
"index.max_result_window": 5000
}
PUT _cluster/settings
{
"persistent": {
"search.max_buckets": 20000,
"search.allow_expensive_queries": false
}
}
マッピングの爆発を防ぐ
フィールドを多く定義したり、フィールドを深くネストしたりすると、大量のメモリを使用するマッピングの爆発が発生する可能性があります。マッピングの爆発を防ぐために、マッピング制限設定を使用してフィールドマッピングの数を制限します。
バルクリクエストを分散させる
個別のリクエストよりも効率的ですが、大規模なバルクインデックスやmulti-searchリクエストは、依然として高いJVMメモリ圧力を引き起こす可能性があります。可能であれば、より小さなリクエストを送信し、それらの間により多くの時間を確保してください。
ノードメモリのアップグレード
重いインデックス作成や検索負荷は、高いJVMメモリ圧力を引き起こす可能性があります。重い作業負荷をより良く処理するために、ノードをアップグレードしてメモリ容量を増やします。