集群故障检测编辑

选定的主节点会定期检查集群中的每个节点,以确保它们仍然连接且处于健康状态。集群中的每个节点也会定期检查选定主节点的健康状况。这些检查分别被称为跟随者检查领导者检查

Elasticsearch 允许这些检查偶尔失败或超时,而不会采取任何措施。只有在连续多次检查失败后,它才会认为节点有故障。您可以使用cluster.fault_detection.* 设置来控制故障检测行为。

但是,如果选定的主节点检测到某个节点已断开连接,则这种情况将被视为立即故障。主节点会绕过超时和重试设置值,并尝试将该节点从集群中移除。同样,如果某个节点检测到选定的主节点已断开连接,则这种情况将被视为立即故障。该节点会绕过超时和重试设置,并重新启动其发现阶段,以尝试查找或选举新的主节点。

此外,每个节点都会定期验证其数据路径是否健康,方法是向磁盘写入一个小文件,然后将其删除。如果某个节点发现其数据路径不健康,则它将从集群中移除,直到数据路径恢复为止。您可以使用monitor.fs.health 设置来控制此行为。

如果节点无法在合理的时间内应用更新的集群状态,选定的主节点也会将节点从集群中移除。超时默认从集群状态更新开始算起为 2 分钟。有关更详细的说明,请参阅发布集群状态

排查不稳定集群编辑

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

  • 集群健康状况可能为黄色或红色。
  • 一些分片将处于初始化状态,而其他分片可能正在失败。
  • 搜索、索引和监控操作可能会失败,并在日志中报告异常。
  • .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

在极端情况下,您可能需要使用 tcpdump 进行数据包捕获,以确定节点之间的消息是否被丢弃或被网络上的其他设备拒绝。

诊断 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 的日志消息可能会提供有关不稳定性原因的更多线索。

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

  • GC 暂停记录在 Elasticsearch 默认情况下发出的 GC 日志中,通常也记录在主节点日志中的 JvmMonitorService 中。使用这些日志确认节点是否正在经历高堆使用率和长时间的 GC 暂停。如果是这样,高堆使用率故障排除指南 提供了一些进一步调查的建议,但通常您需要在高堆使用率期间捕获堆转储才能完全了解问题。
  • VM 暂停也会影响同一主机上的其他进程。VM 暂停通常会导致系统时钟发生不连续,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 故障edit

如果节点离开并重新加入集群,则 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