常见的Elasticsearch日志分析,助力高效故障排除

利用Elasticsearch日志分析,快速诊断集群健康、磁盘、内存、分片恢复及慢查询等问题。

常见Elasticsearch日志分析:高效故障排查指南

Elasticsearch日志分析通常是解释红色集群、索引请求失败或搜索缓慢投诉的最快方式。当集群有多个节点时,日志会告诉你哪个节点首先出现故障,哪个组件做出了反应,以及问题是磁盘、内存、发现、安全还是分片恢复。

本指南将教你如何阅读Elasticsearch日志而不被噪音干扰。你将了解日志通常存放的位置、哪些字段重要、常见故障信息的含义,以及何时从主服务器日志切换到慢日志或分配API。

理解Elasticsearch日志结构

Elasticsearch使用Log4j 2进行日志记录。软件包安装通常将日志文件写入/var/log/elasticsearch/。容器化部署通常将日志发送到标准输出,由容器运行时或日志代理收集。根据你的版本和log4j2.properties配置,你可能会看到纯文本日志、JSON日志或两者兼有。

安装类型 典型日志路径
RPM/DEB Linux包 /var/log/elasticsearch/
Docker 容器标准输出
ZIP或tarball $ES_HOME/logs/

常见文件包括主服务器日志、弃用日志、慢日志,如果启用了安全审计,有时还包括审计日志。

JSON日志条目通常包含以下字段:

  • @timestamp:事件发生的时间。
  • level:严重级别,如INFOWARNERROR
  • component:记录消息的Elasticsearch类或子系统。
  • cluster.uuid:集群标识符。
  • node.name:生成日志行的节点。
  • message:人类可读的事件文本。
{
  "@timestamp": "2024-01-15T10:30:00.123Z",
  "level": "WARN",
  "component": "o.e.c.r.a.DiskThresholdMonitor",
  "cluster.uuid": "abcde12345",
  "node.name": "es-node-01",
  "message": "high disk watermark [90%] exceeded on [es-node-01]"
}

按日志级别优先处理消息

首先过滤WARNERROR级别,然后围绕相同的时间戳扩大搜索范围。第一个ERROR之前的几行通常比最终的堆栈跟踪更能解释原因。

级别 通常含义 首要操作
ERROR 请求、分片、节点或子系统失败。 立即调查。
WARN Elasticsearch检测到风险状况。 在变成故障前检查。
INFO 正常的生命周期活动。 用于提供警告和错误的上下文。
DEBUG / TRACE 深层诊断细节。 仅在需要时短暂启用。

避免在生产节点上使用DEBUGTRACE级别。详细日志会快速消耗磁盘并增加不必要的开销。

排查常见日志模式

Elasticsearch日志很少会用一句简洁的话告诉你“根本原因是X”。寻找一种模式:第一个警告、组件名称、受影响的索引或分片,以及随后重复的消息。

启动检查失败

Elasticsearch在类似生产的网络配置中执行启动检查。这些检查会捕获不安全的主机设置,例如文件描述符限制过低、虚拟内存限制过低或内存锁定问题。如果必需的检查失败,节点将拒绝启动。

搜索bootstrap checks failed

[2024-01-15T10:00:00,123][ERROR][o.e.b.BootstrapCheck$Bootstrap] [es-node-01] bootstrap checks failed
[2024-01-15T10:00:00,124][ERROR][o.e.b.BootstrapCheck$Bootstrap] [es-node-01] max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

修复主机设置,重启节点,并确认启动日志到达节点加入集群的点。

网络绑定和发现失败

如果节点启动但未加入集群,搜索BindExceptionmaster not discovereddiscoverycluster.initial_master_nodesBindException通常指向地址或端口冲突。发现消息通常指向错误的种子主机、被阻止的传输端口9300、不匹配的集群名称或阻止节点相互信任的安全设置。

断路器异常

断路器会阻止可能使用过多内存的请求。失败的请求会返回错误,但节点应保持存活。

搜索CircuitBreakingExceptionData too large

[2024-01-15T11:45:20,500][WARN][o.e.c.c.CircuitBreakerService] [es-node-02]
CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [123456789b], which is larger than the limit of [500mb]

常见原因包括大型聚合、返回过多字段的请求、大量批量索引或为文本字段加载的fielddata。识别请求模式,然后减少请求大小、修复映射或增加容量。

垃圾回收警告

主Elasticsearch日志可以报告长时间的JVM垃圾回收暂停。搜索gcJvmGcMonitorServiceoverhead。在负载高峰期间出现少量警告可能是正常的。重复的警告伴随着搜索延迟上升通常意味着堆内存压力过大。

分片恢复和损坏

当分片分配失败或节点检测到本地分片副本损坏时,Elasticsearch会记录索引和分片编号。

搜索shard failedfailed shardfailed to recover或受影响的索引名称:

[2024-01-15T12:05:10,999][ERROR][o.e.i.e.Engine] [es-node-03] [my_index][2] fatal error in engine loop
java.io.IOException: Corrupt index files, checksum mismatch

如果消息提到损坏,不要手动删除文件。保留日志,检查是否存在良好的副本,并使用Elasticsearch恢复工具和API,而不是直接编辑数据路径。

磁盘水位线

当节点越过磁盘水位线时,Elasticsearch会更改分片分配行为。搜索DiskThresholdMonitorlow disk watermarkhigh disk watermarkflood-stage disk watermark。默认值可能因版本和配置而异,因此在操作前请确认你的集群设置:

GET /_cluster/settings?include_defaults=true&filter_path=**.disk.watermark*

如果索引在洪水阶段事件后变为只读,请先清理磁盘空间。然后仅在节点安全低于水位线后移除该块:

PUT /my-index/_settings
{
  "index.blocks.read_only_allow_delete": null
}

使用慢日志解决性能问题

对于慢速搜索或索引操作,主服务器日志通常过于宽泛。慢日志会跟踪超过配置阈值的操作。可以使用索引设置API为每个索引配置它们。

PUT /my_index/_settings
{
  "index.search.slowlog.threshold.query.warn": "1s",
  "index.search.slowlog.threshold.query.info": "500ms",
  "index.indexing.slowlog.threshold.index.warn": "1s"
}

配置为包含请求源时,慢日志会显示索引、分片、经过时间和请求源。使用它们来发现重复的昂贵查询、宽泛的日期范围、大量使用通配符的搜索以及对未映射为高效聚合的字段进行的聚合。

实用的审查工作流程

从用户可见的症状开始,然后反向工作:

  1. 检查集群健康和受影响的索引。
  2. 在事件发生时间附近搜索WARNERROR日志。
  3. 使用node.namecluster.uuid跨节点比较日志。
  4. 关注第一个重复的警告,而不仅仅是最终的异常。
  5. 接下来使用有针对性的API:对于未分配的分片使用分配解释,对于慢速请求使用慢日志,对于资源压力使用节点统计信息。

例如,如果Kibana显示红色索引,首先找到未分配的分片,然后搜索该索引和分片编号的日志。如果日志提到磁盘水位线,先解决磁盘压力,然后再重新路由任何内容。如果提到节点丢失,在考虑有风险的分配命令之前,先恢复该节点或从快照恢复。

要点

每次处理Elasticsearch事件时,从找到第一个相关的警告或错误开始,而不是最响亮的最终堆栈跟踪。对于节点、发现、磁盘、内存和分片故障,使用主日志。当集群健康但特定搜索或索引工作负载缓慢时,使用慢日志。