网络

编辑

每个 Elasticsearch 节点都有两个不同的网络接口。客户端使用其 HTTP 接口向 Elasticsearch 的 REST API 发送请求,而节点之间则使用 传输接口进行通信。传输接口还用于与 远程集群的通信。传输接口使用通过 长时 TCP 通道发送的自定义二进制协议。这两个接口都可以配置为使用 TLS 来增强安全性

您可以使用 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 将在启动期间将此值解析为单个 IP 地址,并且其他节点将使用生成的 IP 地址,而不是再次自行解析该值。您必须使用一个值,以便它可以解析的所有地址都是节点可以从所有其他节点访问的地址。为避免混淆,最简单的方法是使用解析为单个地址的值。在具有多个网络接口的主机上,通常将 0.0.0.0 用作发布地址是错误的。

使用单个地址

编辑

最常见的配置是使 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 keepalive 探测。默认为 true
network.tcp.keep_idle
静态,整数)配置网络套接字的 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP keepalive 探测之前必须空闲的秒数。默认为 -1,表示使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
network.tcp.keep_interval
静态,整数)配置网络套接字的 TCP_KEEPINTVL 选项,该选项确定发送 TCP keepalive 探测之间的间隔时间(秒)。默认为 -1,表示使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
network.tcp.keep_count
静态,整数)配置网络套接字的 TCP_KEEPCNT 选项,该选项确定在连接断开之前可以在连接上发送的未确认 TCP keepalive 探测的数量。默认为 -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 请求。如果请求中发送的 Originhttp.cors.allow-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,这意味着如果 HTTP 请求包含 ?error_trace 参数,并且遇到异常,则会返回包含堆栈跟踪的详细错误消息。如果设置为 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 keepalive 探测。默认为 network.tcp.keep_alive
http.tcp.keep_idle
静态,整数)配置 HTTP 套接字的 TCP_KEEPIDLE 选项,该选项确定在开始发送 TCP keepalive 探测之前,连接必须处于空闲状态的时间(以秒为单位)。默认为 network.tcp.keep_idle,它使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
http.tcp.keep_interval
静态,整数)配置 HTTP 套接字的 TCP_KEEPINTVL 选项,该选项确定发送 TCP keepalive 探测之间的时间间隔(以秒为单位)。默认为 network.tcp.keep_interval,它使用系统默认值。此值不能超过 300 秒。仅适用于 Linux 和 macOS。
http.tcp.keep_count
静态,整数)配置 HTTP 套接字的 TCP_KEEPCNT 选项,该选项确定在断开连接之前可以在连接上发送的未确认的 TCP keepalive 探测的数量。默认为 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 keepalives。TCP keepalives 是防止客户端在发生网络中断时无限期等待的推荐方法。

高级传输设置

编辑

使用以下高级设置可以独立于 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 keepalive 探测。默认为 network.tcp.keep_alive
transport.tcp.keep_idle
静态,整数)配置传输套接字的 TCP_KEEPIDLE 选项,该选项确定在开始发送 TCP keepalive 探测之前,连接必须空闲多少秒。如果设置了,则默认为 network.tcp.keep_idle,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
transport.tcp.keep_interval
静态,整数)配置传输套接字的 TCP_KEEPINTVL 选项,该选项确定发送 TCP keepalive 探测之间的时间间隔(以秒为单位)。如果设置了,则默认为 network.tcp.keep_interval,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值会自动降低到 300。仅适用于 Linux 和 macOS。
transport.tcp.keep_count
静态,整数)配置传输套接字的 TCP_KEEPCNT 选项,该选项确定在连接断开之前可以在连接上发送的未确认 TCP keepalive 探测的数量。如果设置了,则默认为 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 keepalive(请参阅 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 并确保 keepalive 间隔短于任何可能导致空闲连接关闭的超时,或者在无法配置 keepalive 时设置 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
静态,布尔值)确定是否应启用远程集群服务器。对于 remote_cluster.port 和所有后续远程集群设置生效,此设置必须为 true。启用后,群集可以使用基于 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 保活探测。默认为 transport.tcp.keep_alive
remote_cluster.tcp.keep_idle
(静态, 整数) 配置传输套接字的 TCP_KEEPIDLE 选项,该选项确定连接在开始发送 TCP 保活探测之前必须空闲的秒数。如果设置了 transport.tcp.keep_idle,则默认为该值,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值将自动降低为 300。仅适用于 Linux 和 macOS。
remote_cluster.tcp.keep_interval
(静态, 整数) 配置传输套接字的 TCP_KEEPINTVL 选项,该选项确定发送 TCP 保活探测之间的秒数。如果设置了 transport.tcp.keep_interval,则默认为该值,否则默认为系统默认值。此值不能超过 300 秒。如果系统默认值高于 300,则该值将自动降低为 300。仅适用于 Linux 和 macOS。
remote_cluster.tcp.keep_count
(静态, 整数) 配置传输套接字的 TCP_KEEPCNT 选项,该选项确定在丢弃连接之前可以在连接上发送的未确认 TCP 保活探测的数量。如果设置了 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 来激活跟踪器

