网络编辑

每个 Elasticsearch 节点都有两个不同的网络接口。客户端使用其 HTTP 接口 向 Elasticsearch 的 REST API 发送请求,但节点之间使用 传输接口 进行通信。传输接口也用于与 远程集群 进行通信。

您可以使用 network.* 设置同时配置这两个接口。如果您有一个更复杂的网络,您可能需要使用 http.*transport.* 设置独立配置接口。在可能的情况下,请使用适用于这两个接口的 network.* 设置,以简化您的配置并减少重复。

默认情况下,Elasticsearch 仅绑定到 localhost,这意味着无法远程访问它。此配置足以满足由一个或多个节点组成的本地开发集群,所有节点都在同一主机上运行。要在多台主机上形成集群,或者要使远程客户端可以访问集群,您必须调整一些 网络设置,例如 network.host

请谨慎配置网络!

切勿将未受保护的节点暴露在公共互联网上。如果您这样做,您将允许世界上任何人下载、修改或删除集群中的任何数据。

将 Elasticsearch 配置为绑定到非本地地址将 将一些警告转换为致命异常。如果节点在配置其网络设置后拒绝启动,则必须先解决记录的异常,然后再继续。

常用的网络设置编辑

大多数用户只需要配置以下网络设置。

network.host

(静态,字符串) 设置此节点的 HTTP 和传输流量地址。节点将绑定到此地址,并将其用作其发布地址。接受 IP 地址、主机名或 特殊值

默认为 _local_。但是,请注意,安全自动配置 会将 http.host: 0.0.0.0 添加到您的 elasticsearch.yml 配置文件中,这将覆盖 HTTP 流量的默认值。

http.port

(静态,整数) 用于绑定 HTTP 客户端通信的端口。接受单个值或范围。如果指定了范围,则节点将绑定到该范围内第一个可用的端口。

默认为 9200-9300

transport.port

(静态,整数) 用于绑定节点间通信的端口。接受单个值或范围。如果指定了范围,则节点将绑定到该范围内第一个可用的端口。在每个符合主节点条件的节点上,将此设置设置为单个端口,而不是范围。

默认为 9300-9400

remote_cluster.port

(静态,整数) 用于绑定远程集群客户端通信的端口。接受单个值。

默认为 9443

网络地址的特殊值编辑

您可以将 Elasticsearch 配置为使用以下特殊值自动确定其地址。在配置 network.hostnetwork.bind_hostnetwork.publish_host 以及 HTTP 和传输接口的相应设置时,请使用这些值。

_local_
系统上的任何环回地址,例如 127.0.0.1
_site_
系统上的任何站点本地地址,例如 192.168.0.1
_global_
系统上的任何全局范围地址,例如 8.8.8.8
_[networkInterface]_
使用名为 [networkInterface] 的网络接口的地址。例如,如果您希望使用名为 en0 的接口的地址,则设置 network.host: _en0_
0.0.0.0
所有可用网络接口的地址。

在某些系统中,这些特殊值会解析为多个地址。如果是这样,Elasticsearch 将选择其中一个作为其发布地址,并且可能会在每次节点重启时更改其选择。确保您的节点在每个可能的地址上都可以访问。

任何包含 : 的值(例如 IPv6 地址或某些 特殊值)都必须用引号引起来,因为 : 在 YAML 中是特殊字符。

IPv4 与 IPv6编辑

默认情况下,这些特殊值会同时生成 IPv4 和 IPv6 地址,但您也可以添加 :ipv4:ipv6 后缀,以将它们分别限制为仅 IPv4 或 IPv6 地址。例如,network.host: "_en0:ipv4_" 会将此节点的地址设置为接口 en0 的 IPv4 地址。

云端发现

在云端运行时,如果安装了 EC2 发现插件Google Compute Engine 发现插件,则可以使用更多特殊设置。

绑定和发布编辑

Elasticsearch 将网络地址用于两种不同的目的,称为绑定和发布。大多数节点将对所有内容使用相同的地址,但更复杂的设置可能需要为不同的目的配置不同的地址。

当 Elasticsearch 等应用程序希望接收网络通信时,它必须向操作系统指示它应该接收其流量的地址。这称为*绑定*到这些地址。如果需要,Elasticsearch 可以绑定到多个地址,但大多数节点只绑定到一个地址。只有当 Elasticsearch 在具有该地址的网络接口的主机上运行时,它才能绑定到该地址。如有必要,您可以将传输和 HTTP 接口配置为绑定到不同的地址。

每个 Elasticsearch 节点都有一个地址,客户端和其他节点可以通过该地址与其联系,称为其*发布地址*。每个节点的 HTTP 接口和传输接口各有一个发布地址。这两个地址可以是任何地址,不需要是主机上网络接口的地址。唯一的要求是每个节点必须

  • 在其 HTTP 发布地址上可供所有将使用嗅探发现它的客户端访问。
  • 在其传输发布地址上可供其集群中的所有其他节点以及将使用 远程集群 发现它的任何远程集群访问。

