ElasticSearch 7 权威指南(四)Elasticsearch的配置

配置Elasticsearch

Elasticsearch提供了良好的默认设置,只需要很少的配置。在正在运行的集群上的大多数设置可以使用Cluster update settings API更改。

配置文件应包含特定于节点的设置(如 node.name 和 paths),或节点为了加入集群所需的设置,如 cluster.namenetwork.host

配置文件路径

Elasticsearch有三个配置文件:

  • 用于配置 Elasticsearch 的 elasticsearch.yml
  • 用于配置 Elasticsearch JVM 的 jvm.options
  • 用于配置 Elasticsearch 日志的 log4j2.properties

这些文件位于 config 目录中,其默认路径取决于您是从归档包(tar.gzzip)还是从 Debian 或 RPM 包安装的。

对于归档包:config 目录默认为 $ES_HOME/config 。可以通过环境变量 ES_PATH_CONF 更改 config 目录,如下所示:

ES_PATH_CONF=/path/to/my/config ./bin/elasticsearch

也可以通过命令行或 shell 的 profile 文件里 export ES_PATH_CONF 环境变量。

对于Debian 或 RPM 包:config 目录默认为 /etc/elasticsearch,同样可以通过环境变量 ES_PATH_CONF 进行更改,但请注意,在shell中设置是不够的。相反,此变量来自 /etc/default/elasticsearch(Debian包)和 /etc/sysconfig/elasticsearch(RPM包)。您将需要相应地编辑其中一个文件中的 ES_PATH_CONF=/etc/elasticsearch 条目来更改 config 目录。

配置文件格式

配置格式为 YAML。下面是一个更改数据和日志目录的示例:

path:
    data: /var/lib/elasticsearch
    logs: /var/log/elasticsearch

设置也可以按如下方式展平:

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

环境变量的替换

配置文件中以 ${…} 格式引用的环境变量将被替换为环境变量的值。例如:

node.name:    ${HOSTNAME}
network.host: ${ES_NETWORK_HOST}

环境变量的值必须是简单字符串。使用逗号分隔的字符串将被 Elasticsearch 解析为值的列表。例如,Elasticsearch会将以下字符串拆分为环境变量 HOSTNAME 的值列表:

export HOSTNAME=“host1,host2"

集群和节点的设置类型

集群和节点设置可以根据它们的配置方式进行分类:

  • Dynamic

您可以使用 cluster update settings API 在正在运行的集群上配置和更新动态设置项。

您还可以使用 elasticsearch.yml 在未启动或已关闭的节点上本地配置动态设置项。

最好使用 cluster update settings API 配置动态的、集群范围内的设置项,并仅对本地配置使用 elasticsearch.yml。使用 cluster update settings API 可确保所有节点上的设置相同。如果您不小心在不同节点上的 elasticsearch.yml 中配置了不同的设置,可能很难发现差异。

  • Static

只能使用 elasticsearch.yml 在未启动或已关闭的节点上配置静态设置。

静态设置必须在集群中的每个关联节点上配置。

具体设置项

JVM 选项设置

您几乎不需要更改Java虚拟机(JVM)选项。如果更改,最有可能的情况是设置堆大小。本文档的其余部分将详细说明如何设置 JVM 选项。您可以通过 jvm.options 文件或环境变量 ES_JAVA_OPTS 设置选项。

设置或重写 JVM options 的首选方法是通过 jvm.options 文件。从 tar 或 zip 归档包安装时,则根 jvm.options 配置文件为 config/jvm.options,并且可以将自定义 JVM options 文件添加到 config/jvm.options.d/ 。从Debian或RPM软件包安装时,根 jvm.options 配置文件为 /etc/elasticsearch/jvm.options,可以将自定义 JVM options 文件添加到 /etc/elasticsearch/jvm.options.d/ 中。当使用Elasticsearch的Docker发行版时,可以把自定义 JVM options 文件挂载到 /usr/share/elasticsearch/config/jvm.options.d/ 下。您应该永远不需要修改根 jvm.options 文件,而是使用自定义jvm选项文件。自定义jvm选项按字典序来处理设置。

JVM options 文件必须以 .options 作为后缀 ,并包含一些特殊语法、以行分隔的JVM参数列表:

  • 忽略仅包含空格的行
  • 以 # 开头的行被视为注释,并被忽略
