本地英文版地址: ../en/setup-configuration-memory.html
大多数操作系统都试图将尽可能多的内存用于文件系统缓存,并急切地交换出未使用的应用程序内存。 这可能导致部分 JVM 堆甚至其可执行页面被换出到磁盘。
交换(swapping) 对性能和节点稳定性非常不利,应该不惜一切代价避免。 这可能导致垃圾回收持续几分钟而不是几毫秒,并可能导致节点响应缓慢,甚至与集群断开连接。 在弹性分布式系统中,让操作系统杀死节点更有效。
有三种方法可以禁用交换。 首选的选项是完全禁用交换。 如果这不是一个选项,那么是否更倾向于最小化交换性而不是内存锁定取决于你的环境。
通常 Elasticsearch 是唯一运行在机器上的服务,它的内存使用由 JVM 选项控制。 应该不需要启用交换。
在Linux系统上,您可以通过运行以下命令来临时禁用交换:
sudo swapoff -a
这不需要重启 Elasticsearch。
要永久禁用它,需要编辑 /etc/fstab
文件并注释掉任何包含单词 swap
的行。
在 Windows 上,可以通过 System Properties → Advanced → Performance → Advanced → Virtual memory
完全禁用分页文件来实现相同的效果。
Linux系统上的另一个选项是确保 sysctl 值 vm.swappiness
设置为 1
。
这降低了内核交换的倾向,并且在正常情况下不会导致交换,同时仍然允许整个系统在紧急情况下进行交换。
另一种选择是在Linux/Unix系统上使用mlockall,或者在 Windows 上使用 VirtualLock,尝试将进程地址空间锁定到 RAM 中,防止任何 Elasticsearch 内存被换出。
这可以通过将下面这一行添加到 config/elasticsearch.yml
文件中来实现:
bootstrap.memory_lock: true
如果试图分配比可用内存更多的内存,mlockall
可能会导致 JVM 或 shell 会话退出!
启动 Elasticsearch 后,可以通过检查下面这个请求输出中的 mlockall
值来查看该设置是否成功应用:
GET _nodes?filter_path=**.mlockall
如果你看到mlockall
为 false
,那么这意味着 mlockall
请求已经失败。
你还会在日志中看到一行包含更多信息的文字:Unable to lock JVM Memory
。
在Linux/Unix系统上,最可能的原因是运行 Elasticsearch 的用户没有锁定内存的权限。 可以按以下方式授予权限:
-
使用
.zip
和.tar.gz
归档文件安装的: -
在启动 Elasticsearch 前, 以 root 身份设置
ulimit -l unlimited
,或者在/etc/security/limits.conf
文件中设置memlock
为unlimited
。 - 使用 RPM 和 Debian 包安装的:
-
在 系统配置文件 中设置
MAX_LOCKED_MEMORY
为unlimited
(或者参见下面使用systemd
的系统)。 -
使用
systemd
的系统: -
在 systemd 配置 中设置
LimitMEMLOCK
为infinity
。
另一个可能导致 mlockall
失败的原因是 JNA临时目录(通常是/tmp
的一个子目录) 是使用选项 noexec
挂载的。
这可以通过使用 ES_JAVA_OPTS
环境变量为 JNA 指定一个新的临时目录来解决:
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djna.tmpdir=<path>" ./bin/elasticsearch
或者在 jvm.options 配置文件中设置这个 JVM 标志。