如果您使用主机名指定传输发布地址,则 Elasticsearch 将在启动期间将此主机名解析为 IP 地址一次,其他节点将使用生成的 IP 地址,而不是自己再次解析该名称。为避免混淆,请使用在所有网络位置都解析为节点地址的主机名。

使用单个地址编辑

最常见的配置是 Elasticsearch 绑定到一个地址,客户端和其他节点可以通过该地址访问它。在此配置中,您应该将 network.host 设置为该地址。您不应该单独设置任何绑定或发布地址,也不应该单独配置 HTTP 或传输接口的地址。

使用多个地址编辑

如果您希望将 Elasticsearch 绑定到多个地址,或者要发布与您要绑定的地址不同的地址,请使用 高级网络设置。将 network.bind_host 设置为绑定地址,并将 network.publish_host 设置为此节点公开的地址。在复杂配置中,您可以为 HTTP 和传输接口配置不同的地址。

高级网络设置编辑

这些高级设置允许您绑定到多个地址,或者使用不同的地址进行绑定和发布。在大多数情况下不需要它们,如果您能够使用 常用的设置,则不应使用它们。

network.bind_host
(静态,字符串) 节点应绑定到的网络地址,以便侦听传入连接。接受 IP 地址、主机名和 特殊值 列表。默认为 network.host 给定的地址。仅当绑定到多个地址或对发布和绑定使用不同地址时,才使用此设置。
network.publish_host
(静态,字符串) 客户端和其他节点可用于连接此节点的网络地址。接受 IP 地址、主机名或 特殊值。默认为 network.host 给定的地址。仅当绑定到多个地址或对发布和绑定使用不同地址时,才使用此设置。

您可以为 network.hostnetwork.publish_host 指定地址列表。您还可以指定一个或多个主机名或 特殊值,它们解析为多个地址。如果这样做,则 Elasticsearch 会选择其中一个地址作为其发布地址。此选择使用基于 IPv4/IPv6 堆栈偏好和可达性的试探法,并且可能在节点重新启动时发生变化。确保每个节点在所有可能的发布地址上都可访问。

高级 TCP 设置编辑

使用以下设置来控制 HTTP 和传输接口使用的 TCP 连接的低级参数。

network.tcp.keep_alive
(静态,布尔值) 为网络套接字配置 SO_KEEPALIVE 选项,该选项确定每个连接是否发送 TCP 保活探测。默认为 true
network.tcp.keep_idle
(静态,整数) 为网络套接字配置 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP 保活探测之前必须处于空闲状态的时间(以秒为单位)。默认为 -1,这意味着使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
network.tcp.keep_interval
(静态,整数) 为网络套接字配置 TCP_KEEPINTVL 选项,该选项确定发送 TCP 保活探测之间的时间间隔(以秒为单位)。默认为 -1,这意味着使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
network.tcp.keep_count
(静态,整数) 为网络套接字配置 TCP_KEEPCNT 选项,该选项确定在连接断开之前可以发送的未确认 TCP 保活探测的数量。默认为 -1,这意味着使用系统默认值。仅适用于 Linux 和 macOS。
network.tcp.no_delay
(静态,布尔值) 在网络套接字上配置 TCP_NODELAY 选项,该选项确定是否启用 TCP 无延迟。默认为 true
network.tcp.reuse_address
(静态,布尔值) 为网络套接字配置 SO_REUSEADDR 选项,该选项确定地址是否可以重用。在 Windows 上默认为 false,在其他情况下默认为 true
network.tcp.send_buffer_size
(静态字节值) 配置网络套接字的 TCP 发送缓冲区的大小。默认为 -1,这意味着使用系统默认值。
network.tcp.receive_buffer_size
(静态字节值) 配置 TCP 接收缓冲区的大小。默认为 -1,这意味着使用系统默认值。

高级 HTTP 设置编辑

使用以下高级设置可以独立于 传输接口 配置 HTTP 接口。您还可以使用 网络设置 同时配置两个接口。

http.host

(静态,字符串) 设置此节点的 HTTP 流量地址。节点将绑定到此地址,并将其用作其 HTTP 发布地址。接受 IP 地址、主机名或 特殊值。仅当您需要为传输和 HTTP 接口使用不同的配置时,才使用此设置。

默认为 network.host 给定的地址。但是,请注意,安全自动配置 会将 http.host: 0.0.0.0 添加到您的 elasticsearch.yml 配置文件中,这会覆盖此默认值。

