排查不稳定集群

编辑

通常情况下,节点只有在故意关闭时才会离开集群。如果节点意外离开集群,则必须解决其根本原因。节点意外离开的集群是不稳定的,可能会导致若干问题,例如:

  • 集群健康状态可能为黄色或红色。
  • 一些分片将处于初始化状态,而其他分片可能会失败。
  • 搜索、索引和监控操作可能会失败,并在日志中报告异常。
  • .security 索引可能不可用,从而阻止对集群的访问。
  • 由于频繁的集群状态更新,主节点可能显得繁忙。

要排查此状态下的集群,首先确保集群具有 稳定的主节点。接下来,在所有其他问题之前,重点关注意外离开集群的节点。在集群拥有稳定的主节点和稳定的节点成员资格之前,无法解决其他问题。

诊断和统计信息在不稳定的集群中通常无用。这些工具只能提供集群在单个时间点的状态视图。相反,请查看集群日志以了解一段时间内的行为模式。尤其要关注来自已选举主节点的日志。当节点离开集群时,已选举主节点的日志中将包含类似以下消息(已添加换行符以使其更易于阅读):

[2022-03-21T11:02:35,513][INFO ][o.e.c.c.NodeLeftExecutor] [instance-0000000000]
    node-left: [{instance-0000000004}{bfcMDTiDRkietFb9v_di7w}{aNlyORLASam1ammv2DzYXA}{172.27.47.21}{172.27.47.21:19054}{m}]
    with reason [disconnected]

此消息表明,已选举主节点(instance-0000000000)上的 NodeLeftExecutor 处理了一个 node-left 任务,标识了已移除的节点及其移除原因。当节点再次加入集群时,已选举主节点的日志中将包含类似以下消息(已添加换行符以使其更易于阅读):

[2022-03-21T11:02:59,892][INFO ][o.e.c.c.NodeJoinExecutor] [instance-0000000000]
    node-join: [{instance-0000000004}{bfcMDTiDRkietFb9v_di7w}{UNw_RuazQCSBskWZV8ID_w}{172.27.47.21}{172.27.47.21:19054}{m}]
    with reason [joining after restart, removed [24s] ago with reason [disconnected]]

此消息表明,已选举主节点(instance-0000000000)上的 NodeJoinExecutor 处理了一个 node-join 任务,标识了已添加到集群的节点及其任务原因。

其他节点也可能会记录类似的消息,但报告的详细信息较少。

[2020-01-29T11:02:36,985][INFO ][o.e.c.s.ClusterApplierService]
    [instance-0000000001] removed {
        {instance-0000000004}{bfcMDTiDRkietFb9v_di7w}{aNlyORLASam1ammv2DzYXA}{172.27.47.21}{172.27.47.21:19054}{m}
        {tiebreaker-0000000003}{UNw_RuazQCSBskWZV8ID_w}{bltyVOQ-RNu20OQfTHSLtA}{172.27.161.154}{172.27.161.154:19251}{mv}
    }, term: 14, version: 1653415, reason: Publication{term=14, version=1653415}

这些消息对于故障排除并非特别有用,因此请关注来自 NodeLeftExecutorNodeJoinExecutor 的消息,这些消息仅在已选举的主节点上发出,并且包含更多详细信息。如果看不到来自 NodeLeftExecutorNodeJoinExecutor 的消息,请检查:

  • 您是否查看了已选举主节点的日志。
  • 日志是否涵盖了正确的时段。
  • 日志记录是否已启用 INFO 级别。

每当节点开始或停止跟踪已选举的主节点时,节点也会记录包含 master node changed 的消息。您可以使用这些消息来确定每个节点对一段时间内主节点状态的看法。

如果节点重新启动,它将离开集群,然后再次加入集群。重新加入时, NodeJoinExecutor 将记录它处理了一个 node-join 任务,指示该节点 正在重新启动后加入。如果节点意外重新启动,请查看节点的日志以了解其关闭的原因。

受影响节点上的 健康 API 也将提供有关此情况的一些有用信息。

如果节点未重新启动,则应更仔细地查看其离开的原因。每个原因都有不同的故障排除步骤,如下所述。共有三个可能的原因:

  • disconnected:主节点与已移除节点之间的连接已关闭。
  • lagging:主节点发布了集群状态更新,但已移除节点未在允许的超时时间内应用它。默认情况下,此超时时间为 2 分钟。有关控制此机制的设置的信息,请参阅 发现和集群形成设置
  • followers check retry count exceeded:主节点向已移除节点发送了许多连续的健康检查。这些检查被拒绝或超时。默认情况下,每次健康检查超时时间为 10 秒,Elasticsearch 在连续三次健康检查失败后移除已移除的节点。有关控制此机制的设置的信息,请参阅 发现和集群形成设置

诊断 disconnected 节点

编辑

节点通常在关闭时以 disconnected 原因离开集群,但如果它们在未重新启动的情况下重新加入集群,则存在其他问题。

