上一篇解决了安全体系——认证、授权、加密的洋葱模型。这一篇进入生产环境中 ES 集群怎样运维。

生产运维的核心工作是监控和排障。ES 提供了丰富的内置 API 来观察集群各层的状态。关键是建立分层监控的思路:从集群健康到节点资源到索引性能到查询诊断,逐层下钻。

本文抓两个问题:生产集群应该监控哪些指标,以及常见故障怎样排查。

分层监控

监控从宏观到微观分四层,每层对应不同粒度的 API 和指标。排查问题时从 L1 开始逐层下钻,定位到具体层再展开:

graph TD
    L1[L1 集群健康<br/>_cluster/health] -->|status != green| L2[L2 节点资源<br/>_nodes/stats]
    L2 -->|JVM/disk 异常| L3[L3 索引性能<br/>_cat/indices]
    L3 -->|rejected/慢操作| L4[L4 查询诊断<br/>slow log / profile]

    L1 -->|green| OK[正常运行]

    style L1 fill:#50b86c,color:#fff
    style L2 fill:#e6a23c,color:#fff
    style L3 fill:#e6a23c,color:#fff
    style L4 fill:#f56c6c,color:#fff
    style OK fill:#909399,color:#fff

L1:集群健康

1
GET _cluster/health
Status 含义 响应
green 所有 primary 和 replica 已分配 正常
yellow 所有 primary 已分配,部分 replica 未分配 关注但不紧急
red 部分 primary 未分配 紧急——数据不可用
1
2
GET _cat/health?v
# 快速查看 status, node.total, shards, unassign

Yellow 状态在单节点集群中是正常的(replica 无法分配到另一个节点)。在多节点集群中 yellow 状态需要排查——通常是节点故障、磁盘满或分配规则冲突。

L2:节点资源

1
GET _nodes/stats?filter_path=nodes.*.jvm.mem,nodes.*.os.mem,nodes.*.fs,nodes.*.process.cpu

关键指标:

指标 报警阈值(经验值) 说明
JVM heap used % > 75% 持续 GC 压力大,可能 OOM
GC old gen time 持续 > 5s/次 Stop-the-world GC 影响搜索延迟
Disk used % > 85% 触发 disk watermark,停止 shard 分配
OS memory % > 95% 影响 filesystem cache
1
GET _cat/nodes?v&h=name,heap.percent,ram.percent,cpu,disk.used_percent

L3:索引性能

1
GET _cat/indices?v&h=index,docs.count,store.size,search.query_current,indexing.index_current
1
GET _cat/thread_pool/search,write?v&h=name,active,queue,rejected

rejected 非零表示线程池过载——搜索或写入请求被拒绝。

L4:查询诊断

慢查询日志(slow log)——记录超过阈值的搜索和写入操作:

1
2
3
4
5
6
7
PUT /my-index/_settings
{
"index.search.slowlog.threshold.query.warn": "5s",
"index.search.slowlog.threshold.query.info": "2s",
"index.search.slowlog.threshold.fetch.warn": "1s",
"index.indexing.slowlog.threshold.index.warn": "5s"
}

Profile API——定位搜索内部的耗时热点:

1
2
GET /my-index/_search
{ "profile": true, "query": { "match": { "title": "test" } } }

磁盘水位线

ES 用三级水位线控制 shard 分配:

水位线 默认值 触发行为
disk.watermark.low 85% 不再向该节点分配新 shard
disk.watermark.high 90% 尝试把 shard 迁移到其他节点
disk.watermark.flood_stage 95% 把该节点上所有 index 设为 read-only

flood_stage 触发后,写入失败。需要手动释放磁盘空间后解除 read-only:

1
2
PUT _all/_settings
{ "index.blocks.read_only_allow_delete": null }

扩缩容操作

扩容(加节点):新节点加入集群后,master 自动 rebalance——把一部分 shard 从现有节点迁移到新节点。无需手动操作。

缩容(移除节点):先用 allocation exclude 把 shard 从目标节点迁走:

1
2
3
4
5
6
PUT _cluster/settings
{
"persistent": {
"cluster.routing.allocation.exclude._name": "node-to-remove"
}
}

等所有 shard 迁移完成后再停止节点。直接停止节点会导致 shard 临时 UNASSIGNED,触发 recovery。

常见故障排查