http.bind_host
(静态,字符串) 节点应绑定到的网络地址,以便侦听传入 HTTP 连接。接受 IP 地址、主机名和 特殊值 列表。默认为 http.hostnetwork.bind_host 给定的地址。仅当您需要绑定到多个地址或对发布和绑定使用不同地址,并且还需要为传输和 HTTP 接口使用不同的绑定配置时,才使用此设置。
http.publish_host
(静态,字符串) HTTP 客户端使用嗅探连接节点的网络地址。接受 IP 地址、主机名或 特殊值。默认为 http.hostnetwork.publish_host 给定的地址。仅当您需要绑定到多个地址或对发布和绑定使用不同地址,并且还需要为传输和 HTTP 接口使用不同的绑定配置时,才使用此设置。
http.publish_port
(静态,整数) HTTP 发布地址 的端口。仅当您需要发布端口与 http.port 不同时,才配置此设置。默认为通过 http.port 分配的端口。
http.max_content_length
(静态字节值) HTTP 请求正文的最大大小。如果正文已压缩,则限制适用于压缩前的 HTTP 请求正文大小。默认为 100mb。将此设置配置为大于 100mb 可能会导致集群不稳定,因此不建议这样做。如果您在向 批量 API 发送请求时达到此限制,请将您的客户端配置为在每个批量请求中发送更少的文档。如果您希望索引超过 100mb 的单个文档,请在将它们发送到 Elasticsearch 之前,将它们预处理为较小的文档。例如,将原始数据存储在 Elasticsearch 之外的系统中,并在 Elasticsearch 索引的文档中包含指向原始数据的链接。
http.max_initial_line_length
(静态字节值) HTTP URL 的最大大小。默认为 4kb
http.max_header_size
(静态字节值) 允许的标头的最大大小。默认为 16kb
http.compression logo cloud

(静态,布尔值) 尽可能支持压缩(使用 Accept-Encoding)。如果启用了 HTTPS,则默认为 false。否则,默认为 true

禁用 HTTPS 压缩可以降低潜在的安全风险,例如 BREACH 攻击。要压缩 HTTPS 流量,您必须将 http.compression 显式设置为 true

http.compression_level
(静态,整数) 定义用于 HTTP 响应的压缩级别。有效值在 1(最小压缩)和 9(最大压缩)之间。默认为 3
http.cors.enabled logo cloud

(静态,布尔值) 启用或禁用跨域资源共享,这决定了另一个域上的浏览器是否可以对 Elasticsearch 执行请求。设置为 true 以使 Elasticsearch 能够处理预检 CORS 请求。如果 http.cors.allow-origin 列表允许请求中发送的 Origin,则 Elasticsearch 将使用 Access-Control-Allow-Origin 标头响应这些请求。设置为 false(默认值)以使 Elasticsearch 忽略 Origin 请求标头,从而有效地禁用 CORS 请求,因为 Elasticsearch 永远不会使用 Access-Control-Allow-Origin 响应标头进行响应。

如果客户端没有发送带有 Origin 标头的预检请求,或者它没有检查服务器的响应标头以验证 Access-Control-Allow-Origin 响应标头,则跨域安全性就会受到损害。如果在 Elasticsearch 上未启用 CORS,则客户端知道的唯一方法是发送预检请求并意识到缺少所需的响应标头。

http.cors.allow-origin logo cloud

(静态,字符串) 允许的来源。如果在值的开头和结尾添加正斜杠 (/),则该值将被视为正则表达式,允许您支持 HTTP 和 HTTPs。例如,使用 /https?:\/\/localhost(:[0-9]+)?/ 将在两种情况下都适当地返回请求标头。默认为不允许任何来源。

通配符 (*) 是一个有效值,但被认为是一个安全风险,因为您的 Elasticsearch 实例将对来自 任何地方 的跨域请求开放。

http.cors.max-age logo cloud
(静态,整数) 浏览器发送“预检”OPTIONS 请求以确定 CORS 设置。 max-age 定义结果应缓存多长时间(以秒为单位)。默认为 1728000(20 天)。
http.cors.allow-methods logo cloud
(静态,字符串) 允许的方法。默认为 OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers logo cloud
(静态,字符串) 允许的标头。默认为 X-Requested-With, Content-Type, Content-Length, Authorization, Accept, User-Agent, X-Elastic-Client-Meta
http.cors.expose-headers logo cloud
(静态) 要在客户端中公开的响应标头。默认为 X-elastic-product
http.cors.allow-credentials logo cloud

(静态,布尔值) 是否应返回 Access-Control-Allow-Credentials 标头。默认为 false

仅当该设置设置为 true 时,才会返回此标头。

