常见的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:严重级别,如INFO、WARN或ERROR。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]"
}
按日志级别优先处理消息
首先过滤WARN和ERROR级别,然后围绕相同的时间戳扩大搜索范围。第一个ERROR之前的几行通常比最终的堆栈跟踪更能解释原因。
| 级别 | 通常含义 | 首要操作 |
|---|---|---|
ERROR |
请求、分片、节点或子系统失败。 | 立即调查。 |
WARN |
Elasticsearch检测到风险状况。 | 在变成故障前检查。 |
INFO |
正常的生命周期活动。 | 用于提供警告和错误的上下文。 |
DEBUG / TRACE |
深层诊断细节。 | 仅在需要时短暂启用。 |
避免在生产节点上使用DEBUG或TRACE级别。详细日志会快速消耗磁盘并增加不必要的开销。
排查常见日志模式
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]
修复主机设置,重启节点,并确认启动日志到达节点加入集群的点。
网络绑定和发现失败
如果节点启动但未加入集群,搜索BindException、master not discovered、discovery和cluster.initial_master_nodes。BindException通常指向地址或端口冲突。发现消息通常指向错误的种子主机、被阻止的传输端口9300、不匹配的集群名称或阻止节点相互信任的安全设置。
断路器异常
断路器会阻止可能使用过多内存的请求。失败的请求会返回错误,但节点应保持存活。
搜索CircuitBreakingException或Data 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垃圾回收暂停。搜索gc、JvmGcMonitorService和overhead。在负载高峰期间出现少量警告可能是正常的。重复的警告伴随着搜索延迟上升通常意味着堆内存压力过大。
分片恢复和损坏
当分片分配失败或节点检测到本地分片副本损坏时,Elasticsearch会记录索引和分片编号。
搜索shard failed、failed shard、failed 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会更改分片分配行为。搜索DiskThresholdMonitor、low disk watermark、high disk watermark或flood-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"
}
配置为包含请求源时,慢日志会显示索引、分片、经过时间和请求源。使用它们来发现重复的昂贵查询、宽泛的日期范围、大量使用通配符的搜索以及对未映射为高效聚合的字段进行的聚合。
实用的审查工作流程
从用户可见的症状开始,然后反向工作:
- 检查集群健康和受影响的索引。
- 在事件发生时间附近搜索
WARN和ERROR日志。 - 使用
node.name和cluster.uuid跨节点比较日志。 - 关注第一个重复的警告,而不仅仅是最终的异常。
- 接下来使用有针对性的API:对于未分配的分片使用分配解释,对于慢速请求使用慢日志,对于资源压力使用节点统计信息。
例如,如果Kibana显示红色索引,首先找到未分配的分片,然后搜索该索引和分片编号的日志。如果日志提到磁盘水位线,先解决磁盘压力,然后再重新路由任何内容。如果提到节点丢失,在考虑有风险的分配命令之前,先恢复该节点或从快照恢复。
要点
每次处理Elasticsearch事件时,从找到第一个相关的警告或错误开始,而不是最响亮的最终堆栈跟踪。对于节点、发现、磁盘、内存和分片故障,使用主日志。当集群健康但特定搜索或索引工作负载缓慢时,使用慢日志。