集群状态异常时,按 health status 走不同的排查路径。Red 最紧急(primary 丢失),Yellow 次之(replica 问题),Green 下仍可能有性能问题需要进 L3/L4 排查:

flowchart TD
    Start[_cluster/health<br/>status?] -->|red| Red[Primary 未分配]
    Start -->|yellow| Yellow[Replica 未分配]
    Start -->|green| Green[检查 L2-L4 指标]

    Red --> R1{allocation/explain}
    R1 -->|节点不足| R1a[加节点]
    R1 -->|shard 损坏| R1b[reroute 到<br/>其他副本]
    R1 -->|磁盘满| R1c[清理磁盘 /<br/>加存储]

    Yellow --> Y1{单节点集群?}
    Y1 -->|是| Y1a[正常,<br/>replica 无处分配]
    Y1 -->|否| Y2{allocation/explain}
    Y2 -->|磁盘水位线| Y2a[清理磁盘]
    Y2 -->|allocation rule| Y2b[检查 exclude<br/>/ awareness 配置]

    Green --> G1[检查 rejected<br/>/ slow log / GC]

    style Red fill:#f56c6c,color:#fff
    style Yellow fill:#e6a23c,color:#fff
    style Green fill:#50b86c,color:#fff

UNASSIGNED Shards

1
2
GET _cluster/allocation/explain
{ "index": "my-index", "shard": 0, "primary": false }

常见原因和处理:

原因 表现 处理
节点不足 “no valid shard copy” 加节点或减少 replica
磁盘满 “disk watermark exceeded” 清理磁盘或加存储
Allocation rule “allocation filtering” 检查 allocation settings
损坏的 shard “shard copy corrupt” _cluster/reroute 分配到其他节点

节点 OOM

JVM OOM 通常由以下原因导致:

  • Fielddata 使用 text 字段做聚合/排序
  • Circuit breaker 阈值配置过高
  • 单个查询聚合结果集太大
  • Bulk 请求过大

Circuit breaker 机制防止单个操作耗尽内存:

1
GET _nodes/stats?filter_path=nodes.*.breakers
1
2
3
4
parent breaker:总内存限制(默认 JVM heap 的 95%)
fielddata breaker:fielddata 缓存限制(默认 40%)
request breaker:单个请求内存限制(默认 60%)
in_flight_requests:正在传输的请求大小限制

慢查询

排查步骤:

1
2
3
4
5
1. 开启 slow log,收集慢查询样本
2. 对慢查询加 profile: true,定位热点 segment/scorer
3. 检查是否有 wildcard/regexp 前缀通配
4. 检查 shard 数是否过多(scatter-gather 开销)
5. 检查 filesystem cache 命中率

模式提炼:分层监控

1
2
cluster → node → index → query
宏观状态 资源使用 业务指标 诊断细节
系统 L1 集群 L2 节点 L3 业务 L4 诊断
ES _cluster/health _nodes/stats _cat/indices slow log, profile
MySQL SHOW STATUS OS metrics slow query log EXPLAIN
Kafka broker state broker metrics topic metrics consumer lag
Redis INFO INFO memory/cpu INFO keyspace SLOWLOG

工程迁移表

运维操作 Elasticsearch MySQL Kafka Redis
健康检查 _cluster/health SHOW STATUS broker health PING / INFO
节点监控 _nodes/stats SHOW PROCESSLIST JMX metrics INFO sections
慢操作 Slow log + Profile Slow query log + EXPLAIN 无内置 SLOWLOG
扩容 加节点自动 rebalance 手动分库分表 加 broker + reassign 加节点 + resharding
缩容 Allocation exclude → stop 迁移数据 → stop Reassign → stop 迁移 slot → stop
磁盘保护 Disk watermark 无内置 Log retention maxmemory

练习

  1. _cat/health?v_cat/nodes?v_cat/indices?v_cat/shards?v 建立一个基础监控视图,理解各 API 返回的关键字段。

  2. 对一个 index 配置 slow log,执行一些搜索后查看 ES 日志目录中的 slowlog 文件。

  3. _cluster/allocation/explain 查看一个 UNASSIGNED shard(如果有)的分配失败原因。

系列导航

上一篇 下一篇
安全体系:认证、授权与加密 Elasticsearch 与 Solr:两种搜索引擎的设计选择

参考资料