http.detailed_errors.enabled
(静态,布尔值) 配置是否启用 HTTP 响应中的详细错误报告。默认为 true,这意味着包含 ?error_trace 参数 的 HTTP 请求如果遇到异常,将返回包含堆栈跟踪的详细错误消息。如果设置为 false,则拒绝包含 ?error_trace 参数的请求。
http.pipelining.max_events
(静态,整数) 在关闭 HTTP 连接之前,要在内存中排队的最大事件数,默认为 10000
http.max_warning_header_count
(静态,整数) 客户端 HTTP 响应中警告标头的最大数量。默认为 -1,这意味着警告标头的数量不受限制。
http.max_warning_header_size
(静态字节值) 客户端 HTTP 响应中警告标头的最大总大小。默认为 -1,这意味着警告标头的大小不受限制。
http.tcp.keep_alive
(静态,布尔值) 为此套接字配置 SO_KEEPALIVE 选项,该选项确定它是否发送 TCP 保活探测。默认为 network.tcp.keep_alive
http.tcp.keep_idle
(静态,整数) 为 HTTP 套接字配置 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP 保活探测之前必须处于空闲状态的时间(以秒为单位)。默认为 network.tcp.keep_idle,它使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
http.tcp.keep_interval
(静态,整数) 为 HTTP 套接字配置 TCP_KEEPINTVL 选项,该选项确定发送 TCP 保活探测之间的时间间隔(以秒为单位)。默认为 network.tcp.keep_interval,它使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
http.tcp.keep_count
(静态,整数) 为 HTTP 套接字配置 TCP_KEEPCNT 选项,该选项确定在断开连接之前,可以在连接上发送的未确认 TCP 保活探测的数量。默认为 network.tcp.keep_count,它使用系统默认值。仅适用于 Linux 和 macOS。
http.tcp.no_delay
(静态,布尔值) 在 HTTP 套接字上配置 TCP_NODELAY 选项,该选项确定是否启用 TCP 无延迟。默认为 true
http.tcp.reuse_address
(静态,布尔值) 为 HTTP 套接字配置 SO_REUSEADDR 选项,该选项确定地址是否可以重用。在 Windows 上默认为 false,否则为 true
http.tcp.send_buffer_size
(静态字节值) HTTP 流量的 TCP 发送缓冲区大小。默认为 network.tcp.send_buffer_size
http.tcp.receive_buffer_size
(静态字节值) HTTP 流量的 TCP 接收缓冲区大小。默认为 network.tcp.receive_buffer_size
http.client_stats.enabled
(动态,布尔值) 启用或禁用 HTTP 客户端统计信息的收集。默认为 true
http.client_stats.closed_channels.max_count
(静态,整数) 当 http.client_stats.enabledtrue 时,设置 Elasticsearch 报告统计信息的已关闭 HTTP 通道的最大数量。默认为 10000
http.client_stats.closed_channels.max_age
(静态时间值) 当 http.client_stats.enabledtrue 时,设置关闭 HTTP 通道后 Elasticsearch 将报告该通道统计信息的最长时间。默认为 5m

HTTP 客户端配置编辑

许多 HTTP 客户端和代理都配置为类似浏览器的响应延迟,并且默认情况下会设置相当短的超时时间,如果 Elasticsearch 完成请求处理的时间超过此超时时间,则会报告失败。Elasticsearch 最终将始终响应每个请求,但某些请求可能需要几分钟的处理时间才能完成。请仔细考虑您的客户端的默认响应超时时间是否适合您的需求。在许多情况下,最好等待更长时间以获得响应,而不是失败,这意味着您应该禁用任何响应超时时间

  • 如果您通过重试请求来响应超时,则重试通常最终会放在保存原始请求的同一队列的末尾。因此,如果您超时并重试,而不是更有耐心地等待,则完成请求的处理将花费更长时间。重试还会给 Elasticsearch 带来额外的负载。
  • 如果请求不是幂等的,并且无法重试,则使请求失败是您的最后手段。更有耐心地等待响应通常会使整个操作成功。

如果您在客户端中禁用了响应超时,请确保改为配置 TCP 保活。TCP 保活是防止客户端在网络中断时无限期等待的推荐方法。

高级传输设置编辑

使用以下高级设置可以独立于 HTTP 接口 配置传输接口。使用 网络设置 可以同时配置这两个接口。

transport.host

(静态,字符串) 设置此节点用于传输流量的地址。该节点将绑定到此地址,并将其用作其传输发布地址。接受 IP 地址、主机名或 特殊值。仅当您需要为传输和 HTTP 接口进行不同的配置时,才使用此设置。

默认为 network.host 给定的地址。

transport.bind_host
(静态,字符串) 节点应绑定到的网络地址,以便侦听传入的传输连接。接受 IP 地址、主机名和 特殊值 的列表。默认为 transport.hostnetwork.bind_host 给定的地址。仅当您需要绑定到多个地址或使用不同的地址进行发布和绑定,并且还需要为传输和 HTTP 接口进行不同的绑定配置时,才使用此设置。
transport.publish_host
(静态,字符串) 其他节点可以通过其联系此节点的网络地址。接受 IP 地址、主机名或 特殊值。默认为 transport.hostnetwork.publish_host 给定的地址。仅当您需要绑定到多个地址或使用不同的地址进行发布和绑定,并且还需要为传输和 HTTP 接口进行不同的绑定配置时,才使用此设置。
transport.publish_port
(静态,整数) 传输发布地址 的端口。仅当您需要发布端口与 transport.port 不同时,才设置此参数。默认为通过 transport.port 分配的端口。
transport.connect_timeout
(静态时间值) 建立新连接的连接超时时间(以时间设置格式)。默认为 30s
transport.compress

