# 重要的系统配置

## 重要的系统配置

理想情况下，Elasticsearch应该在服务器上单独运行并使用所有可用资源。为此，您需要配置您的操作系统，以允许运行Elasticsearch的用户访问比默认允许更多的资源。

进入生产之前，**必须**考虑以下设置：

* [禁用交换](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setup-configuration-memory.html)
* [增加文件描述符](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/file-descriptors.html)
* [确保有足够的虚拟内存](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/vm-max-map-count.html)
* [确保足够的线程](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/max-number-of-threads.html)
* [JVM DNS缓存设置](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/networkaddress-cache-ttl.html)
* [临时目录未安装 `noexec`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/executable-jna-tmpdir.html)

### 开发模式与生产模式

默认情况下，Elasticsearch假定您正在开发模式下工作。如果以上任何设置的配置都不正确，将在日志文件中写入警告，但是您将能够启动和运行Elasticsearch节点。

一旦您配置了类似的网络设置`network.host`，Elasticsearch就会假定您即将投入生产，并将上述警告升级为异常。这些异常将阻止您的Elasticsearch节点启动。这是一项重要的安全措施，可确保不会因服务器配置错误而丢失数据。

## 配置系统设置

在哪里配置系统设置取决于您用于安装Elasticsearch的软件包以及所使用的操作系统。

使用`.zip`或`.tar.gz`软件包时，可以配置系统设置：