# this is a comment

- 开头的行被视为独立于JVM版本的JVM选项

-Xmx2g

以数字开头、并且跟着 :- 的行也被视为JVM选项,不过该选项仅在JVM版本与数字匹配时才适用

8:-Xmx2g

以数字开头、并且跟着 -: 的行也被视为JVM选项,仅在JVM版本大于或等于该数字时才适用

8-:-Xmx2g

以数字开头、并且跟着 - 、数字和 : 的行也被视为JVM选项,仅当JVM的版本在两个数字的范围内时才适用

8-9:-Xmx2g

所有其他类型的行都会被拒绝

另一种设置JAVA虚拟机选项的方法是通过环境变量 ES_JAVA_OPTS。例如:

export ES_JAVA_OPTS="$ES_JAVA_OPTS -Djava.io.tmpdir=/path/to/temp/dir"
./bin/elasticsearch

当使用RPM或Debian包时,可以在系统配置文件中指定 ES_JAVA_OPTS

JVM 有个内置机制,可以观察 JAVA_TOOL_OPTIONS 环境变量。我们有意在打包脚本中忽略此环境变量。其主要原因是,在某些操作系统(例如Ubuntu)上,默认情况下通过此环境变量安装了代理,我们不希望这些代理干扰 Elasticsearch。

此外,其他一些java程序支持 JAVA_OPTS 环境变量。这不是jvm的内置机制,而是生态系统中的约定。但是,我们不支持这个环境变量,而是支持通过 jvm.options 文件或环境变量 ES_JAVA_OPTS 设置JVM选项,如上所述。

被保护的设置

有些设置比较敏感,依靠文件系统权限来保护它们的值还不够。对于这种情况,Elasticsearch提供了一个密钥库和相关工具来管理密钥库中的设置。

仅有部分设置被设计为从密钥库中读取。但是,密钥库没有校验是否有不支持的设置。将不支持的设置添加到密钥库会导致Elasticsearch无法启动。要查看密钥库是否支持该设置,请在设置参考中查找 “Secure” 修饰符。

重启Elasticsearch之后,对密钥库的所有修改才会生效。

这些设置与 elasticsearch.yml 配置文件中的常规设置一样,需要在集群的每个节点上指定。 目前所有被保护的设置项都是特定于节点的设置,在每个节点上必须具有相同的值。

被保护设置的重新加载

就像 elasticsearch.yml 中的设置值一样,对密钥库内容的更改不会自动应用于正在运行的Elasticsearch节点。重新读取设置需要重启节点。但是,某些被保护的设置被标记为可重新加载。这样的设置可以被重新读取并应用于正在运行的节点

所有被保护的设置的值(可重新加载或不可重新加载)必须在集群的所有节点上相同。在更改所需的设置后,使用 bin/elasticsearch-keystore add 命令调用:

POST _nodes/reload_secure_settings
{
  "secure_settings_password": "s3cr3t" 
}

注:用于加密Elasticsearch密钥库的密码。

该API在集群的每个节点上解密并重新读取整个密钥库,但仅应用可重新加载的被保护设置。对其他设置的更改需要重启生效。调用返回后,重新加载就完成了,这意味着依赖这些设置的所有内部数据结构都变了,一切看上去就好像设置从一开始就是新值。

当更改多个可重新加载的被保护设置时,请在集群中每个节点上修改所有设置,然后发出reload_secure_settings 调用,而不是在每次修改后重新加载。

有以下可重新加载的被保护设置:

审计安全设置

您可以在集群中的每个节点上的 elasticsearch.yml 配置文件中配置安全审计设置。详情请参阅日志审计启用

开启审计

xpack.security.audit.enabled 设置为 true 可启用节点上的审计。默认值为 false。这会将审计事件放在每个节点上名为 <clustername>_audit.json 的专用文件中。

审计事件

事件或者一些内容记录都是可以通过以下设置来进行配置:
xpack.security.audit.logfile.events.include 指定审计输出中包含哪些事件,一共包含:access_denied, access_granted, anonymous_access_denied, authentication_failed, connection_denied, tampered_request, run_as_denied, run_as_granted 这些事件。