(静态,字符串) 确定在将哪些传输请求发送到另一个节点之前对其进行压缩。仅当相应的请求被压缩时,Elasticsearch 才会压缩传输响应。另请参阅 transport.compression_scheme,它指定了使用的压缩方案。接受以下值

false
不压缩任何传输请求。此选项使用最多的网络带宽,但避免了压缩和解压缩的 CPU 开销。
indexing_data
仅压缩摄取期间、CCR 跟踪(引导除外)和基于操作的分片恢复(基于文件的恢复除外,后者复制原始 Lucene 数据)期间节点之间发送的原始索引数据。此选项在节省网络带宽和压缩和解压缩所需的额外 CPU 之间取得了良好的平衡。此选项为默认选项。
true
压缩所有传输请求。在网络带宽方面,此选项的性能可能优于 indexing_data,但压缩和解压缩工作将需要最多的 CPU。
transport.compression_scheme
静态,字符串)为由 transport.compress 设置选择进行压缩的请求配置压缩方案。接受 deflatelz4,它们在压缩率和 CPU 使用率之间提供了不同的权衡。Elasticsearch 将对响应使用与相应请求相同的压缩方案。默认为 lz4
transport.tcp.keep_alive
静态,布尔值)为传输套接字配置 SO_KEEPALIVE 选项,该选项确定它们是否发送 TCP 保活探测。默认为 network.tcp.keep_alive
transport.tcp.keep_idle
静态,整数)为传输套接字配置 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP 保活探测之前必须处于空闲状态的时间(以秒为单位)。如果设置了 network.tcp.keep_idle,则默认为该值,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
transport.tcp.keep_interval
静态,整数)为传输套接字配置 TCP_KEEPINTVL 选项,该选项确定发送 TCP 保活探测之间的时间间隔(以秒为单位)。如果设置了 network.tcp.keep_interval,则默认为该值,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
transport.tcp.keep_count
静态,整数)为传输套接字配置 TCP_KEEPCNT 选项,该选项确定在断开连接之前,连接上可以发送的未确认 TCP 保活探测的数量。如果设置了 network.tcp.keep_count,则默认为该值,否则默认为系统默认值。仅适用于 Linux 和 macOS。
transport.tcp.no_delay
静态,布尔值)在传输套接字上配置 TCP_NODELAY 选项,该选项确定是否启用 TCP 无延迟。默认为 true
transport.tcp.reuse_address
静态,布尔值)为网络套接字配置 SO_REUSEADDR 选项,该选项确定地址是否可以重复使用。默认为 network.tcp.reuse_address
transport.tcp.send_buffer_size
静态字节值)传输流量的 TCP 发送缓冲区的大小。默认为 network.tcp.send_buffer_size
transport.tcp.receive_buffer_size
静态字节值)传输流量的 TCP 接收缓冲区的大小。默认为 network.tcp.receive_buffer_size
transport.ping_schedule
静态时间值)配置在所有传输连接上发送应用程序级 ping 之间的时间,以便及时检测传输连接何时发生故障。默认为 -1,表示不发送应用程序级 ping。应尽可能使用 TCP 保活(请参阅 transport.tcp.keep_alive),而不是应用程序级 ping。

传输配置文件编辑

Elasticsearch 允许您通过使用传输配置文件绑定到不同接口上的多个端口。请参阅此示例配置

transport.profiles.default.port: 9300-9400
transport.profiles.default.bind_host: 10.0.0.1
transport.profiles.client.port: 9500-9600
transport.profiles.client.bind_host: 192.168.0.1
transport.profiles.dmz.port: 9700-9800
transport.profiles.dmz.bind_host: 172.16.1.2

default 配置文件很特殊。如果任何其他配置文件没有设置特定的配置设置,则它将用作回退,并且是此节点连接到集群中其他节点的方式。其他配置文件可以有任何名称,并且可以用于为传入连接设置特定端点。

可以在每个传输配置文件上配置以下参数,如上例所示

  • port:要绑定到的端口。
  • bind_host:要绑定到的主机。
  • publish_host:在信息 API 中发布的主机。

配置文件还支持 传输设置 部分中指定的所有其他传输设置,并将这些设置用作默认值。例如,可以显式配置 transport.profiles.client.tcp.reuse_address,否则默认为 transport.tcp.reuse_address

长期空闲连接编辑

两个节点之间的传输连接由许多长期存在的 TCP 连接组成,其中一些连接可能会长时间处于空闲状态。尽管如此,Elasticsearch 要求这些连接保持打开状态,如果任何节点间连接因外部影响(例如防火墙)而关闭,则可能会中断集群的运行。务必配置网络以保留 Elasticsearch 节点之间长期存在的空闲连接,例如,保持启用 *.tcp.keep_alive 并确保保活间隔短于可能导致空闲连接关闭的任何超时,或者如果无法配置保活,则设置 transport.ping_schedule。当连接达到一定年龄时断开连接的设备是 Elasticsearch 集群常见的问题根源,因此不得使用。

