作者:来自 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