Elasticsearch 基础与集群巡检

各位同学,今天我们聊聊 Elasticsearch 的基础和集群巡检。说实话,作为一个从 Logstash 1.x 就开始折腾的老运维,我判断一个 ES 集群靠不靠谱,第一件事就是看健康状态。不是看监控面板上那些花哨的图表,而是直接敲一行 API。

我个人习惯把集群巡检分成三个层面:节点层面、分片层面、业务层面。前两个层面通过健康状态 API 一把梭,第三个层面靠巡检脚本定时扫。今天我们先打地基——把节点角色、API 用法和常见故障啃透。

安装与配置:别踩这些坑

ES 的安装本身不难,单节点下载解压就能跑。但生产环境我建议用 RPM 或 Docker 方式,方便后续管理。这里分享几个我踩过的坑:

  • network.host 别乱配:我以前图省事直接配 0.0.0.0,结果跨网段通讯时发现节点之间无法发现。原因是发现模块的 discovery.seed_hosts 没加本机 IP。
  • JVM 堆内存别超过 31GB:ES 底层大量使用对象压缩,超过 31GB 会触发 JVM 的压缩对象指针失效,导致性能雪崩。我一般设成物理内存的一半,上限 30GB。
  • data 和 logs 目录分开:把两个目录挂到不同磁盘,防止日志写满导致数据节点挂掉。这个事情我在一个客户环境里吃了大亏——日志塞满磁盘,集群直接红色了两小时。

下面是一份简版配置清单,适合 3 节点入门集群:

配置项推荐值说明
cluster.nameelk-cluster同一集群必须一致
node.namenode-1, node-2, node-3每个节点唯一
network.host内网 IP不要用 0.0.0.0 或 127.0.0.1
discovery.seed_hosts["IP1", "IP2", "IP3"]种子节点列表
cluster.initial_master_nodes["node-1"]首次选举用
path.data/data/elasticsearch建议独立磁盘
path.logs/var/log/elasticsearch系统盘分区分开

我的小技巧:启动前用 elasticsearch-setup-passwords interactive 设置内置用户密码,安全审计逃不掉。

节点角色:各司其职才稳定

一个 ES 集群里节点可以扮演多重角色。你想想看,如果让一个节点又当 master 又忙 data 又做 ingest,出问题概率会很高。我建议按职能拆分。

角色职责配置参数我踩过的坑
Master管理集群元数据、分配分片、处理 join/leavenode.master: truemaster 节点数量推荐奇数(3或5),避免脑裂。我见过有人用 2 个 master,网络抖动直接丢半数票
Data存储数据、执行 CRUD 和聚合node.data: true数据节点磁盘利用率超过 85% 自动触发分片迁移,这是 ES 的自我保护机制,合理,但会加剧 IO 压力
Ingest在索引前处理文档(Pipeline)node.ingest: true默认开启,如果 ingest 负载高建议独立节点,避免拖慢数据写入
Coordinating接收客户端请求,转发到对应节点并合并结果以上三个角色全为 false这种节点负责做负载均衡,不加硬盘也能跑。我之前写巡检脚本时发现协调节点 CPU 飙升,排查后才意识到是聚合请求没做限流

实际生产环境,我建议至少部署 3 个专有 master 节点 + 3 个 data 节点 + 2 个 coordinating 节点。如果你资源紧张,至少保证 master 和 data 角色物理分离。

集群健康状态 API:一眼看穿问题

最常用也最实用的 API 就这一条:

GET /_cluster/health

返回结果长这样:

{
  "cluster_name" : "elk-cluster",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 2,
  "active_primary_shards" : 45,
  "active_shards" : 90,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 1,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 98.9
}

说白了,核心就三句话:

  • green:所有主副分片都分配好了,集群健康。
  • yellow:主分片正常,但有些副本没分配。往往是因为单节点或磁盘不足。黄了赶紧查,别拖成红。
  • red:有主分片丢失,数据不可用。这是事故,需要立刻处理。

我记得有一次,巡检脚本报警显示 yellow 持续了 3 天,我以为是副本延迟分配,没在意。结果第四天数据节点宕机,因为副本一直没分配,主分片无法转移,集群直接红了……从那以后我在巡检脚本里加了逻辑:yellow 状态如果超过 1 小时就发紧急告警。

小心这个陷阱:API 返回的 unassigned_shards 不等于 0 的时候,不要只盯着 status。有些场景下 status 是 green 但 unassigned_shards 非零(比如延迟分配策略),一样棘手。我建议巡检脚本同时检查这两个字段。

基础故障排查:遇到问题别慌

集群出问题太正常了。下面这几个是我在实战中反复遇到的,每个都有血泪史。

  1. 节点无法加入集群——检查 cluster.name 是否一致,discovery.seed_hosts 是否可达。我曾经犯过低级错误:两个节点配了不同的 transport.port。
  2. 分片未分配——用 GET /_cluster/allocation/explain 查看具体原因。常见原因有:磁盘空间不足、节点有 _allocation.exclude._ip 设置、索引副本数大于可用节点数。
  3. 集群状态 red——先定位丢失的索引:GET /_cat/shards?h=index,shard,prirep,state | grep UNASSIGNED。如果数据不重要,直接删除索引;如果重要,尝试 reroute 手动分配或重新索引。
  4. 节点 OOM——看日志里的 OutOfMemoryError,通常是聚合查询太暴力。我建议限流 + 设置 search.max_buckets。

经验之谈:不要一上来就重启节点。重启可能导致 master 选举,如果 master 节点集群只有两个节点,选举失败会直接脑裂。优先用 POST /_nodes/_restart 滚动重启。

下面这张图画的是我每次做集群健康检查时的操作流程,你可以直接套用到自己的巡检脚本里。

Elasticsearch 集群健康检查流程 集群健康检查流程(巡检脚本核心逻辑) 1. 发起健康请求 2. 协调节点转发 3. Master 检查元数据 4a. 检查主分片分配 4b. 检查副本分片分配 5. 汇总健康状态 ✅ Green:正常 ⚠️ Yellow:告警 🚨 Red:紧急 修复建议:检查磁盘、reroute、删除索引

流程很简单:先请求健康 API,协调节点转发给 master,master 检查所有索引的 primary 和 replica 分片是否都到位,然后返回 green/yellow/red。巡检脚本拿到状态后,配合 unassigned_shards 和 relocating_shards 做阈值判断,该报警报警,该处理处理。

小结

今天的内容算是 ES 巡检的入门必修课。安装配置别犯低级错误,节点角色按场景拆分,健康 API 要读懂每个字段,故障排查有套路可循。这些技能我建议你直接在测试环境出一份故障模拟——故意关掉一个数据节点,然后用 API 观察状态变化,比看十遍文档都管用。