请求压缩编辑

默认的 transport.compress 配置选项 indexing_data 将仅压缩与节点之间原始索引源数据的传输相关的请求。此选项主要压缩在摄取、ccr 和分片恢复期间发送的数据。此默认值通常适用于本地集群通信,因为压缩原始文档往往会显着减少节点间网络使用量,而对 CPU 的影响最小。

transport.compress 设置始终配置本地集群请求压缩,并且是远程集群请求压缩的回退设置。如果要为远程请求压缩配置与本地请求压缩不同的配置,则可以使用 cluster.remote.${cluster_alias}.transport.compress 设置 为每个远程集群设置它。

响应压缩编辑

压缩设置不配置响应的压缩。如果入站请求已压缩,则 Elasticsearch 将压缩响应,即使未启用压缩也是如此。同样,如果入站请求未压缩,则 Elasticsearch 不会压缩响应,即使启用了压缩也是如此。用于压缩响应的压缩方案将与远程节点用于压缩请求的方案相同。

高级远程集群(基于 API 密钥的模型)设置编辑

使用以下高级设置可以独立于 传输接口 配置远程集群接口(基于 API 密钥的模型)。您还可以使用 网络设置 同时配置这两个接口。

remote_cluster_server.enabled
静态,布尔值)确定是否应启用远程集群服务器。此设置必须为 trueremote_cluster.port 和以下所有远程集群设置才能生效。启用此设置允许集群使用基于 API 密钥的模型来处理跨集群请求。默认为 false
remote_cluster.host

静态,字符串)为远程集群服务器流量设置此节点的地址。该节点将绑定到此地址,并将其用作其远程集群服务器发布地址。接受 IP 地址、主机名或 特殊值。仅当您需要为远程集群服务器和传输接口使用不同的配置时,才使用此设置。

默认为 transport.bind_host 给出的地址。

remote_cluster.bind_host
静态,字符串)节点应绑定到的网络地址,以便侦听传入的远程集群连接。接受 IP 地址、主机名和 特殊值 的列表。默认为 remote_cluster.host 给出的地址。仅当您需要绑定到多个地址或使用不同的地址进行发布和绑定,并且还需要为远程集群服务器和传输接口使用不同的绑定配置时,才使用此设置。
remote_cluster.publish_host
静态,字符串)其他节点可以通过该网络地址联系到该节点。接受 IP 地址、主机名或 特殊值。默认为 remote_cluster.host 给出的地址。仅当您需要绑定到多个地址或使用不同的地址进行发布和绑定,并且还需要为远程集群服务器和传输接口使用不同的绑定配置时,才使用此设置。
remote_cluster.publish_port
静态,整数)远程集群服务器发布地址的端口。仅当需要发布端口与 remote_cluster.port 不同时,才设置此参数。默认为通过 remote_cluster.port 分配的端口。
remote_cluster.tcp.keep_alive
静态,布尔值)为远程集群套接字配置 SO_KEEPALIVE 选项,该选项确定它们是否发送 TCP keepalive 探测。默认为 transport.tcp.keep_alive
remote_cluster.tcp.keep_idle
静态,整数)为传输套接字配置 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP keepalive 探测之前必须处于空闲状态的时间(以秒为单位)。如果设置了,则默认为 transport.tcp.keep_idle,否则为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
remote_cluster.tcp.keep_interval
静态,整数)为传输套接字配置 TCP_KEEPINTVL 选项,该选项确定发送 TCP keepalive 探测之间的时间间隔(以秒为单位)。如果设置了,则默认为 transport.tcp.keep_interval,否则为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
remote_cluster.tcp.keep_count
静态,整数)为传输套接字配置 TCP_KEEPCNT 选项,该选项确定在连接断开之前可以发送的未确认 TCP keepalive 探测的数量。如果设置了,则默认为 transport.tcp.keep_count,否则为系统默认值。仅适用于 Linux 和 macOS。
remote_cluster.tcp.no_delay
静态,布尔值)在传输套接字上配置 TCP_NODELAY 选项,该选项确定是否启用 TCP 无延迟。默认为 transport.tcp.no_delay
remote_cluster.tcp.reuse_address
静态,布尔值)为网络套接字配置 SO_REUSEADDR 选项,该选项确定地址是否可以重用。默认为 transport.tcp.reuse_address
remote_cluster.tcp.send_buffer_size
静态字节值)传输流量的 TCP 发送缓冲区大小。默认为 transport.tcp.send_buffer_size
remote_cluster.tcp.receive_buffer_size
静态字节值)传输流量的 TCP 接收缓冲区大小。默认为 transport.tcp.receive_buffer_size