xpack.security.audit.logfile.events.exclude 从输出中排除某些事件。默认情况下,不排除任何事件。

xpack.security.audit.logfile.events.emit_request_body 指定是否在某些特定事件(如 authentication_failed)的REST请求中包含请求body,默认值是 false

审计时不会过滤,因此在审计事件中包括请求body时,敏感数据可能会以纯文本形式审计。

本地节点信息

xpack.security.audit.logfile.emit_node_name 指定是否在每个审计事件中包含节点名作为字段,默认是 true

xpack.security.audit.logfile.emit_node_host_address 指定是否包含节点的ip地址作为字段,默认是 false

xpack.security.audit.logfile.emit_node_host_name 指定是否包含节点的域名作为字段,默认是 false

xpack.security.audit.logfile.emit_node_id 指定是否包含节点的ID作为字段,默认是 true。该信息不会在 <clustername>_access.log 里面,他是一种新格式,不像节点名可以通过配置修改,ID在集群重启的时候就确定了,管理员无法修改。

审计事件忽略策略

这些设置会影响忽略策略,这些策略以更细粒度空值哪些审计事件打印到日志文件。具有相同策略名称的所有设置合并为一个策略。如果事件匹配特定策略的所有条件,则将忽略该事件并不打印它。

xpack.security.audit.logfile.events.ignore_filters.<policy_name>.users 用户名或通配符列表。用户匹配了这些策略,那么将不打印日志。

xpack.security.audit.logfile.events.ignore_filters.<policy_name>.realms 身份验证名称或通配符列表。用户满足这些指定身份的策略,那么将不打印日志。

xpack.security.audit.logfile.events.ignore_filters.<policy_name>.roles 角色名或者通配符列表。用户有这些角色的话,那么将不打印日志。如果用户有多个角色,但是有一些策略不在这个范围内,那么这个事件对那些策略不起作用。

xpack.security.audit.logfile.events.ignore_filters.<policy_name>.indices 索引名或者通配符列表。当事件中的所有索引都匹配这些值时,指定的策略将不会打印审计事件。如果事件涉及多个索引,其中一些索引不包含在策略中,则策略将不包含此事件。

熔断器设置

Elasticsearch 含多种熔断器用来避免因为操作引起来的OutOfMemoryError(内存溢出错误). 每个熔断器指定可以使用多少内存的限制。 另外,还有一个父级别的熔断器,指定可以在所有熔断器上使用的总内存量。

除非另有说明,否则可以使用 cluster-update-settings API 在正在运行的集群上动态更新这些设置。

父熔断器

可以使用以下设置配置父熔断器:

indices.breaker.total.use_real_memory 静态设置,确定是父熔断器应该考虑实际内存使用情况(true),还是仅考虑子熔断器保留的内存量(false)。 默认为true。

indices.breaker.total.limit 整个父熔断器的启动限制。
如果 indices.breaker.total.use_real_memoryfalse,则默认为JVM堆的70%。
如果 indices.breaker.total.use_real_memorytrue,则默认为JVM堆的95%。

列数据熔断器

列数据熔断器,Elasticsearch系统会估计一个列加载到内存中需要消耗多少内存,它可以避免因为列字段加载(缓存)增长过多带来的异常。 默认配置为最大JVM堆的40%。它可以使用以下参数进行配置:

indices.breaker.fielddata.limit 列数据熔断器限制,默认为JVM堆的40%。

indices.breaker.fielddata.overhead 所有列数据乘以一个常量得到最终的值。 默认为1.03。

请求熔断器

请求熔断器允许Elasticsearch防止每个请求数据结构(例如,用于在请求期间计算聚合的内存)超过指定特定的内存量。

indices.breaker.request.limit 请求熔断器限制,默认为JVM堆的60%。

indices.breaker.request.overhead 所有请求乘以一个常量得到最终的值。 默认为1。

请求并发熔断器

请求并发熔断器允许Elasticsearch限制当前进来的所有传输层或HTTP活跃请求的总内存使用,使其不超过节点的特定的内存量。内存使用基于请求本身的内容长度。该熔断器还认为,不仅原始请求需要内存,一些结构化对象也是不少的开销。