* 暂时与[`ulimit`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#ulimit)或
* 永久在[`/etc/security/limits.conf`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#limits.conf)。

使用RPM或Debian软件包时，大多数系统设置是在[系统配置文件](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#sysconfig)中设置的 。但是，使用systemd的系统要求在[systemd配置文件](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#systemd)中指定系统限制 。

### ulimit

在Linux系统上，`ulimit`可用于临时更改资源限制。通常需要像`root`切换到要运行Elasticsearch的用户之前那样设置限制。例如，要将打开的文件句柄（`ulimit -n`）的数量设置为65,536，可以执行以下操作：

```bash
sudo su  
ulimit -n 65535 
su elasticsearch
```

新限制仅适用于当前会话。

您可以通过查阅所有当前应用的限制`ulimit -a`。

### /etc/security/limits.conf

在Linux系统上，可以通过编辑`/etc/security/limits.conf`文件为特定用户设置持久限制。要将`elasticsearch`用户打开的最大文件数设置为65,536，请在`limits.conf`文件中添加以下行：

```bash
elasticsearch   -   nofile   65535
```

此更改仅在`elasticsearch`用户下次打开新会话时生效。

## 禁用交换

大多数操作系统尝试为文件系统缓存使用尽可能多的内存，并急切换出未使用的应用程序内存。这可能导致JVM堆的一部分甚至其可执行页面换出到磁盘上。

交换对性能，节点稳定性非常不利，应不惜一切代价避免交换。它可能导致垃圾收集持续**数分钟**而不是毫秒，并且可能导致节点响应缓慢甚至断开与群集的连接。在弹性分布式系统中，让操作系统杀死该节点更为有效。

有三种禁用交换的方法。首选选项是完全禁用交换。如果这不是一个选择，则是否要尽量减少交换性而不是内存锁定取决于您的环境。

### 禁用所有交换文件

通常，Elasticsearch是在盒子上运行的唯一服务，其内存使用情况由JVM选项控制。无需启用交换功能。

在Linux系统上，可以通过运行以下命令暂时禁用交换：

```bash
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](http://opengroup.org/onlinepubs/007908799/xsh/mlockall.html)或 在Windows 上 使用 \[VirtualLock]\([https://msdn.microsoft.com/en-us/library/windows/desktop/aa366895(v=vs.85).aspx)尝试将进程地址空间锁定在RAM中，以防止任何Elasticsearch内存被换出。可以通过将以下行添加到\`config/elasticsearch.yml\`文件中来完成此操作：](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366895\(v=vs.85\).aspx\)%E5%B0%9D%E8%AF%95%E5%B0%86%E8%BF%9B%E7%A8%8B%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E9%94%81%E5%AE%9A%E5%9C%A8RAM%E4%B8%AD%EF%BC%8C%E4%BB%A5%E9%98%B2%E6%AD%A2%E4%BB%BB%E4%BD%95Elasticsearch%E5%86%85%E5%AD%98%E8%A2%AB%E6%8D%A2%E5%87%BA%E3%80%82%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%B0%86%E4%BB%A5%E4%B8%8B%E8%A1%8C%E6%B7%BB%E5%8A%A0%E5%88%B0%60config/elasticsearch.yml%60%E6%96%87%E4%BB%B6%E4%B8%AD%E6%9D%A5%E5%AE%8C%E6%88%90%E6%AD%A4%E6%93%8D%E4%BD%9C%EF%BC%9A)

```yaml
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`**

    [`ulimit -l unlimited`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#ulimit)在启动Elasticsearch之前 设置为root，或者设置`memlock`为`unlimited`in [`/etc/security/limits.conf`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#limits.conf)。
*   **RPM和Debian**

    在 [系统配置文件中](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#sysconfig) 设置`MAX_LOCKED_MEMORY`为（对于使用的系统，请参见下文 ）。 `unlimited``systemd`
*   **系统使用 `systemd`**

    在[systemd配置中](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#systemd) 设置`LimitMEMLOCK`为。 `infinity`

`mlockall`失败的另一个可能原因是 [JNA临时目录（通常是的子目录 `/tmp`）是通过`noexec`option 挂载的](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/executable-jna-tmpdir.html)。这可以通过使用`ES_JAVA_OPTS`环境变量为JNA指定新的临时目录来解决：

```bash
export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djna.tmpdir=<path>"
./bin/elasticsearch
```

或在jvm.options配置文件中设置此JVM标志

## 文件描述符

> 这仅与Linux和macOS有关，如果在Windows上运行Elasticsearch，则可以安全地忽略它。在Windows上，JVM使用 仅受可用资源限制的 \[API]\([https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx)。](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858\(v=vs.85\).aspx\)%E3%80%82)

Elasticsearch使用许多文件描述符或文件句柄。文件描述符用尽可能是灾难性的，很可能导致数据丢失。确保将运行Elasticsearch的用户的打开文件描述符数限制增加到65,536或更高。

对于`.zip`和`.tar.gz`包，[`ulimit -n 65535`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#ulimit)在启动Elasticsearch之前设置为root，或者设置`nofile`为`65535`in [`/etc/security/limits.conf`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#limits.conf)。

在macOS上，您还必须将JVM选项传递`-XX:-MaxFDLimit` 给Elasticsearch，以使其使用较高的文件描述符限制。

RPM和Debian软件包已经默认将文件描述符的最大数量设置为65535，并且不需要进一步配置。

您可以`max_file_descriptors`使用[Nodes stats](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/cluster-nodes-stats.html) API 检查每个节点的配置，其中包括：

```
GET _nodes / stats / process ？filter_path = **。max_file_descriptors
```

## 虚拟内存

Elasticsearch [`mmapfs`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/index-modules-store.html#mmapfs)默认使用目录来存储其索引。默认的操作系统对mmap计数的限制可能太低，这可能会导致内存不足异常。

在Linux上，您可以通过运行以下命令来增加限制 `root`：

```bash
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`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#ulimit)在启动Elasticsearch之前设置为root或设置`nproc`为`4096`in来完成 [`/etc/security/limits.conf`](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/setting-system-settings.html#limits.conf)。

包分发作为服务运行时，`systemd`将自动为Elasticsearch进程配置线程数。无需其他配置。

## DNS缓存设置

Elasticsearch在适当的位置运行安全管理器。有了安全管理器，JVM默认将无限期地缓存正主机名解析，并且默认将十秒内缓存负主机名解析。Elasticsearch使用默认值覆盖此行为，以将正向查找缓存六十秒，并将负向查找缓存十秒。这些值应适用于大多数环境，包括DNS分辨率随时间变化的环境。如果没有，您可以 在[JVM选项中](https://www.elastic.co/guide/en/elasticsearch/reference/7.x/jvm-options.html)编辑值`es.networkaddress.cache.ttl`和`es.networkaddress.cache.negative.ttl`。需要注意的是 [`networkaddress.cache.ttl=`](http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html) 和[`networkaddress.cache.negative.ttl=`](http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html) 价值 和 在 [Java安全策略](http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html)由Elasticsearch忽略，除非你删除的设置 `es.networkaddress.cache.ttl` 和`es.networkaddress.cache.negative.ttl`.

## JNA临时目录未通过安装 noexec

> 这仅与Linux有关。

Elasticsearch使用Java本机访问（JNA）库来执行一些平台相关的本机代码。在Linux上，在运行时从JNA存档中提取支持该库的本机代码。默认情况下，此代码被提取到Elasticsearch临时目录，该目录默认为的子目录 `/tmp`。或者，可以使用JVM标志来控制此位置 `-Djna.tmpdir=`。由于本机库以可执行文件的形式映射到JVM虚拟地址空间中，因此必须**不**装入提取此代码的位置的基础安装点，`noexec`因为这会阻止JVM进程将其映射为可执行文件。在某些加固的Linux安装中，这是默认的安装选项`/tmp`。表示已安装基础安装的一种迹象`noexec`是，在启动时，JNA将无法加载，并且`java.lang.UnsatisfiedLinkerError`带有一条消息，带有一条类似的消息`failed to map segment from shared object`。请注意，在JVM版本之间，异常消息可能有所不同。此外，依赖于通过JNA执行本机代码的Elasticsearch组件将失败，并显示指示其为的消息`because JNA is not available`。如果看到这样的错误消息，则必须重新挂载JNA所用的临时目录，以使其不能挂载`noexec`。
