我知道ES建议堆的可用内存为50%,但有些事情让我感到困惑:在2GB系统上,这将为ES提供1GB,为操作系统提供1GB。
为什么在8GB系统上,我们是否需要为操作系统预留4GB而不是像较小系统那样预留1GB?
P.S。我在辩论这个问题是否属于StackOverflow或ServerFault。如果这是发布它的错误位置,请在评论中提及它,我会移动它。
答案 0 :(得分:3)
历史上,大多数elasticsearch的JVM堆使用都是由于查询过滤器和字段数据(构面/聚合/排序),并且没有很多安全措施来防止OOM(这已经改变)。
为了实际执行搜索,elasticsearch使用mmap的文件并完全绕过JVM堆并将其管理交给操作系统磁盘缓存,这对于使用操作系统可用的每一小部分内存都做得非常出色。如果你饿了,你的表现会受到影响。
通过最近的更新,现在可以通过doc_values将字段数据直接存储到磁盘。由于doc_values最终比纯内存解决方案YMMV慢一点,因此可以权衡您可以使用速度/聚合/排序的数据量。
我在1.x elasticsearch之后的一般建议是为JVM分配2-4GB并确保您提前计划并在计划聚合的任何高基数字段上使用doc_values。
因此,50%的数字确实不再有效,特别是如果您的服务器超过64GB,因为您真的不希望堆不能使用CompressedOops(https://blog.codecentric.de/en/2014/02/35gb-heap-less-32gb-java-jvm-memory-oddities/)。
以下是一些很好的解读为什么你应该喜欢磁盘缓存: http://kafka.apache.org/documentation.html#persistence
答案 1 :(得分:2)
所以首先要记住,50%的可用内存是一个很好的经验法则,不是刻在石头上。假设您获得了特定环境,文档量,使用模式等方面的经验,您可以改变这一点。
对于正在运行的进程和缓存文件系统(对于ES性能而言非常重要),操作系统可以使用未分配给JVM堆的所有内容。因此,如果你将堆设置得太高(有些人之前做过),你最终可能会使内存操作系统挨饿,这对文件系统缓存几乎没有影响,在极端情况下会导致内存耗尽,这在Linux下会导致OOM杀手被调用。
通常假设随着服务器大小的增加,您的堆需求和进程运行以及文件系统缓存要求都会增加,因此经验法则保持不变为50%。没有什么神奇之处,只是人们发现这是一个很好的第一个起点。一般情况下,如果由于内存限制需要更大的服务器,则需要更多的堆和操作系统内存,因此只需将其保持在50%就可以了。
在实际的生产用途中,您要做的是从50%开始,然后测量堆使用情况,弹性搜索过程的内存使用情况以及OOM杀手是否被调用。对于许多用户,特别是在较大的实例上,50%的堆分配可能是过度的。这一切都取决于您的使用情况。幸运的是,ES具有非常好的关于堆使用情况的统计信息,开箱即用(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cluster-nodes-stats.html)。
对于我们的生产系统的价值,我们尝试使用大约75%的已分配堆来保持我们的ES,默认为50%的内存。任何高于此的东西,我们都会担心索引/大查询/等等的激增可能会导致堆积 - 远低于此值,我们担心我们在堆中浪费了可用于文件系统缓存的内存。