Elasticsearch 旨在运行在相当可靠的网络上。它在节点之间打开多个 TCP 连接,并期望这些连接保持打开状态 永久。如果连接关闭,Elasticsearch 将尝试重新连接,因此偶尔的故障可能会使某些进行中的操作失败,但否则对集群的影响应该有限。相反,反复断开的连接将严重影响其操作。

从已选举的主节点到集群中每个其他节点的连接尤其重要。已选举的主节点绝不会自发地关闭其到其他节点的出站连接。同样,一旦入站连接完全建立,节点就不会自发地关闭它,除非节点正在关闭。

如果您看到节点意外以 disconnected 原因离开集群,则可能并非 Elasticsearch 导致连接关闭。常见原因是防火墙配置错误,具有不正确的超时或其他与 Elasticsearch 不兼容 的策略。也可能是由于一般的连接问题造成的,例如由于硬件故障或网络拥塞导致的丢包。如果您是高级用户,请配置以下记录器以获取有关网络异常的更多详细信息:

logger.org.elasticsearch.transport.TcpTransport: DEBUG
logger.org.elasticsearch.xpack.core.security.transport.netty4.SecurityNetty4Transport: DEBUG

如果这些日志没有显示足够的信息来诊断问题,请同时从不稳定连接两端节点获取数据包捕获,并将其与这些节点的 Elasticsearch 日志一起分析,以确定网络上的其他设备是否正在中断节点之间的流量。

诊断 lagging 节点

编辑

Elasticsearch 需要每个节点都能够合理快速地处理集群状态更新。如果节点处理集群状态更新花费的时间过长,则可能会对集群造成损害。主节点将使用 lagging 原因移除这些节点。有关控制此机制的设置的信息,请参阅 发现和集群形成设置

滞后通常是由已移除节点上的性能问题引起的。但是,节点也可能由于严重的网络延迟而滞后。要排除网络延迟,请确保 net.ipv4.tcp_retries2 已正确配置。包含 warn threshold 的日志消息可能会提供有关根本原因的更多信息。

如果您是高级用户,可以通过配置以下记录器来获取有关节点在移除时正在执行的操作的更多详细信息:

logger.org.elasticsearch.cluster.coordination.LagDetector: DEBUG

启用此记录器后,Elasticsearch 将尝试在故障节点上运行 节点热线程 API,并在已选举主节点的日志中报告结果。结果经过压缩、编码并分成块,以避免截断。

[DEBUG][o.e.c.c.LagDetector      ] [master] hot threads from node [{node}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] lagging at version [183619] despite commit of cluster state version [183620] [part 1]: H4sIAAAAAAAA/x...
[DEBUG][o.e.c.c.LagDetector      ] [master] hot threads from node [{node}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] lagging at version [183619] despite commit of cluster state version [183620] [part 2]: p7x3w1hmOQVtuV...
[DEBUG][o.e.c.c.LagDetector      ] [master] hot threads from node [{node}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] lagging at version [183619] despite commit of cluster state version [183620] [part 3]: v7uTboMGDbyOy+...
[DEBUG][o.e.c.c.LagDetector      ] [master] hot threads from node [{node}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] lagging at version [183619] despite commit of cluster state version [183620] [part 4]: 4tse0RnPnLeDNN...
[DEBUG][o.e.c.c.LagDetector      ] [master] hot threads from node [{node}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] lagging at version [183619] despite commit of cluster state version [183620] (gzip compressed, base64-encoded, and split into 4 parts on preceding log lines)

要重建输出,请使用 gzip 对数据进行 base64 解码并解压缩。例如,在类 Unix 系统上:

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

诊断 follower check retry count exceeded 节点

编辑

节点有时在关闭时会以 follower check retry count exceeded 原因离开集群,但如果它们在未重新启动的情况下重新加入集群,则存在其他问题。

Elasticsearch 需要每个节点都能成功且合理快速地响应网络消息。如果节点拒绝请求或根本不响应,则可能会对集群造成损害。如果连续失败的检查次数足够多,则主节点将以 follower check retry count exceeded 原因移除节点,并在 node-left 消息中指示连续失败的检查次数以及其中超时次数。有关控制此机制的设置的信息,请参阅 发现和集群形成设置

超时和失败可能是由于网络延迟或受影响节点上的性能问题造成的。确保 net.ipv4.tcp_retries2 已正确配置,以消除网络延迟作为此类不稳定性的可能原因。包含 warn threshold 的日志消息可能会提供有关不稳定性原因的更多线索。