resp = client.cluster.put_settings(
    persistent={
        "logger.org.elasticsearch.http.HttpTracer": "TRACE"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.http.HttpTracer": 'TRACE'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "logger.org.elasticsearch.http.HttpTracer": "TRACE",
  },
});
console.log(response);
PUT _cluster/settings
{
   "persistent" : {
      "logger.org.elasticsearch.http.HttpTracer" : "TRACE"
   }
}

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

resp = client.cluster.put_settings(
    persistent={
        "http.tracer.include": "*",
        "http.tracer.exclude": ""
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      'http.tracer.include' => '*',
      'http.tracer.exclude' => ''
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "http.tracer.include": "*",
    "http.tracer.exclude": "",
  },
});
console.log(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

resp = client.cluster.put_settings(
    persistent={
        "logger.org.elasticsearch.http.HttpTracer": "TRACE",
        "logger.org.elasticsearch.http.HttpBodyTracer": "TRACE"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.http.HttpTracer": 'TRACE',
      "logger.org.elasticsearch.http.HttpBodyTracer": 'TRACE'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "logger.org.elasticsearch.http.HttpTracer": "TRACE",
    "logger.org.elasticsearch.http.HttpBodyTracer": "TRACE",
  },
});
console.log(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 来激活跟踪器

resp = client.cluster.put_settings(
    persistent={
        "logger.org.elasticsearch.transport.TransportService.tracer": "TRACE"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      "logger.org.elasticsearch.transport.TransportService.tracer": 'TRACE'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "logger.org.elasticsearch.transport.TransportService.tracer": "TRACE",
  },
});
console.log(response);
PUT _cluster/settings
{
   "persistent" : {
      "logger.org.elasticsearch.transport.TransportService.tracer" : "TRACE"
   }
}

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

resp = client.cluster.put_settings(
    persistent={
        "transport.tracer.include": "*",
        "transport.tracer.exclude": "internal:coordination/fault_detection/*"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      'transport.tracer.include' => '*',
      'transport.tracer.exclude' => 'internal:coordination/fault_detection/*'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "transport.tracer.include": "*",
    "transport.tracer.exclude": "internal:coordination/fault_detection/*",
  },
});
console.log(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 线程的证据。但是,如果 transport_worker 线程过于繁忙,则此 API 本身会发送网络消息,因此可能无法正常工作。更可靠的方法是使用 jstack 获取堆栈转储或使用 Java Flight Recorder 获取分析跟踪。这些工具独立于 JVM 正在执行的任何工作。

也可能从服务器日志中识别出某些延迟的原因。例如,请参阅以下记录器

org.elasticsearch.transport.InboundHandler
如果处理入站消息占用了网络线程的时间过长(这几乎肯定是错误),则此记录器会报告警告。该警告包含一些信息,可用于识别花费过长时间处理的消息。
org.elasticsearch.transport.OutboundHandler
如果发送出站消息的时间超过预期,则此记录器会报告警告。此持续时间包括等待网络拥塞清除所花费的时间,以及在同一网络线程上处理其他工作所花费的时间,因此并不总是表示存在与日志条目中指定的出站消息相关的错误。
org.elasticsearch.common.network.ThreadWatchdog

当它注意到网络线程在两次连续检查之间没有取得进展时,此记录器会报告警告和线程转储,这几乎肯定是错误

[WARN ][o.e.c.n.ThreadWatchdog   ] the following threads are active but did not make progress in the preceding [5s]: [elasticsearch[instance-0000000004][transport_worker][T#1]]]
[WARN ][o.e.c.n.ThreadWatchdog   ] hot threads dump due to active threads not making progress [part 1]: H4sIAAAAAAAA/+1aa2/bOBb93l8hYLUYFWgYvWw5AQbYpEkn6STZbJyiwAwGA1qiY8US6ZJUHvPr90qk/JJky41TtDMuUIci...
[WARN ][o.e.c.n.ThreadWatchdog   ] hot threads dump due to active threads not making progress [part 2]: LfXL/x70a3eL8ve6Ral74ZBrp5x7HmUD9KXQz1MaXUNfFC6SeEysxSw1cNXL9JXYl3AigAE7ywbm/AZ+ll3Ox4qXJHNjVr6h...
[WARN ][o.e.c.n.ThreadWatchdog   ] hot threads dump due to active threads not making progress (gzip compressed, base64-encoded, and split into 2 parts on preceding log lines; ...

要重建线程转储,请将数据进行 base64 解码并使用 gzip 解压缩。例如,在类 Unix 系统上

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

此机制可以通过以下设置进行控制

network.thread.watchdog.interval
(静态, 时间值) 定义看门狗检查之间的间隔。默认为 5s。设置为 0 可禁用网络线程看门狗。
network.thread.watchdog.quiet_time
(静态, 时间值) 定义看门狗警告之间的间隔。默认为 10m