禁用交换
编辑禁用交换
编辑大多数操作系统会尽量使用尽可能多的内存来缓存文件系统,并积极地将未使用的应用程序内存交换到磁盘。这可能导致 JVM 堆的部分甚至其可执行页面被交换到磁盘。
交换对性能和节点稳定性非常不利,应不惜一切代价避免。它可能导致垃圾回收持续数分钟而不是毫秒,并可能导致节点响应缓慢甚至与集群断开连接。在弹性分布式系统中,让操作系统杀死节点更有效。
有三种方法可以禁用交换。首选的选项是完全禁用交换。如果这不是一个选项,那么是优先最小化交换还是内存锁定取决于您的环境。
禁用所有交换文件
编辑通常 Elasticsearch 是在机器上运行的唯一服务,其内存使用由 JVM 选项控制。应该不需要启用交换。
在 Linux 系统上,您可以通过运行以下命令临时禁用交换
sudo swapoff -a
这不需要重启 Elasticsearch。
要永久禁用它,您需要编辑 /etc/fstab
文件,并注释掉任何包含单词 swap
的行。
在 Windows 上,可以通过 系统属性 → 高级 → 性能 → 高级 → 虚拟内存
完全禁用页面文件来实现等效操作。
配置 swappiness
编辑在 Linux 系统上可用的另一个选项是确保将 sysctl 值 vm.swappiness
设置为 1
。这将减少内核进行交换的倾向,在正常情况下不应导致交换,同时仍然允许整个系统在紧急情况下进行交换。
启用 bootstrap.memory_lock
编辑另一个选项是在 Linux/Unix 系统上使用 mlockall,或者在 Windows 上使用 VirtualLock,尝试将进程地址空间锁定到 RAM 中,防止任何 Elasticsearch 堆内存被交换出去。
某些平台在使用内存锁定时仍然会交换堆外内存。要防止堆外内存交换,请禁用所有交换文件。
要启用内存锁定,请在 elasticsearch.yml
中将 bootstrap.memory_lock
设置为 true
bootstrap.memory_lock: true
如果 mlockall
尝试分配比可用内存更多的内存,可能会导致 JVM 或 shell 会话退出!
启动 Elasticsearch 后,您可以通过检查此请求的输出中 mlockall
的值来查看是否已成功应用此设置
resp = client.nodes.info( filter_path="**.mlockall", ) print(resp)
response = client.nodes.info( filter_path: '**.mlockall' ) puts response
const response = await client.nodes.info({ filter_path: "**.mlockall", }); console.log(response);
GET _nodes?filter_path=**.mlockall
如果您看到 mlockall
为 false
,则表示 mlockall
请求失败。您还会在日志中看到一行包含更多信息,其中包含 无法锁定 JVM 内存
字样。
在 Linux/Unix 系统上,最可能的原因是运行 Elasticsearch 的用户没有锁定内存的权限。可以按如下方式授予此权限
-
.zip
和.tar.gz
-
在启动 Elasticsearch 之前,以 root 身份设置
ulimit -l unlimited
。或者,在/etc/security/limits.conf
中将memlock
设置为unlimited
# allow user 'elasticsearch' mlockall elasticsearch soft memlock unlimited elasticsearch hard memlock unlimited
- RPM 和 Debian
- 在 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 标志。