1.21 网络相关的配置
网络
每一个 Elasticsearch 节点都有两个不同的网络接口。客户端使用HTTP RESTFul接口向 Elasticsearch集群发送请求, 但是节点间的通信使用的事 transport 接口。 同时 transport 接口也用来和远程的集群进行通信。
network.* 开头的配置可以对两个接口同时生效。 如果你有更复杂的网络结构,你可能需要分开设置 http.* and transport.* 两个接口的配置。如果需要的话, 使用 network.* 配置可以同时使两个接口都生效,从而简化你的配置。
默认情况下 Elasticsearch 只绑定 localhost 本地地址,那意味着他不能被远程访问。对于由一个或多个节点组成的本地开发集群,这些节点都在同一台主机上运行,这种配置就足够了。对于运行在多个机器上的集群或者需要被远程的客户端访问到,你必须适配或者修改某些网络配置,例如 network.host。
小心这些网络配置:不要暴漏一个无防护的节点到公网,这么做会让网上所有的用户都能修改、下载、删除你的数据
配置 Elasticsearch 绑定到非本地地址会将将一些警告变成致命的异常。 如果一个节点在你修改网络配置之后无法启动,你就需要先解决你的日志里的异常然后再尝试启动。
常用的网络配置
大部分用户只需要配置下面这几个常用网络配置
network.host
(静态配置,字符串) HTTP和Transport同时生效。集群节点将绑定到这个地址上,并作为对外发布的地址 接受的值有ip地址、hostname主机地址,或者特殊的值special value。默认值是特殊值: local。
http.port
(静态配置, 数字) HTTP client 绑定的端口。 接受的值是一个值,或者是一个范围。如果设置的是一个范围的话,他会轮询绑定到范围里的第一个端口上。默认值是一个范围: 9200-9300。
transport.port
(静态配置, 数字) 节点间通信的端口。 和http.port类似,接受一个值或者一个范围,如果配置的是一个范围的话,他会尝试绑定第一个可用的端口上。每一个master-eligible 都应该设置成一个值,而不是一个范围。默认值是:9300-9400。
remote_cluster.port
(静态配置, 数字) [beta] 这个特性尚在beta中,并计划做一些改变。 这个设计不如官方的GA 特性成熟并且是没有保证的。Beta 特性没有SLA的支持和保证。这个端口是用来和远程的集群间通信用的,接受一个数值,默认值是9443。
一些特殊的网络地址
你可以通过一些特殊值让Elasticsearch可以自己决定自己的网络地址,这些值可以配置在这些配置项下network.host, network.bind_host, network.publish_host,并且可以同时在HTTP and transport interfaces.两个接口上生效。
local:回环地址,例如127.0.0.1
site: 没看懂,系统上的内网局域网地址? 例如 192.168.0.1
global: 系统上的外网地址?例如 8.8.8.8
[networkInterface]: 网卡地址,你可以配置网卡例如eth0,让系统自行读取这个卡上的网络地址
0.0.0.0: 所有地址皆可访问
** 注意: 如果上面这些特殊地址对应了多个ip地址(有的系统会这样),Elasticsearch在发布服务的时候会选择其中一个,如果发生了重启,他会重新选择其中一个,你不会知道他选择哪个,因此要保证这些地址都可以访问**
注意:任何地址如果包含了: 冒号,必须用引号圈起来,因为冒号在YMAL里是特殊符号。
IPv4 vs IPv6
这些特殊的地址既可以支持ipv4也可以支持ipv6,如果你有奇怪的需求,比如仅用ipv4,这个Elasticsearch也是支持的,你可以这样配置network.host: "en0:ipv4" ,这样他在选择的时候,只会选择ipv4地址。对的,你发现了规律,那就是使用冒号 :ipv4或者使用:ipv6来限定使用哪种ip
tips:某些配置比较特殊,仅仅存在于云计算平台上之上, EC2 discovery plugin 或者 Google Compute Engine discovery plugin 可以点击上面的链接查看
绑定和发布
Elasticsearch基于两个不同的目的来使用网络地址,分别是绑定和发布。大部分节点使用相同的地址,但是其他更复杂的设置可能需要不同的地址来达到上述目的。
当一个应用程序,如Elasticsearch希望接收网络通信时,它必须向操作系统指示应接收其流量的地址。这个就叫绑定到这些地址。必要的时候,ElastciSearch可以绑定多个地址,但是大部分的节点只需要绑定一个地址。当ElasticSearch在机器上运行时,只能绑定到宿主机上网卡拥有的地址。如果需要的话,你可以绑定HTTP和transport到不同的地址上。
每一个Elasticsearch节点都有一个客户端或者其他节点可以连接的地址,这个叫发布地址。每一个Elasticsearch节点有一个HTTP接口的发布地址和一个transport的地址,这两个地址可以随意设置,不需要必须是宿主机的网卡地址。唯一需要的是每一个节点必须:
- 能够被所有的http client在HTTP接口上访问,这些client将会使用嗅探来发现这些节点。
- 能够被集群里其他节点在transport地址上授权访问,能够被远程集群在transport接口上被授权访问,远程集群使用Remote clusters来发现他们。
如果你设置transport地址为主机名的话,Elasticsearch在系统启动的时候会将主机名解析成地址,然后其他节点连接他的时候,会使用他解析好的地址而不是主机名。为了避免冲突,请使用网络里唯一的主机地址。
使用单一地址
通常的做法是在客户端和其他节点连接的时候使用唯一的地址。在这种情况下,你只需要设置network.host到那个地址。你不需要分开设置绑定和发布地址,或者分开设置HTTP接口和transport接口。
使用多个地址
使用 advanced network settings 如果你想绑定Elasticsearch到多个地址,或者绑定和发布地址不同。使用network.bind_host设置绑定地址,network.publish_host设置发布地址以暴漏给外面使用。更复杂的配置你可以为HTTP接口和transport接口分开设置不同的地址。
高级网络设置(Advanced network settings)
以下这些高级配置可以让你绑定到多个地址,或者让你绑定地址和发布地址分开不同。大部分情况下,都用不到,尽量使用通用的默认配置代替他。
network.bind_host:
(Static, string) 为连接这个节点所绑定的监听地址。 接受值是一个列表,可以是ip地址、主机名、后者是特殊值。 默认值是network.host配置给出的地址。 仅仅在绑定到多个地址,或者绑定地址和发布地址需要设置不同值的时候使用。
network.publish_host:
(Static, string) 用于其他客户端和节点进行连接的地址。接受的是单个地址,ip地址、主机名、特殊值。 默认值是配置项network.host给出的值。 仅仅在绑定到多个地址,或者绑定地址和发布地址需要设置不同值的时候使用。
高级TCP配置
以下这些参数是用来控制使用HTTP接口或者transports接口时,底层的TCP连接参数。
network.tcp.keep_alive
(Static, boolean) 配置网络Socket的SO_KEEPALIVE配置项, 决定了每一个TCP链接是否发送keepalive探测。默认值是 true 。
network.tcp.keep_idle
(Static, integer) 配置网络Socket的 TCP_KEEPIDLE 选项, 决定了发送TCP keepalive 探测之前的空闲时间。默认值是 -1, 意味着使用操作系统的配置值。这个值不能超过300 秒。只有在Linux和MacOS操作系统上生效。
network.tcp.keep_interval
(Static, integer) 配置网络Socket的 TCP_KEEPINTVL 选项, 决定了发送 TCP keepalive探测间隔时间。默认值是 -1, 意味着使用操作系统的配置值。这个值不能超过300 秒。只有在Linux和MacOS操作系统上生效。
network.tcp.keep_count
(Static, integer) 配置网络Socket的 TCP_KEEPCNT 配置项,决定了在连接被丢弃之前可以容忍的不能确认的探测次数。默认值是 -1, 意味着使用操作系统的配置值。这个值不能超过300 秒。只有在Linux和MacOS操作系统上生效。
network.tcp.no_delay
(Static, boolean) 配置网络Socket的 TCP_NODELAY 配置项, 决定了是否开启 TCP no delay 。默认值是 true,开启。
network.tcp.reuse_address
(Static, boolean) 配置网络Socket的 SO_REUSEADDR 配置项, 决定了这个网络地址是否可以重用。 Windows系统默认值是false,其他操作系统是true。
network.tcp.send_buffer_size
(Static, byte value) 配置了 TCP 发送 buffer 大小. 默认值 -1 意味着使用操作系统的配置值。
network.tcp.receive_buffer_size
(Static, byte value) 配置 TCP receive buffer大小. 默认值为 -1 意味着使用操作系统的配置值。
高级HTTP配置
下面这些配置用来配置 HTTP 接口,并独立于 transport interface。如果要同时设置HTTP接口和transport接口,则使用 network settings。
http.host
(Static, string) 设置节点的HTTP通信地址。节点将绑定这个地址,并使用这个地址作为发布地址。 能够接受单个值,ip地址、主机地址或者是特殊值。仅仅在HTTP和transport需要不同的配置的时候再使用。默认值是使用network.host配置的地址。
http.bind_host
(Static, string) 为HTTP链接设置的绑定地址。接受一个列表,IP 地址、 主机名、特殊的值。默认是由 http.host 或者 network.bind_host两个配置项设置的。 当绑定地址和发布地址需要设置不同的值,并且HTTP和transport需要分开设置的时候才启用这个配置。
http.publish_host
(Static, string) HTTP客户端嗅探的时候的连接地址。 接受一个单个值,ip、主机名或者是特殊值。默认是由 http.host 或者 network.publish_host设置的。当绑定地址和发布地址需要设置不同的值,并且HTTP和transport需要分开设置的时候才启用这个配置。
http.publish_port
(Static, integer) HTTP发布地址的端口号。仅仅当你需要设置的发布端口和 http.port不一样的时候才需要设置。默认情况是使用 http.port配置项的值。
http.max_content_length
(Static, byte value) 最大的HTTP Reques body大小。 如果http body是被压缩的,那么这个值限定的是压缩前的体积大小。 默认值是 100mb。配置这个值操作 100mb 不被推荐,因为可能会导致集群的不稳定。如果你再使用Bulk API超过了这个限制, 请再每一个bulk请求里,减少你的文档数量。如果你单个的文档都已经超过了 100mb, 在发送往Elasticsearch之前,使用pre-process 减少他们的体积。 比如在外部系统存储你的原始数据,然后在Elasitcisearch链向外部资源。
http.max_initial_line_length
(Static, byte value) 最大的 HTTP URL长度。 默认值是 4kb。
http.max_header_size
(Static, byte value) 最大的HTTP headers体积, 默认值是 16kb。
**http.compression **[图片上传失败...(image-9f3612-1716382156664)]
(Static, boolean) 尽量支持压缩 (with Accept-Encoding). 如果 HTTPS 开启的话, 默认值是 false. 其他情况默认值是 true。
在HTTPS 下禁止压缩,可以减少潜在的安全风险, 例如 BREACH attack. 你可以将 http.compression 设置为 true来开启http下的压缩。
http.compression_level
(Static, integer)定义了HTTP的压缩等级。 可以设置的范围是 1 (minimum compression) 到 9 (maximum compression). 默认值是 3。
**http.cors.enabled **[图片上传失败...(image-5543d7-1716382156664)]
(Static, boolean) 跨域相关的配置, 决定了其他域名的浏览器是否可以访问这个域名下的Elasticsearch。 设置成 true 可以开启 Elasticsearch CORS 请求。Elasticsearch 将会在响应的header里增加 Access-Control-Allow-Origin ,如果 Origin 发送的请求是在 http.cors.allow-origin 允许的列表中。默认值是false , Elasticsearch 会忽略 Origin 请求头, 有效的禁用 CORS 请求 因为 Elasticsearch 不会再影响header里响应 Access-Control-Allow-Origin 。
注意: 如果客户端没有在原始header里发送一个预检的请求或者没有校验服务端影响头里的Access-Control-Allow-Origin,那么就可能发生跨域的安全威胁。如果一个ElasticSearch集群未启用CORS,对于客户端来说知晓的唯一办法就是需要发送一个预检的请求,并且去检查响应header里有没有需要的信息。
**http.cors.allow-origin **[图片上传失败...(image-af9d3a-1716382156664)]
(Static, string) 配置哪些origin可以被允许跨域。如果你在值前面加了一个/字符,那么他将被当做正则表达式处理,允许你可以同时支持HTTP和HTTPS。比如/https?://localhost(:[0-9]+)?/允许你同时支持HTTP和HTTPS。默认值是没有任何origin被支持。
重要注意: (*) 这个通配符将允许所有的域名跨域支持,他将带来安全风险。
**http.cors.max-age **[图片上传失败...(image-2bd34d-1716382156664)]
(Static, integer) 浏览器将发送一个预检的OPTIONS-request 决定 CORS 的设定. max-age 定义了这个特探测的结果被缓存多久(单位是秒) 默认值是 1728000 (20 days).
**http.cors.allow-methods **[图片上传失败...(image-ce3c4a-1716382156664)]
(Static, string) 哪些method是被允许的。默认值是 OPTIONS, HEAD, GET, POST, PUT, DELETE.
**http.cors.allow-headers **[图片上传失败...(image-9832e2-1716382156664)]
(Static, string) 哪些header是被允许的。 默认值是 X-Requested-With, Content-Type, Content-Length, Authorization, Accept, User-Agent, X-Elastic-Client-Meta.
**http.cors.expose-headers **[图片上传失败...(image-703d64-1716382156664)]
(Static) 在客户端中公开响应哪些header. 默认值是 X-elastic-product.
http.detailed_errors.enabled
(Static, boolean) 配置是否在 HTTP 的响应里展示错误详情。 默认值是 true, 如果HTTP的请求参数里带有 ?error_trace将会在发生异常的时候返回错误详情,包含错误堆栈. 如果是 false的话, 请求里带有 ?error_trace 参数将会被拒绝。
http.pipelining.max_events
(Static, integer) 在HTTP的连接关闭之前,队里里的排队的事件数的最大值, 默认值是 10000个。
http.max_warning_header_count
(Static, integer) HTTP响应的最大的warning headers 数量. 默认值是 -1 代表了数量是无限制的。
http.max_warning_header_size
(Static, byte value) 响应给client端HTTP响应里最大的warning headers Size. 默认值是 -1 表示大小没有限制
http.tcp.keep_alive
(Static, boolean) 配置Socket层里的 SO_KEEPALIVE 选项, 决定了是否发送TCP keepalive 协议。 默认值是 network.tcp.keep_alive也就是开启保持连接。
http.tcp.keep_idle
(Static, integer) HTTP的Socket里的TCP_KEEPIDLE 选项, 决定了以秒为单位的空闲多长时间发送检测心跳包。 默认值是 network.tcp.keep_idle意味着使用系统默认配置。 这个值不能超过300 秒 并且仅在Linux 和macOS操作系统里有效。
http.tcp.keep_interval
(Static, integer) 配置了HTTP Socket连接里的 TCP_KEEPINTVL配置项, 决定了发送心跳包的间隔时间。 默认值是 network.tcp.keep_interval, 采用系统默认配置。 这个值不能超过300 秒 并且仅在Linux 和macOS操作系统里有效。(他和keep_idle的区别是,keep_idle更关注空闲时间,而keep_interval则是固定的间隔,自己的理解,非官方文档)
http.tcp.keep_count
(Static, integer) 配置了HTTP sockets里的 TCP_KEEPCNT 配置项, 决定了在一个TCP的连接里,未响应的探测包的数量,超过这数量包将会被丢弃。默认值是 network.tcp.keep_count, 意味着使用系统默认配置。 仅在Linux 和macOS操作系统里有效。
http.tcp.no_delay
(Static, boolean) 配置了HTTP sockets里的 TCP_NODELAY 配置项, 决定了 TCP no delay 是否被允许,默认值是 true。
http.tcp.reuse_address
(Static, boolean) 配置了HTTP sockets里的 SO_REUSEADDR 配置项, 决定了地址是否能被重用 Windows默认值是false,其他操作系统是true
http.tcp.send_buffer_size
(Static, byte value) TCP发送 buffer缓冲区大小。 默认值是 network.tcp.send_buffer_size.
http.tcp.receive_buffer_size
(Static, byte value) TCP 接受 buffer 缓冲区大小 。 默认值是 network.tcp.receive_buffer_size.
http.client_stats.enabled
(Dynamic, boolean) 开启或是关闭手机http client端的状态信息。默认值是 true。
http.client_stats.closed_channels.max_count
(Static, integer)当 http.client_stats.enabled 设置为 true的时候,设置了 Elasticsearch 最大的统计的已关闭的通道的数量。 默认值是 10000.(Elasticsearch会跟踪和报告最多10000个已关闭的HTTP通道的统计信息。如果通道数量超过这个值,那么最早的统计信息可能会被丢弃,以保持总数不超过设定的最大值。编者注)
http.client_stats.closed_channels.max_age
(Static, time value) 当 http.client_stats.enabled 设置为 true时, 设置了 Elasticsearch 统计报告通道关闭的最长时间. 默认值是5m.(超过5分钟的,将不再在统计报告里,编者注)
高级transport接口配置
使用下面这些高级配置,来配置独立于HTTP接口的transport相关配置。使用network 配置可以在HTTP和transport两个接口下都生效。
transport.host
(Static, string) 设置transport 通信的节点网络地址。 节点将绑定这个网络地址,并且作为transport的公开地址。 可以接受一个ip地址、特殊值、hostname主机地址。只有当和HTTP协议地址不一样的时候才配置这个选项,默认值是 network.host 提供的地址。
transport.bind_host
(Static, string) 主机transport接口应该绑定的主机地址,用于监听进来的连接。能够接受一个ip列表、多个hostname值或者特殊值。 默认值是 transport.host 或者 network.bind_host设置的。 这个配置和transport的区别是他是一个list,可以绑定多个地址,并且可以和发布的地址不一样的时候。同时如果和HTTP的配置一样的话,也没有必要单独设置。
transport.publish_host
(Static, string) 用于其他节点连接这台节点的时候的公开连接地址。能接受一个ip、主机名、或者是特殊值。默认值是 transport.host 或者 network.publish_host。 当你的发布地址和绑定地址不一样的时候,你需要配置他,同时如果你的transport配置和HTTP的配置一样,可以不用配置直接使用HTTP的协议配置。
transport.publish_port
(Static, integer) 公开地址的端口号。当发布地址和 transport.port要求不一样的时候,可以配置这个值。 默认值是由 transport.port配置的。
transport.connect_timeout
(Static, time value) 初始化一个新的连接的时候,连接超时时间,默认值是 30s。
transport.compress
(Static, string) 可以设置成true, indexing_data, false 配置transport连接节点间的压缩。 配置成 true 将会开启数据压缩。 配置成indexing_data 只有当原始索引数据在 ingest, ccr following (excluding bootstrap)或者shard恢复期间的数据压缩 (excluding transferring lucene files). 默认值是 indexing_data.
transport.compression_scheme
(Static, string)配置transport.compress压缩的scheme 。可以设置成 deflate 或者是 lz4。如果设置了 lz4 但是连接的远程节点还不支持 lz4, 通信将以非压缩的格式传输。 默认值是 lz4。
transport.tcp.keep_alive
(Static, boolean) 配置socket连接的 SO_KEEPALIVE 配置项, 决定了是否发送TCP keepalive 探测包。 默认值是读取的 network.tcp.keep_alive配置项
transport.tcp.keep_idle
(Static, integer) 配置socket连接的 TCP_KEEPIDLE 配置项, 配置了空闲连接的时间,默认值是network.tcp.keep_idle 有值的话用这个配置,如果没有 用操作系统的默认配置。 这个值不能超过 300 秒。如果系统值超过了300, 这个值将自动降到 300. 只有在 Linux 和 macOS生效。
transport.tcp.keep_interval
(Static, integer) 配置socket连接的TCP_KEEPINTVL 配置项, 心跳包发送的间隔时间。如果 network.tcp.keep_interval 有值就用这个值作为默认值 否则用系统的默认值。 这个值不能超过 300 秒。如果系统值超过了300, 这个值将自动降到 300。只有在 Linux 和 macOS生效。
transport.tcp.keep_count
(Static, integer) 配置了socket连接里的 TCP_KEEPCNT配置项,决定了未ack的探测包的个数,超过这个之后包将会被丢弃。默认值使用 network.tcp.keep_count 配置, 否则用系统的默认值。只有在 Linux 和 macOS生效。
transport.tcp.no_delay
(Static, boolean) 配置了socket连接的TCP_NODELAY 配置项, 决定了tcp的no delay是否开启。默认值是true
transport.tcp.reuse_address
(Static, boolean) 配置了socket连接的 SO_REUSEADDR配置项,地址是否能够被复用,默认值使用network.tcp.reuse_address配置的值。
transport.tcp.send_buffer_size
(Static, byte value) 配置了tcp的发送buffer的大小,network.tcp.send_buffer_size默认值是这个。
transport.tcp.receive_buffer_size
(Static, byte value) 配置了tcp的接受的buffer的大小,默认值是 network.tcp.receive_buffer_size.
transport.ping_schedule
(Static, time value) 配置了应用层的 pings 值时间,用于探测应用层的所有的节点是否存活。默认值是-1 不发送应用层的ping。 建议使用 TCP keepalives (see transport.tcp.keep_alive) 来代替应用层的ping。
transport文档
Elasticsearch 通过transport 文档可以让你在不同的接口上(HTTP以及transport接口上)。下面这是一个示例:
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
默认配置文件是特殊的。如果其他配置文件没有设置特定的配置项,默认配置项将作为回退选项配置默认值,决定了该节点如何与集群中的其他节点连接。其他配置文件可以具有任何名称,并可用于为传入连接设置特定的端点。
如下参数可以在每个传输配置文件中进行配置,如上例所示:
- port(端口):绑定的端口号。
- bind_host(绑定主机):绑定的主机地址。
- publish_host(公布主机):连接用的公开地址。
配置文件同样支持在“传输设置”部分指定的所有其他传输参数,并将这些参数作为默认值使用。例如,transport.profiles.client.tcp.reuse_address
可以被显式配置,如未明确配置则默认采用 transport.tcp.reuse_address
的值。
长时间存活的空闲连接
两个节点间的transport连接是有一定数量的 长时间存活的TCP 链接组成的,有些连接可能已经空闲了相当长的一段时间了。 尽管如此Elasticsearch需要这些连接保持open, 否则的话可能会导致集群的一些操作被扰乱,例如防火墙等影响和干预了连接的正常。保持Elasticsaerch集群节点间的空闲连接是比较重要的, 因此保持 *.tcp.keep_alive enabled 并确保 keepalive interval 比timeout要短,否则可能会导致空闲连接关闭。或者设置 transport.ping_schedule如果keeplive不能被配置的话。设备在达到一定闲置时间后断开连接,这是导致Elasticsearch集群出现问题的常见原因,因此不应使用这类设备。
请求压缩
transport.compress 默认配置是 indexing_data只会在节点间的原始index数据传输才会压缩数据。 这个配置项决定了在 ingest, ccr, and shard recovery期间会启用压缩。这个默认配置通过增加一点点的cpu开销,减少了集群的本地通信的时候的网络传输
transport.compress配置项配置了集群本地的网络通信,同时是远端集群的默认配置。如果你希望远程集群通信和本地集群的通信压缩配置项不同,使用 cluster.remote.${cluster_alias}.transport.compresssetting这个配置项来配置。
响应压缩
响应的压缩是不能被配置的。 Elasticsearch 在进来的请求如果是压缩过的情况下会启用压缩响应,尽管自己的配置项是不压缩。同时如果进来的请求是非压缩的,他的响应也不会被压缩,尽快自己id配置项是压缩。 用于压缩响应的压缩方案将与远程节点用于压缩请求的压缩方案相同。
高级远程集群(API key based model)配置
注意:这个功能是beta版本并且将来可能会改变。 与官方的GA版本特性相比,这个特性是不稳定性的且没有保证的。 Beta 特性也没有 像官方 GA 版本的 SLA支持
使用下面这些高级配置配置独立于transport接口的远程集群接口 (API key based model) transport interface. 你也可以通过 network settings同时配置两个接口都生效。
remote_cluster_server.enabled
(Static, boolean) 配置了远程集群服务是否被启用。 这个配置必须被设置为 true 这样类似 remote_cluster.port 以及下面的所有配置才会生效。启用它可以使远程通过API key based model进行跨集群的请求。默认是 false.
remote_cluster.host
(Static, string) 设置了当前节点和远程集群节点通信的地址。当前节点会绑定到当前的地址并且也会用作远程集群的公开地址。能接受ip地址、主机名、特殊值。仅仅当transport地址和远程的地址不一致的时候,才启用这个配置,默认值是transport.bind_host给出的。
remote_cluster.bind_host
(Static, string) 为远程节点通信所绑定的节点地址。配置是一个列表值,接受多个ip、多个主机名或者多个特殊值。默认值是由remote_cluster.host设置的。仅仅当绑定地址和公开地址不一样的时候,或者远程地址和transport的绑定地址不一样的时候,再启用这个配置
remote_cluster.publish_host
(Static, string) 可以被其他节点访问和连接的地址。接受一个ip地址、主机地址或者是特殊值。 默认值是 remote_cluster.host给出来的。仅仅当绑定地址和公开地址不一样的时候,或者远程地址和transport的绑定地址不一样的时候,再启用这个配置
remote_cluster.publish_port
(Static, integer) 远程服务器连接的公开端口号。仅仅当远程的公开端口和 remote_cluster.port的值不一样的时候再配置。默认值是通过remote_cluster.port设置的。
remote_cluster.tcp.keep_alive
(Static, boolean) Configures the SO_KEEPALIVE option for remote cluster sockets, which determines whether they send TCP keepalive probes. Defaults to transport.tcp.keep_alive.
remote_cluster.tcp.keep_idle
(Static, integer) 配置远程连接的socket的TCP_KEEPIDLE 配置项, 决定了发送探针的空闲时间。 默认值是由 transport.tcp.keep_idle 设置的,如果这个值没有就用系统的默认地址。这个值不能超过300秒。如果这个系统值超过了300秒,将会被降到300秒。只在Linux和mac操作系统下有效。
remote_cluster.tcp.keep_interval
(Static, integer) 配置了远程连接的sock的 TCP_KEEPINTVL 配置项。决定了发送保活的探测包的时间间隔。 默认值是 transport.tcp.keep_interval配置的, 这个值没有就用系统值。 这个值不能超过300秒。如果这个系统值超过了300秒,将会被降到300秒。只在Linux和mac操作系统下有效。
remote_cluster.tcp.keep_count
(Static, integer) 配置了socket连接的 TCP_KEEPCNT 选项值,决定了在未连接前未ack的包的个数,超过之后的包会被丢弃。默认值是 transport.tcp.keep_count 或者系统值。仅仅在Linux系统和mac操作系统上有效。
remote_cluster.tcp.no_delay
(Static, boolean) 配置了socket连接的 TCP_NODELAY 配置项,决定了 TCP no delay 是否被启用。默认值是 transport.tcp.no_delay配置的。
remote_cluster.tcp.reuse_address
(Static, boolean) 配置了网络socket里的 SO_REUSEADDR 配置项, 决定了地址是否可以被重用。默认值是由transport.tcp.reuse_address配置的。
remote_cluster.tcp.send_buffer_size
(Static, byte value) TCP的发送buffer大小,默认值是由transport.tcp.send_buffer_size配置的
remote_cluster.tcp.receive_buffer_size
(Static, byte value) TCP 接受 buffer大小。默认值是由 transport.tcp.receive_buffer_size配置的。
请求跟踪
你可以分开独立的跟踪transport层和HTTP层的请求。
注意:跟踪可能会产生大量的日志,从而使你的集群不稳定。不要在比较忙的或者重要的集群上启用跟踪。
REST request tracer
HTTP 层 可以跟踪进来的请求和当时的请求响应。 通过设置org.elasticsearch.http.HttpTracer 成TRACE来开启HTTP层的跟踪功能。
PUT _cluster/settings
{
"persistent" : {
"logger.org.elasticsearch.http.HttpTracer" : "TRACE"
}
}
你也可以通过正则表达式来控制哪些URL可以被跟踪,默认值是所有的请求,例如:
PUT _cluster/settings
{
"persistent" : {
"http.tracer.include" : "*",
"http.tracer.exclude" : ""
}
}
默认情况下日志只记录了请求和响应的摘要信息。如果要同时记录请求和响应的body信息, 设置es.insecure_network_trace_enabled 未 true, 同时将org.elasticsearch.http.HttpTracer and org.elasticsearch.http.HttpBodyTracer l设置未 TRACE。
PUT _cluster/settings
{
"persistent" : {
"logger.org.elasticsearch.http.HttpTracer" : "TRACE",
"logger.org.elasticsearch.http.HttpBodyTracer" : "TRACE"
}
}
每一个消息体都是被压缩且编码的,被切割成 chunks防止被截断。
[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)
每一个 chunk 都带有一个内部的 request ID ([276] 上面的例子里) 你可以将 chunks 和摘要行信息关联起来。 通过 base64-decode 和gzip解压你可以还原chunks信息. 例如在Unix-like 系统里可以输入如下命令:
cat httptrace.log | sed -e 's/.*://' | base64 --decode | gzip --decompress
注意:注意因为http的请求和响应body里可能包含例如信用卡等敏感信息,因此默认状态下他是被关闭的。你需要在每个节点上配置es.insecure_network_trace_enabled 为true来打开它。这个特性应该在测试环境下不涉及任何敏感信息的时候启用。如果在包含敏感系统的服务器上启用,一定要确保日志有访问授权,防止敏感信息泄露。
Transport 层的跟踪
transport 层的跟踪配置决定了是否开启请求和响应的跟踪信息日志。通过配置 org.elasticsearch.transport.TransportService.tracer 为TRACE来启用这个配置。
PUT _cluster/settings
{
"persistent" : {
"logger.org.elasticsearch.transport.TransportService.tracer" : "TRACE"
}
}
你也可以通过正则表达式来决定哪些URL可以开启,例如:
PUT _cluster/settings
{
"persistent" : {
"transport.tracer.include" : "*",
"transport.tracer.exclude" : "internal:coordination/fault_detection/*"
}
}
网络线程模型
以下这个章节描述了 Elasticsearch下的网络子系统的线程模型。 正常情况下一般用户用不上,但是在高级用户在诊断集群的网络问题的时候有用。
Elasticsearch 在transport层通过多个TCP channels通信。 Elasticsearch在HTTP层也是通过多个TCP channels通信。 在线程模型里这些channel都是被 transport_worker管理的。这个线程在channel被启用的时候进行管理,并且管理着这些channel的生命周期。
每个运输工作线程(transport_worker)负责在其拥有的通道上发送和接收数据。此外,每个HTTP和transport的socket都被分配给运输工作线程之一。该工作线程负责接受到其拥有的socket4上的新传入连接。
如果Elasticsearch中的某个线程希望通过特定通道发送数据,它会将数据传递给该通道所属的运输工作线程(transport_worker),由该线程负责实际的数据传输。
通常 transport_worker线程不会完全处理他接受到的信息。他会做一些简单的前置处理,然后分发给其他不同的线程池处理。比如, bulk 信息会分发给 write 线程池, 搜索信息会 分发给search 线程池, 分析请求和其他管理任务 会分发给 management 线程池。 在一些场景下,Elasticsearch要求信息的处理快速,这个时候 transport_worker 将会接管处理这些信息而不是分发给其他线程池了。
默认情况下transport_worker 数量跟处理器的核数一直, 与之对比的是可能会有成百上千的TCP channels 。如果一个数据到达了channel但是 transport_worker 却在忙的话,这个数据就不会被处理直到这worker空闲下来,不管你当前的data是什么任务。类似的如果 transport_worker 没有空闲,向外发送的数据也会一直等待。 这意味着 transport_worker 必须频繁的空闲,一个空闲的 transport_worker在堆栈dump里看起来如下:
"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(java.base@17.0.2/Native Method)
at sun.nio.ch.EPollSelectorImpl.doSelect(java.base@17.0.2/EPollSelectorImpl.java:118)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@17.0.2/SelectorImpl.java:129)
- locked <0x00000000c443c518> (a sun.nio.ch.Util$2)
- locked <0x00000000c38f7700> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(java.base@17.0.2/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(java.base@17.0.2/Thread.java:833)
一个空闲的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
java.base@17.0.2/sun.nio.ch.EPoll.wait(Native Method)
java.base@17.0.2/sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:118)
java.base@17.0.2/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
java.base@17.0.2/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)
java.base@17.0.2/java.lang.Thread.run(Thread.java:833)
需要注意的是 transport_worker 应该始终设置为 RUNNABLE状态, 即使是他们在等待IO的时候,因为他们是在native的 EPoll#wait 方法上被阻塞住的。 idle= 时间报告了这个线程在IO等待上花费的时间,cpu= 时间报告的是这线程在处理收到的信息上花费的时间。
- 如果一个transport_worker无法被频繁的释放的话,可能会导致工作的积压,这会导致这个线程关联的channel上的消息处理延迟,但是很难预测哪些work会被延迟:
- 一个worker可能会负责很多很多的channel,如果其中一个channel出现了拥堵,其他所有的channel的信息都会发生延迟
- worker和channel之间的映射关系是随机分配的,分配完之后他是固定的。在channel open的时候,通过RR算法随机为这个channel分配一个worker线程。每一个worker会负责很多个不同类型的channel。
- 在两个节点间可能会有很多个channel。针对每一个请求,ElasticSearch会为每个请求用RR算法随机分配一个channel。在一些channel上延迟的时候,其他的channel可能会非常的通畅。
如果被阻塞了很长时间,可能会导致健康检查失败 fail its health checks 从而导致节点被移出集群。一般情况你可以使用 Nodes hot threads API来找到比较忙的线程。但是当 transport_worker 太忙的时候,这个诊断请求可能也处理不了。这个时候使用JVM的 jstack 命令会更加行之有效。
你也可以通过在日志里寻找 org.elasticsearch.transport.InboundHandler and org.elasticsearch.transport.OutboundHandler来发现问题。 来自InboundHandler的关于长时间处理的警告特别能说明线程行为不正确的问题,而OutboundHandler报告的传输时间包括了等待网络拥堵的时间,在此期间,transport_worker线程可以自由地进行其他工作。