作者:來自 Elastic?Valentin Crettaz
探索 Elasticsearch 的內存需求以及不同類型的內存統計信息。
Elasticsearch 擁有豐富的新功能,幫助你為你的使用場景構建最佳搜索解決方案。瀏覽我們的示例筆記本了解更多信息,開始免費云試用,或者現在就在本地機器上體驗 Elastic。
Elasticsearch 的內存需求
Elasticsearch 進程對內存的需求非常高。Elasticsearch 使用 JVM(Java Virtual Machine),最佳實踐建議為 JVM 分配接近節點可用內存的 50%。JVM 依賴內存,以便 Lucene 進程能夠非常快速地訪問索引值。剩下的 50% 留給文件系統緩存,用來將經常訪問的數據保存在內存中。
要了解 JVM 內存管理的完整解釋,請閱讀這篇博客。收到來自不同類型斷路器(circuit breakers)的警告也是很常見的。
jvm.mem
最重要的內存部分是 JVM 堆內存。
GET _nodes/stats/jvm
輸出如下所示:
"jvm" : {"timestamp" : 1603351829573,"uptime_in_millis" : 150932107,"mem" : {"heap_used_in_bytes" : 258714272,"heap_used_percent" : 24,"heap_committed_in_bytes" : 1073741824,"heap_max_in_bytes" : 1073741824,"non_heap_used_in_bytes" : 192365488,"non_heap_committed_in_bytes" : 209186816,
請注意,健康的 JVM 中的 heap_used_in_bytes 會因為垃圾回收過程而呈現鋸齒狀模式,使用量會逐漸上升到大約 70%,然后在垃圾回收發生時迅速降到 30%。
JVM 的 heap_max_in_bytes 取決于 jvm.options 文件中設置的值,建議你將其設置為容器或服務器可用內存的 50%。
關于 JVM 堆內存問題的更多信息,請參閱:Elasticsearch 中的堆大小使用和 JVM 垃圾回收。
解釋不同類型的內存統計信息
查看內存統計信息時,我們需要注意,許多 Elasticsearch 應用運行在容器中,而這些容器部署在更大的機器上。這在你使用 AWS Elasticsearch 服務、Elastic Cloud 這類托管服務,或是在 Docker 或 Kubernetes 上運行 Elasticsearch 時很常見。在這種情況下,解讀可用的內存統計信息時需要特別小心。
Elasticsearch 監控 API 提供了多種內存統計信息,如下所述:
GET _nodes/stats/os"os" : {"timestamp" : 1603350306857,"cpu" : {"percent" : 13,"load_average" : {"1m" : 3.37,"5m" : 3.18,"15m" : 2.8}},"mem" : {"total_in_bytes" : 16703369216,"free_in_bytes" : 361205760,"used_in_bytes" : 16342163456,"free_percent" : 2,"used_percent" : 98},"swap" : {"total_in_bytes" : 1023406080,"free_in_bytes" : 1302528,"used_in_bytes" : 1022103552},"cgroup" : {"cpuacct" : {"control_group" : "/","usage_nanos" : 2669636420088},"cpu" : {"control_group" : "/","cfs_period_micros" : 100000,"cfs_quota_micros" : -1,"stat" : {"number_of_elapsed_periods" : 0,"number_of_times_throttled" : 0,"time_throttled_nanos" : 0}},"memory" : {"control_group" : "/","limit_in_bytes" : "9223372036854771712","usage_in_bytes" : "4525641728"}}}
上述統計信息是針對在 Docker 上運行的開發節點。讓我們解釋一下我們收到的各個部分:
os.mem
第一個部分 “os.mem” 指的是運行該機器的主機。在這種情況下,我們運行在 Docker 上,因此 16GB 指的是容器所在主機的內存。請注意,機器使用接近 100% 的內存是完全正常的,這并不表示有問題。
os.swap
“os.swap” 部分同樣指的是主機。在這種情況下,我們可以看到主機允許交換。當我們在啟用交換的主機內運行容器時,這是很正常的。如果要確認 Docker 容器內是否禁止交換,可以通過運行以下命令進行檢查:
GET _nodes?filter_path=**.mlockall
os.cgroup
最后,我們可以看到 “os.cgroup” 部分,它指的是容器本身。在這種情況下,容器使用了 4GB 的內存。
process.mem
我們還可以訪問一個虛擬內存的統計信息:
GET _nodes/stats/process"process" : {"timestamp" : 1603352751181,"open_file_descriptors" : 436,"max_file_descriptors" : 1048576,"cpu" : {"percent" : 0,"total_in_millis" : 1964850},"mem" : {"total_virtual_in_bytes" : 5035376640}
注意,“process.total_virtual_in_bytes” 包括了進程可用的整個內存,包括通過 mmap 獲得的虛擬內存。
原文:Elasticsearch memory usage guide - Elasticsearch Labs