请求跟踪编辑

您可以跟踪在 HTTP 和传输层上发出的各个请求。

跟踪可能会生成极高的日志量,从而导致集群不稳定。请勿在繁忙或重要的集群上启用请求跟踪。

REST 请求跟踪器编辑

HTTP 层有一个专用跟踪器,用于记录传入请求和相应的传出响应。通过将 org.elasticsearch.http.HttpTracer 记录器的级别设置为 TRACE 来激活跟踪器。

response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.http.HttpTracer": 'TRACE'
    }
  }
)
puts response
PUT _cluster/settings
{
   "persistent" : {
      "logger.org.elasticsearch.http.HttpTracer" : "TRACE"
   }
}

您还可以使用一组包含和排除通配符模式来控制将跟踪哪些 URI。默认情况下,将跟踪每个请求。

response = client.cluster.put_settings(
  body: {
    persistent: {
      'http.tracer.include' => '*',
      'http.tracer.exclude' => ''
    }
  }
)
puts response
PUT _cluster/settings
{
   "persistent" : {
      "http.tracer.include" : "*",
      "http.tracer.exclude" : ""
   }
}

默认情况下,跟踪器会记录与这些过滤器匹配的每个请求和响应的摘要。要同时记录每个请求和响应的正文,请将系统属性 es.insecure_network_trace_enabled 设置为 true,然后将 org.elasticsearch.http.HttpTracerorg.elasticsearch.http.HttpBodyTracer 记录器的级别都设置为 TRACE

response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.http.HttpTracer": 'TRACE',
      "logger.org.elasticsearch.http.HttpBodyTracer": 'TRACE'
    }
  }
)
puts response
PUT _cluster/settings
{
   "persistent" : {
      "logger.org.elasticsearch.http.HttpTracer" : "TRACE",
      "logger.org.elasticsearch.http.HttpBodyTracer" : "TRACE"
   }
}

每个消息正文都经过压缩、编码并拆分为多个块,以避免截断。

[TRACE][o.e.h.HttpBodyTracer     ] [master] [276] response body [part 1]: H4sIAAAAAAAA/9...
[TRACE][o.e.h.HttpBodyTracer     ] [master] [276] response body [part 2]: 2oJ93QyYLWWhcD...
[TRACE][o.e.h.HttpBodyTracer     ] [master] [276] response body (gzip compressed, base64-encoded, and split into 2 parts on preceding log lines)

每个块都标有内部请求 ID(在本例中为 [276]),您应该使用该 ID 将块与相应的摘要行相关联。要重建输出,请对数据进行 base64 解码,然后使用 gzip 对其进行解压缩。例如,在类 Unix 系统上:

cat httptrace.log | sed -e 's/.*://' | base64 --decode | gzip --decompress

HTTP 请求和响应正文可能包含敏感信息,例如凭据和密钥,因此默认情况下禁用 HTTP 正文跟踪。您必须通过在每个节点上将系统属性 es.insecure_network_trace_enabled 设置为 true 来显式启用它。此功能主要用于不包含任何敏感信息的测试系统。如果在包含敏感信息的系统上设置此属性,则必须保护您的日志免遭未经授权的访问。

传输跟踪器编辑

传输层有一个专用跟踪器,用于记录传入和传出的请求和响应。通过将 org.elasticsearch.transport.TransportService.tracer 记录器的级别设置为 TRACE 来激活跟踪器。

response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.transport.TransportService.tracer": 'TRACE'
    }
  }
)
puts response
PUT _cluster/settings
{
   "persistent" : {
      "logger.org.elasticsearch.transport.TransportService.tracer" : "TRACE"
   }
}

您还可以使用一组包含和排除通配符模式来控制将跟踪哪些操作。默认情况下,将跟踪每个请求,但故障检测 ping 除外。

response = client.cluster.put_settings(
  body: {
    persistent: {
      'transport.tracer.include' => '*',
      'transport.tracer.exclude' => 'internal:coordination/fault_detection/*'
    }
  }
)
puts response
PUT _cluster/settings
{
   "persistent" : {
      "transport.tracer.include" : "*",
      "transport.tracer.exclude" : "internal:coordination/fault_detection/*"
   }
}

网络线程模型编辑

本节介绍 Elasticsearch 中网络子系统使用的线程模型。使用 Elasticsearch 不需要这些信息,但对于诊断集群中网络问题的高级用户来说,这些信息可能很有用。

Elasticsearch 节点通过一组 TCP 通道进行通信,这些通道共同构成一个传输连接。Elasticsearch 客户端通过 HTTP 与集群通信,HTTP 也使用一个或多个 TCP 通道。这些 TCP 通道中的每一个都由节点中 transport_worker 线程中的一个线程拥有。此拥有线程在通道打开时选择,并在通道的整个生命周期内保持不变。

