确保 JNA 临时目录允许执行文件

编辑

这仅适用于 Linux。

Elasticsearch 使用 Java Native Access (JNA) 库和另一个名为 libffi 的库来执行一些平台相关的本地代码。在 Linux 上,这些库的本地代码会在运行时被提取到一个临时目录中,然后映射到 Elasticsearch 地址空间中的可执行页面。这要求底层文件所在的 文件系统不能使用 noexec 选项挂载。

默认情况下,Elasticsearch 会在 /tmp 中创建其临时目录。但是,一些加固的 Linux 安装默认使用 noexec 选项挂载 /tmp。这会阻止 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
  • 对于通过 RPM 或 DEB 包进行的安装,需要通过 系统配置文件设置环境变量。
  • 如果您使用 systemd 将 Elasticsearch 作为服务运行,请在 服务覆盖文件中的 [Service] 部分添加以下行

    Environment=ES_TMPDIR=/usr/share/elasticsearch/tmp

如果需要对这些临时文件的位置进行更精细的控制,您还可以使用 JVM 标志 -Djna.tmpdir=<path> 配置 JNA 使用的路径,并且可以通过设置 LIBFFI_TMPDIR 环境变量来配置 libffi 用于其临时文件的路径。未来的 Elasticsearch 版本可能需要额外的配置,因此您应尽可能设置 ES_TMPDIR

Elasticsearch 不会删除其临时目录。您应该在 Elasticsearch 未运行时删除遗留的临时目录。最好自动执行此操作,例如在每次重新启动时执行。如果您在 Linux 上运行,可以通过使用 tmpfs 文件系统来实现此目的。