排查不稳定的集群

编辑

通常,节点只有在被有意关闭时才会离开集群。如果节点意外离开集群,则必须找出原因。节点意外离开的集群是不稳定的,可能会引发多个问题。例如:

  • 集群健康状态可能为黄色或红色。
  • 一些分片会处于初始化状态,而其他分片可能会失败。
  • 搜索、索引和监控操作可能会失败,并在日志中报告异常。
  • .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 任务,表明该节点正在 joining after restart。如果节点意外重新启动,请查看该节点的日志,了解它为何关闭。

受影响节点上的健康 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)

要重建输出,请使用 base64 解码数据,然后使用 gzip 解压缩。例如,在类 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 的日志消息可能会提供有关不稳定原因的进一步线索。

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

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

    节点热线程 API 有时会产生有用的信息,但请记住,此 API 还需要集群中所有节点上的许多 transport_workergeneric 线程。此 API 可能会受到您试图诊断的问题的影响。jstack 更可靠,因为它不需要任何 JVM 线程。

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

默认情况下,跟随者检查将在 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)

要重建输出,请使用 base64 解码数据,然后使用 gzip 解压缩。例如,在类 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 日志一起分析,以确定节点之间的流量是否因网络上的其他设备而中断。