文章摘要(AI生成)
系统环境配置理想情况下,Elasticsearch 应该在服务器上单独运行并使用所有可用的资源。为此,您需要配置操作系统以允许运行 Elasticsearch 的用户访问比默认情况下允许的更多的资源。在投入生产之前必须考虑以下设置:配置系统设置禁用交换增加文件描述符确保足够的虚拟内存确保足够的线程J
系统环境配置
理想情况下,Elasticsearch 应该在服务器上单独运行并使用所有可用的资源。为此,您需要配置操作系统以允许运行 Elasticsearch 的用户访问比默认情况下允许的更多的资源。
在投入生产之前必须考虑以下设置:
默认情况下,Elasticsearch 假定您正在开发模式下工作。如果上述任何设置配置不正确,日志文件中将写入警告,但您将能够启动并运行 Elasticsearch 节点。
一旦您配置了诸如 之类的网络设置network.host
,Elasticsearch 就会假定您正在转向生产,并将上述警告升级为例外。这些异常将阻止您的 Elasticsearch 节点启动。这是一项重要的安全措施,可确保您不会因服务器配置错误而丢失数据。
配置系统设置
在何处配置系统设置取决于您用于安装 Elasticsearch 的软件包以及您使用的操作系统。
使用.zip
或.tar.gz
软件包时,可以配置系统设置:
- 暂时配置使用
ulimit
. - 持久化配置使用
/etc/security/limits.conf
.
使用 RPM 或 Debian 软件包时,大多数系统设置都是在 系统配置文件中设置的。但是,使用 systemd 的系统要求在systemd 配置文件中指定系统限制 。
ulimit
在 Linux 系统上,ulimit
可用于临时更改资源限制。通常需要像root
切换到将运行 Elasticsearch 的用户之前一样设置限制。例如,要将打开文件句柄 ( ulimit -n
) 的数量设置为 65,536,您可以执行以下操作:
sudo su
ulimit -n 65535
su elasticsearch
新限制仅在当前会话期间应用。
您可以使用ulimit -a
查询所有当前应用的限制.
/etc/security/limits.conf
在 Linux 系统上,可以通过编辑文件为特定用户设置持久限制/etc/security/limits.conf
。要将用户打开文件的最大数量设置elasticsearch
为 65,535,请将以下行添加到limits.conf
文件中:
elasticsearch - nofile 65535
elasticsearch
此更改仅在用户下次打开新会话时生效。
Ubuntu和limits.conf
Ubuntu会忽略limits.conf
由 启动的进程的文件init.d
。要启用该limits.conf
文件,请编辑/etc/pam.d/su
并取消注释以下行:
# session required pam_limits.so
系统配置文件
当使用 RPM 或 Debian 软件包时,可以在系统配置文件中指定环境变量,该文件位于:
RPM | /etc/sysconfig/elasticsearch |
---|---|
Debian | /etc/default/elasticsearch |
但是,系统限制需要通过systemd指定。
系统配置
在使用 systemd的系统上使用 RPM 或 Debian 软件包时,必须通过 systemd 指定系统限制。
systemd 服务文件 ( /usr/lib/systemd/system/elasticsearch.service
) 包含默认应用的限制。
要覆盖它们,请添加一个名为 /etc/systemd/system/elasticsearch.service.d/override.conf
的文件(或者,您可以运行sudo systemctl edit elasticsearch
,它在默认编辑器中自动打开该文件)。设置此文件中的任何更改,例如:
[Service]
LimitMEMLOCK=infinity
完成后,运行以下命令重新加载单元:
sudo systemctl daemon-reload
禁用内存交换
大多数操作系统尝试使用尽可能多的内存作为文件系统缓存,并急切地换出未使用的应用程序内存。这可能会导致部分 JVM 堆甚至其可执行页面被换出到磁盘。
交换对于性能和节点稳定性来说非常糟糕,应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒,并且可能导致节点响应缓慢甚至与集群断开连接。在弹性分布式系统中,让操作系统杀死节点更为有效。
可以通过三种方法来禁用交换。首选选项是完全禁用交换。如果这不是一个选项,则是否更喜欢最小化交换而不是内存锁定取决于您的环境。
禁用所有交换文件
通常,Elasticsearch 是唯一在机器上运行的服务,其内存使用情况由 JVM 选项控制。应该不需要启用交换。
在 Linux 系统上,您可以通过运行以下命令暂时禁用交换:
sudo swapoff - a
这不需要重新启动 Elasticsearch。
要永久禁用它,您需要编辑该/etc/fstab
文件并注释掉包含单词 的所有行swap
。
在 Windows 上,可以通过完全禁用分页文件来实现等效效果System Properties → Advanced → Performance → Advanced → Virtual memory
。
配置swappiness
Linux 系统上可用的另一个选项是确保 sysctl 值 vm.swappiness
设置为1
。这减少了内核交换的倾向,并且在正常情况下不应导致交换,同时仍然允许整个系统在紧急情况下进行交换。
使能够bootstrap.memory_lock
编辑
另一种选择是在 Linux/Unix 系统上使用 mlockall,或 在 Windows 上使用 VirtualLock ,尝试将进程地址空间锁定到 RAM,防止任何 Elasticsearch 堆内存被换出。
要启用内存锁定,请设置bootstrap.memory_lock
为true
in elasticsearch.yml
:
bootstrap.memory_lock: true
mlockall
启动 Elasticsearch 后,您可以通过检查此请求输出中的值来查看此设置是否已成功应用:
GET _nodes?filter_path=**.mlockall
如果您看到的mlockall
是false
,则表示mlockall
请求失败。您还将在日志中看到一行包含更多信息的文字Unable to lock JVM Memory
。
在 Linux/Unix 系统上,最可能的原因是运行 Elasticsearch 的用户没有锁定内存的权限。这可以按如下方式授予:
-
.zip
和.tar.gz
在启动 Elasticsearch 之前设置
ulimit -l unlimited
为 root。或者,在/etc/security/limits.conf
中设置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 标志。
文件描述符设置
Elasticsearch 使用大量文件描述符或文件句柄。文件描述符用完可能是灾难性的,并且很可能会导致数据丢失。确保将运行 Elasticsearch 的用户的打开文件描述符数量限制增加到 65,536 或更高。
对于.zip
和.tar.gz
包,ulimit -n 65535
在启动 Elasticsearch 之前设置为 root,或者设置nofile
为65535
in /etc/security/limits.conf
。
在 macOS 上,您还必须将 JVM 选项传递-XX:-MaxFDLimit
给 Elasticsearch,以便它利用更高的文件描述符限制。
RPM 和 Debian 软件包已将文件描述符的最大数量默认为 65535,不需要进一步配置。
您可以使用Nodes statsmax_file_descriptors
API 检查每个节点的配置:
GET _nodes/stats/process?filter_path=**.max_file_descriptors
虚拟内存
Elasticsearch默认使用mmapfs
目录来存储其索引。默认操作系统对 mmap 计数的限制可能太低,这可能会导致内存不足异常。
在 Linux 上,您可以通过运行以下命令来增加限制 root
:
sysctl -w vm.max_map_count=262144
要永久设置此值,请更新vm.max_map_count
中的设置 /etc/sysctl.conf
。要在重新启动后进行验证,请运行sysctl vm.max_map_count
.
RPM 和 Debian 软件包将自动配置此设置。无需进一步配置。
线程数
Elasticsearch 使用多个线程池来执行不同类型的操作。重要的是它能够在需要时创建新线程。确保Elasticsearch用户可以创建的线程数至少为4096。
ulimit -u 4096
这可以通过在启动 Elasticsearch 之前设置为 root 或设置nproc
为4096
in 来完成/etc/security/limits.conf
。
当作为服务运行时,包发行版systemd
将自动配置 Elasticsearch 进程的线程数。无需额外配置。
DNS缓存设置
Elasticsearch 在适当的位置运行安全管理器。部署安全管理器后,JVM 默认无限期缓存正主机名解析,默认缓存负主机名解析 10 秒。Elasticsearch 使用默认值覆盖此行为,将正查找缓存 60 秒,将负查找缓存 10 秒。这些值应该适合大多数环境,包括 DNS 解析随时间变化的环境。 如果没有,您可以在JVM 选项中编辑值es.networkaddress.cache.ttl
和es.networkaddress.cache.negative.ttl
。请注意,除非您删除networkaddress.cache.ttl=<timeout>
和networkaddress.cache.negative.ttl=<timeout>
的设置,否则 Elasticsearch 将忽略 Java 安全策略 中的es.networkaddress.cache.ttl
和es.networkaddress.cache.negative.ttl
值。
确保 JNA 临时目录允许可执行文件
这仅与 Linux 相关。
Elasticsearch 使用 Java Native Access (JNA) 库和另一个名为 libffi
的库来执行一些依赖于平台的本机代码。在 Linux 上,支持这些库的本机代码在运行时被提取到临时目录中,然后映射到 Elasticsearch 地址空间中的可执行页面。这要求底层文件不能位于使用该 noexec
选项挂载的文件系统上。
默认情况下,Elasticsearch 将在/tmp
下. 但是,某些强化的 Linux 安装默认使用/tmp
下noexec
选项进行安装。这会阻止 JNA和libffi
正常工作。例如,在启动时,JNA 可能无法加载,并出现java.lang.UnsatisfiedLinkerError
异常或显示类似于 failed to map segment from shared object
的消息,或者libffi
可能报告诸如failed to allocate closure
之类的消息。请注意,不同 JVM 版本的异常消息可能有所不同。此外,依赖于通过 JNA 执行本机代码的 Elasticsearch 组件可能会失败,并显示消息 because JNA is not available
表明原因.
要解决这些问题,请从/tmp
文件目录中删除该noexec
选项,或者通过设置环境变量将 Elasticsearch 配置为为其临时目录使用不同的位置$ES_TMPDIR
。例如:
- 如果您直接从 shell 运行 Elasticsearch,请进行
$ES_TMPDIR
如下设置:
export ES_TMPDIR=/usr/share/elasticsearch/tmp
Environment=ES_TMPDIR=/usr/share/elasticsearch/tmp
如果您需要更好地控制这些临时文件的位置,您还可以通过JVM 标志 -Djna.tmpdir=<path>
配置 JNA 使用的路径,并且可以通过设置环境变量LIBFFI_TMPDIR
来配置libffi
用于其临时文件的路径。Elasticsearch 的未来版本可能需要额外的配置,因此您应该尽可能设置ES_TMPDIR
。
TCP重传超时
每对 Elasticsearch 节点通过多个 TCP 连接进行通信,这些连接一直保持打开状态,直到其中一个节点关闭或节点之间的通信因底层基础设施故障而中断。
TCP 通过对通信应用程序隐藏临时网络中断,在偶尔不可靠的网络上提供可靠的通信。在通知发件人任何问题之前,您的操作系统将多次重新传输任何丢失的消息。Elasticsearch 必须在重新传输发生时等待,并且只有在操作系统决定放弃时才能做出反应。因此,用户还必须等待一系列重传完成。
大多数 Linux 发行版默认重传丢失的数据包 15 次。重传会呈指数级下降,因此这 15 次重传需要 900 秒以上才能完成。这意味着 Linux 使用此方法需要花费很多分钟来检测网络分区或故障节点。Windows 默认仅重新传输 5 次,这对应于大约 6 秒的超时。
Linux 默认允许通过可能会经历很长一段时间丢包的网络进行通信,但这种默认设置对于大多数 Elasticsearch 安装所使用的高质量网络来说是过度的,甚至是有害的。当集群检测到节点故障时,它会通过重新分配丢失的分片、重新路由搜索以及可能选举新的主节点来做出反应。高可用集群必须能够及时检测节点故障,这可以通过减少允许的重传次数来实现。与 远程集群的连接也应该比 Linux 默认允许的更快地检测故障。因此,Linux 用户应该减少 TCP 重传的最大次数。
您可以通过root
运行以下命令来减少 TCP 重新传输的最大次数5。五次重传对应于大约六秒的超时。
sysctl -w net.ipv4.tcp_retries2=5
要永久设置此值,请更新net.ipv4.tcp_retries2
中的设置 /etc/sysctl.conf
。要在重新启动后进行验证,请运行 sysctl net.ipv4.tcp_retries2
.
相关配置
Elasticsearch 还实现了自己的内部健康检查,其超时时间比 Linux 上默认的重传超时时间短得多。由于这些是应用程序级别的运行状况检查,因此它们的超时必须考虑到应用程序级别的影响,例如垃圾收集暂停。您不应减少与这些应用程序级运行状况检查相关的任何超时。
您还必须确保您的网络基础设施不会干扰节点之间的长期连接,即使这些连接看似空闲。当达到一定年龄时断开连接的设备是 Elasticsearch 集群问题的常见来源,因此不得使用。
评论区