与请求熔断器不同的是,请求熔断器控制单个query占用的空间大小,而求并发熔断器是限制当前进来的所有活跃请求的内存总量,用于限制并发请求流量。

network.breaker.inflight_requests.limit 请求并发熔断器的限制,默认为JVM堆的100%,这意味着它受父熔断器限制的约束。

network.breaker.inflight_requests.overhead 所有并发请求的估算值都将与该常数相乘以确定最终估算值。 默认为2。

累计请求熔断器

累计请求熔断器允许Elasticsearch限制请求完成后未释放的内存使用。例如 Lucene Segment memory(段内存)。

indices.breaker.accounting.limit 累计请求熔断器的限制,默认为JVM堆的100%,这意味着它受父熔断器限制的约束。

indices.breaker.accounting.overhead 所有累计请求的估算值都将与该常数相乘以确定最终估算值。 默认为1。

脚本编译熔断器

与上面基于内存的熔断器略有不同,脚本编译熔断器在一段时间内限制了内联脚本编译的数量。

有关详细信息,请参阅脚本文档的 “首选参数” 部分。

script.max_compilations_rate 限制在特定时间间隔内允许编译的唯一动态脚本数。默认值为75 / 5m,即每5分钟75次。

集群层面的分片分配、路由设置

分片分配是节点之间分片重新分配的过程。这可能发生在节点初始化恢复、副本的复制分配、重新平衡过程中,或者在添加或删除节点时。

主服务器的主要功能之一就是决定将哪些分片分配给哪些节点,以及何时在节点之间移动分片,以便重新平衡集群。

有许多设置可用于控制分片分配过程:

  • 集群层面的分片分配设置控制分配和重新平衡的操作。
  • 基于磁盘的分片分配设置解释了Elasticsearch是如何考虑可用磁盘空间的,以及相关设置。
  • 分片分配感知和强制感知特性可以控制分片分布于不同机房或可用区域。
  • 集群级分片分配过滤允许从分配中排除某些节点或节点组,以便它们可以被摘除。

除此之外,还有一些其他的集群层面设置。

所有这些设置都是 动态 的,可以使用cluster-update-settings API 在正在运行的集群上更新。

集群层面分片分配设置

以下动态设置可用于控制分片分配和恢复:
cluster.routing.allocation.enable 启用或禁用指定类型分片的分配:

  • all -(默认)允许所有类型的分片分配。
  • primaries - 仅允许主分片的分配。
  • new_primaries - 仅允许新索引的主分片的分配。
  • none - 不允许对任何索引进行任何种类的分片分配。

但是这个设置对节点重启时本地主分片的恢复没有影响,重启节点时,如果本地有一个未被分配的主分片的拷贝,还是会立即被用于恢复这个主分片,前提是该分片属于群集中的一个活跃分片。

cluster.routing.allocation.node_concurrent_incoming_recoveries 在一个节点上允许同时恢复多少个传入的分片,一般指从其它节点的副本分片恢复至本节点,除非是分片的重新平衡,默认为 2

cluster.routing.allocation.node_concurrent_outgoing_recoveries 在一个节点上允许同时发送多少个恢复分片。一般指分片从本节点恢复至其它节点,除非是分片的重新平衡,否则很有可能是主分片,默认为 2

cluster.routing.allocation.node_concurrent_recoveries 同时设置上面两个值。

cluster.routing.allocation.node_initial_primaries_recoveries 初始化数据恢复时,指定并发恢复线程数,默认为 4,副本分片恢复是通过网络进行的,而节点重启后,未分配的主分片的恢复则使用本地磁盘中的数据,由于启用了多线程,这个恢复比较快。

cluster.routing.allocation.same_shard.host 允许根据主机名和主机地址进行检查,防止主副本分片被分配到同一台物理主机上。默认为 false,表示默认情况下不执行检查。该设置仅在同一台计算机上启动多个节点时适用。

分片重新平衡设置

以下动态设置可用于控制集群分片的重新平衡:
cluster.routing.rebalance.enable 启用或禁用指定类型分片的重新平衡:

  • all -(默认)允许对所有类型的分片平衡。
  • primaries - 仅允许对主分片进行分片平衡。
  • replicas - 仅允许对副本分片进行分片平衡。
  • none - 任何索引都不允许进行任何类型的分片平衡。