每个 transport_worker 线程都全权负责通过其拥有的通道发送和接收数据。此外,每个 http 和传输服务器套接字都分配给一个 transport_worker 线程。该工作线程负责接受到其拥有的服务器套接字的新传入连接。

如果 Elasticsearch 中的某个线程想要通过特定通道发送数据,它会将数据传递给拥有该通道的 transport_worker 线程以进行实际传输。

通常,transport_worker 线程不会完全处理它们接收到的消息。相反,它们将执行少量初步处理,然后将消息调度(移交)给不同的 线程池 以进行其余处理。例如,批量消息被调度到 write 线程池,搜索被调度到 search 线程池之一,而对统计信息和其他管理任务的请求大多被调度到 management 线程池。但是,在某些情况下,消息的处理预计会非常快,以至于 Elasticsearch 会在 transport_worker 线程上完成所有处理,而不是将其调度到其他地方的开销。

默认情况下,每个 CPU 对应一个 transport_worker 线程。相比之下,有时可能有数万个 TCP 通道。如果数据到达 TCP 通道,并且其拥有的 transport_worker 线程正忙,则在该线程完成其正在执行的任何操作之前,不会处理该数据。同样,在拥有该通道的 transport_worker 线程空闲之前,不会通过该通道发送传出数据。这意味着我们需要每个 transport_worker 线程都经常处于空闲状态。空闲的 transport_worker 在堆栈转储中看起来像这样:

"elasticsearch[instance-0000000004][transport_worker][T#1]" #32 daemon prio=5 os_prio=0 cpu=9645.94ms elapsed=501.63s tid=0x00007fb83b6307f0 nid=0x1c4 runnable  [0x00007fb7b8ffe000]
   java.lang.Thread.State: RUNNABLE
	at sun.nio.ch.EPoll.wait([email protected]/Native Method)
	at sun.nio.ch.EPollSelectorImpl.doSelect([email protected]/EPollSelectorImpl.java:118)
	at sun.nio.ch.SelectorImpl.lockAndDoSelect([email protected]/SelectorImpl.java:129)
	- locked <0x00000000c443c518> (a sun.nio.ch.Util$2)
	- locked <0x00000000c38f7700> (a sun.nio.ch.EPollSelectorImpl)
	at sun.nio.ch.SelectorImpl.select([email protected]/SelectorImpl.java:146)
	at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:813)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at java.lang.Thread.run([email protected]/Thread.java:833)

节点热点线程 API 中,空闲的 transport_worker 线程报告如下:

   0.0% [cpu=0.0%, idle=100.0%] (500ms out of 500ms) cpu usage by thread 'elasticsearch[instance-0000000004][transport_worker][T#1]'
     10/10 snapshots sharing following 9 elements
       [email protected]/sun.nio.ch.EPoll.wait(Native Method)
       [email protected]/sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:118)
       [email protected]/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
       [email protected]/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:146)
       io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:813)
       io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
       io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
       io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
       [email protected]/java.lang.Thread.run(Thread.java:833)

请注意,transport_worker 线程应始终处于 RUNNABLE 状态,即使在等待输入时也是如此,因为它们在本地 EPoll#wait 方法中阻塞。idle= 时间表示线程花费在等待输入上的时间比例,而 cpu= 时间表示线程花费在处理已接收输入上的时间比例。

如果 transport_worker 线程不经常处于空闲状态,则可能会积压大量工作。这可能会导致处理其拥有的通道上的消息延迟。很难准确预测哪些工作会延迟:

  • 通道比线程多得多。如果与一个通道相关的工作导致其工作线程延迟,则该线程拥有的所有其他通道也将遭受延迟。
  • 从 TCP 通道到工作线程的映射是固定的,但却是任意的。每个通道在打开时都以循环方式分配一个拥有线程。每个工作线程负责许多不同类型的通道。
  • 每对节点之间都打开了许多通道。对于每个请求,Elasticsearch 将以循环方式从适当的通道中进行选择。某些请求最终可能会出现在延迟工作线程拥有的通道上,而其他相同的请求将发送到运行平稳的通道上。

如果积压的工作太多,某些消息可能会延迟几秒钟。该节点甚至可能 无法通过其运行状况检查 并从集群中删除。有时,您可以使用 节点热点线程 API 找到 transport_worker 线程繁忙的证据。但是,此 API 本身也会发送网络消息,因此如果 transport_worker 线程太忙,则可能无法正常工作。使用 jstack 获取堆栈转储或使用 Java Flight Recorder 获取分析跟踪更为可靠。这些工具独立于 JVM 正在执行的任何工作。

还可以从服务器日志中识别出一些延迟原因,特别是查看来自 org.elasticsearch.transport.InboundHandlerorg.elasticsearch.transport.OutboundHandler 的警告。来自 InboundHandler 的有关长时间处理的警告尤其表明线程行为不正确,而 OutboundHandler 报告的传输时间包括等待网络拥塞的时间,并且 transport_worker 线程在此期间可以自由执行其他工作。