如果最后一次检查因异常而失败,则会报告该异常,并且通常表明需要解决的问题。如果任何检查超时,则按如下方式缩小问题范围。

  • Elasticsearch 默认会发出 GC 日志,其中记录了 GC 暂停,`JvmMonitorService` 通常也会在主节点日志中记录。使用这些日志确认节点是否经历了高堆使用率和长时间的 GC 暂停。如果是这样,高堆使用率的故障排除指南 提供了一些进一步调查的建议,但通常需要在高堆使用率期间捕获堆转储和垃圾收集器日志 以完全理解问题。
  • 虚拟机暂停也会影响同一主机上的其他进程。虚拟机暂停通常还会导致系统时钟中断,Elasticsearch 会在其日志中报告此中断。如果您看到其他进程同时暂停的证据,或出现意外的时钟中断,请调查运行 Elasticsearch 的基础设施。
  • 数据包捕获将揭示系统级和网络级的故障,尤其是在您同时捕获选举出的主节点和故障节点的网络流量并将其与这些节点的 Elasticsearch 日志一起分析时。用于 follower 检查的连接不用于任何其他流量,因此即使使用 TLS,也可以仅从流模式中轻松识别它:几乎每秒都会有几百字节的数据在两个方向上传输,首先是主节点的请求,然后是 follower 的响应。您应该能够观察到任何重传、数据包丢失或此类连接上的其他延迟。
  • 可以通过在相关日志消息之前的几秒钟内获取主 Elasticsearch 进程的堆栈转储(例如,使用jstack)或概要分析跟踪(例如,使用 Java Flight Recorder)来识别特定线程长时间等待可用。

    节点热线程 API 有时会产生有用的信息,但请记住,此 API 也需要跨集群中所有节点的多个transport_workergeneric线程。API 可能会受到您尝试诊断的同一问题的干扰。jstack 更可靠,因为它不需要任何 JVM 线程。

    参与发现和集群成员的线程主要是transport_workercluster_coordination线程,这些线程永远不应该长时间等待。Elasticsearch 日志中也可能存在长时间等待线程的证据,尤其是在org.elasticsearch.transport.InboundHandler的警告日志中。有关更多信息,请参阅网络线程模型

默认情况下,follower 检查将在 30 秒后超时,因此如果节点离开不可预测,则每 15 秒捕获一次堆栈转储,以确保至少在正确的时间捕获了一个堆栈转储。

诊断ShardLockObtainFailedException错误

编辑

如果节点离开并重新加入集群,则 Elasticsearch 通常会关闭并重新初始化其分片。如果分片没有快速关闭,则 Elasticsearch 可能会由于ShardLockObtainFailedException而无法重新初始化它们。

要收集有关分片关闭缓慢原因的更多信息,请配置以下日志记录器

logger.org.elasticsearch.env.NodeEnvironment: DEBUG

启用此日志记录器后,Elasticsearch 将尝试在遇到ShardLockObtainFailedException时运行节点热线程 API。结果会被压缩、编码并拆分成块以避免截断。

[DEBUG][o.e.e.NodeEnvironment    ] [master] hot threads while failing to obtain shard lock for [index][0] [part 1]: H4sIAAAAAAAA/x...
[DEBUG][o.e.e.NodeEnvironment    ] [master] hot threads while failing to obtain shard lock for [index][0] [part 2]: p7x3w1hmOQVtuV...
[DEBUG][o.e.e.NodeEnvironment    ] [master] hot threads while failing to obtain shard lock for [index][0] [part 3]: v7uTboMGDbyOy+...
[DEBUG][o.e.e.NodeEnvironment    ] [master] hot threads while failing to obtain shard lock for [index][0] [part 4]: 4tse0RnPnLeDNN...
[DEBUG][o.e.e.NodeEnvironment    ] [master] hot threads while failing to obtain shard lock for [index][0] (gzip compressed, base64-encoded, and split into 4 parts on preceding log lines)

要重建输出,请使用 gzip 对数据进行 base64 解码并解压缩。例如,在类 Unix 系统上:

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

诊断其他网络断开连接

编辑

Elasticsearch 旨在运行在相当可靠的网络上。它在节点之间打开多个 TCP 连接,并期望这些连接保持打开状态 永久。如果连接关闭,Elasticsearch 将尝试重新连接,因此偶尔的故障可能会使某些进行中的操作失败,但否则对集群的影响应该有限。相反,反复断开的连接将严重影响其操作。

只有当其他节点离开集群时,Elasticsearch 节点才会主动关闭到另一个节点的出站连接。有关识别和解决此问题的更多信息,请参阅解决不稳定的集群问题。如果出站连接由于其他原因关闭,节点将记录如下消息

[INFO ][o.e.t.ClusterConnectionManager] [node-1] transport connection to [{node-2}{g3cCUaMDQJmQ2ZLtjr-3dg}{10.0.0.1:9300}] closed by remote

同样,一旦入站连接完全建立,节点就不会自发地关闭它,除非节点正在关闭。

因此,如果您看到节点报告与另一个节点的连接意外关闭,则很可能是 Elasticsearch 之外的某些原因导致连接关闭。常见原因是防火墙配置错误,具有不正确的超时或其他与Elasticsearch 不兼容 的策略。也可能是由一般的连接问题引起的,例如由于硬件故障或网络拥塞导致的数据包丢失。如果您是高级用户,请配置以下日志记录器以获取有关网络异常的更详细信息

logger.org.elasticsearch.transport.TcpTransport: DEBUG
logger.org.elasticsearch.xpack.core.security.transport.netty4.SecurityNetty4Transport: DEBUG

如果这些日志没有显示足够的信息来诊断问题,请同时从不稳定连接两端节点获取数据包捕获,并将其与这些节点的 Elasticsearch 日志一起分析,以确定网络上的其他设备是否正在中断节点之间的流量。