≤ 50% RAM fisik
Sisakan setengah RAM untuk filesystem cache OS. Lucene sangat bergantung padanya untuk kecepatan baca. Heap terlalu besar justru memperlambat.
Elasticsearch berjalan di atas JVM, dan ukuran heap yang salah adalah penyebab umum OutOfMemoryError, garbage collection panjang, dan node tidak responsif. Panduan ini membahas aturan ukuran heap, cara menyetelnya, gejala masalah, diagnosis, serta circuit breaker dan field data.
Sisakan setengah RAM untuk filesystem cache OS. Lucene sangat bergantung padanya untuk kecepatan baca. Heap terlalu besar justru memperlambat.
Di bawah ~32GB, JVM memakai compressed oops (pointer 32-bit). Melewatinya, heap 40GB menampung lebih sedikit objek daripada 31GB.
| RAM server | Heap disarankan | Catatan |
|---|---|---|
| 8 GB | 4 GB | 50% RAM. |
| 16 GB | 8 GB | 50% RAM. |
| 32 GB | 16 GB | 50% RAM. |
| 64 GB | 31 GB | Dibatasi ambang compressed oops, bukan 50%. |
| 128 GB | 31 GB + node kedua | Jalankan beberapa node 31GB per mesin. |
Selalu setel Xms (min) sama dengan Xmx (max) agar JVM tidak perlu mengubah ukuran heap saat runtime.
# config/jvm.options.d/heap.options
-Xms16g
-Xmx16g
# mis. di docker / systemd
ES_JAVA_OPTS="-Xms16g -Xmx16g"
jvm.options bawaan saat upgrade akan menimpanya. Pakai folder jvm.options.d/ agar setelan Anda bertahan antar versi.GET /_nodes/jvm?filter_path=**.mem.heap_max atau lihat heap.max di _cat/nodes.# GC muda yang lama & sering di log [gc][young][1432][88] duration [2.4s], collections [1]/[3.1s], total [2.4s]/[1.2m], memory [15.2gb]->[14.9gb]/[16gb] # circuit breaker tersandung { "type": "circuit_breaking_exception", "reason": "[parent] Data too large, data for [<http_request>] would be larger than limit" } # puncaknya: node mati java.lang.OutOfMemoryError: Java heap space
# pemakaian heap ringkas per node
GET /_cat/nodes?v&h=name,heap.percent,heap.current,heap.max,ram.percent,cpu,load_1m
name heap.percent heap.current heap.max ram.percent cpu load_1m
es-01 91 14.6gb 16gb 78 64 3.10
es-02 63 10.1gb 16gb 71 22 1.40
# statistik JVM rinci: heap, GC, pool
GET /_nodes/stats/jvm?filter_path=nodes.*.jvm.mem,nodes.*.jvm.gc
# status semua circuit breaker
GET /_nodes/stats/breaker?filter_path=nodes.*.breakers
| Indikator | Sehat | Bermasalah |
|---|---|---|
heap.percent | < 75% rata-rata | Konsisten > 85% |
| Durasi old GC | < 1 detik, jarang | > 1 detik, sering |
breakers.parent.tripped | 0 | Naik terus |
Circuit breaker menolak operasi yang diperkirakan menghabiskan memori, mencegah OOM yang mematikan node. Field data adalah struktur in-heap untuk agregasi/sort pada field text — sering jadi biang pemborosan heap.
# batas circuit breaker (dynamic)
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.total.limit": "70%",
"indices.breaker.fielddata.limit": "40%"
}
}
text langsung — itu mengaktifkan field data yang boros heap. Pakai multi-field .keyword yang memakai doc values di disk, bukan heap.# benar: agregasi pakai sub-field keyword (doc values, hemat heap) GET /produk/_search { "aggs": { "merek": { "terms": { "field": "merek.keyword" } } } }
Xms = Xmx, maksimal 50% RAM, tidak lebih dari ~31GB.text; pakai sub-field keyword berbasis doc values.heap.percent dan durasi GC; pasang alert pada heap > 85% berkelanjutan.Aturannya: heap maksimal 50% dari RAM fisik, dan jangan melebihi sekitar 31GB. Sisa RAM dibiarkan untuk filesystem cache OS yang dipakai Lucene. Melewati ~31-32GB membuat JVM kehilangan compressed ordinary object pointers (compressed oops), sehingga heap besar justru kurang efisien.
Di bawah ambang ~32GB, JVM memakai compressed oops yang menyimpan pointer objek dalam 32-bit, menghemat memori dan mempercepat akses. Di atas ambang itu pointer menjadi 64-bit penuh, sehingga heap 40GB bisa menampung objek lebih sedikit daripada heap 31GB. Karena itu 31GB adalah batas praktis.
Gejalanya: GC (garbage collection) lama dan sering muncul di log (mis. "[gc][young] ... collections ... took [Xs]"), heap.percent konsisten tinggi (di atas 85%), node lambat atau tidak responsif, dan akhirnya OutOfMemoryError yang bisa membuat node mati. Circuit breaker juga mulai menolak request.
Circuit breaker mencegah operasi yang akan memakai memori berlebih sehingga menghindari OutOfMemoryError yang mematikan node. Bila estimasi pemakaian melewati batas, request ditolak dengan circuit_breaking_exception. Ini melindungi stabilitas node dengan mengorbankan satu request, bukan seluruh node.
Terlalu banyak shard kecil membebani heap. Gunakan kalkulator shard untuk menentukan jumlah yang sehat.
Buka Kalkulator Shard