跳转到内容

Elasticsearch 分布式搜索与运维面试题

22 道题
分类
中间件
题目数
22 道
已阅读 0 / 22 题
1 Elasticsearch 的核心数据模型是什么?集群、节点、索引、文档和分片如何关联?

答案:

Elasticsearch 是分布式文档存储和搜索引擎。业务数据以 JSON 文档保存到索引 (index)中;索引被拆成若干主分片(primary shard),每个主分片可有零个或多个 副本分片(replica shard)。节点(node)共同组成集群(cluster),负责保存分片、 执行检索和维护集群状态。

  • 索引是逻辑命名空间,定义字段映射(mapping)和索引级设置(settings)。
  • 文档只会路由到一个主分片;同一主分片及其副本构成一个复制组 (replication group)。
  • 主分片数量不能直接在原索引上修改。需要改变数据布局时,应评估拆分 (split)、收缩(shrink)或重建索引(reindex)创建出的新索引。
  • 副本数可动态调整。副本既提高节点故障时的可恢复性,也可以分担搜索请求; 它不替代集群外的备份。
PUT /products-v1
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      },
      "created_at": {
        "type": "date"
      }
    }
  }
}

面试中不要把“索引”等同于关系型数据库的一张表。索引的主分片数量、字段映射、 生命周期和查询模式都会直接影响后续容量与性能。

2 Elasticsearch 的节点角色有哪些?什么时候需要专用节点?

答案:

节点通过 node.roles 声明职责。所有节点都隐式承担协调 (coordinating)职责:接收请求、把请求分发给相关分片,再汇总结果。协调职责不能 关闭;专用协调节点只是把显式角色设为空,仍需要足够的 CPU 和内存处理聚合与结果归并。

  • 主节点候选(master-eligible)参与选举,并负责索引创建、分片分配、节点加入和 集群状态发布。稳定的生产集群通常使用三个可参与选举的专用主节点,其中至少两个 不应是仅投票节点(voting-only)。
  • 数据节点(data、data_hot、data_content 等)保存分片,执行搜索、聚合和写入。 集群至少需要 data,或同时具备 data_hot 与 data_content。
  • 摄取节点(ingest)执行摄取管道(ingest pipeline)。当解析、富化或脚本处理成为 瓶颈时,才考虑把它拆成专用角色。
  • remote_cluster_client 是跨集群搜索(CCS)和跨集群复制(CCR)的前提;机器学习 (ml)和转换(transform)角色也应随功能启用而规划。
# 专用主节点示例
node.roles: [master]
path.data: /var/lib/elasticsearch

角色变更不是简单改配置后重启。移除 data 前要先迁走该节点分片;移除 master 和 data 后,数据路径中若仍有索引元数据,节点会拒绝启动。实践中更稳妥的做法通常是 新建目标角色节点、迁移数据、再下线旧节点。

3 倒排索引、分析器和字段映射各解决什么问题?

答案:

全文检索依靠倒排索引(inverted index):它把词项映射到包含该词项的文档列表,而不是 逐篇扫描文档。写入 text 字段时,分析器(analyzer)会按“字符过滤器、分词器、 词元过滤器”的顺序处理原文本,再把词项、位置和偏移信息写入 Lucene 段(segment)。

  • text 适合全文匹配,默认不适合直接聚合或排序。
  • keyword 保留完整值,适合精确过滤、聚合、排序和标识字段。
  • doc_values 是面向排序、聚合和脚本访问的列式数据结构。除 text 外,多数可用字段 默认启用它。
  • _source 保存原始 JSON,便于取回文档和重建索引;它不是倒排索引的替代品。
  • 动态映射(dynamic mapping)能降低接入门槛,但未经约束的动态字段会造成字段爆炸, 挤占集群状态和堆内存。
PUT /articles-v1
{
  "settings": {
    "analysis": {
      "analyzer": {
        "title_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "title_analyzer",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "category": {
        "type": "keyword"
      }
    }
  }
}

设计字段时先问清楚“怎样搜、怎样筛、怎样聚合、保留多久”,再定映射。对同一业务字段 同时需要全文检索和精确聚合时,多字段(multi-fields)通常比事后开启 fielddata 更合适。

4 文档如何路由到分片?主副本模型如何保证已确认写入的一致性?

答案:

写入请求先根据 _routing 找到目标主分片。未指定时默认使用文档 _id;指定自定义 路由后,相关的写入、读取、更新和删除请求都必须携带相同路由值,否则可能查不到文档, 或把操作发往错误分片。

主分片是复制组的写入入口。它校验并执行操作,然后并行转发给当前“已同步副本集合” (in-sync copies)。只有这些副本都完成操作,或失联副本已被集群状态安全地移出集合后, 主分片才向客户端确认成功。wait_for_active_shards 控制请求开始前至少要有多少活动 分片副本,不是“把所有副本都强制拉起”的开关。

PUT /orders/_doc/order-42?routing=tenant-a
{
  "tenant_id": "tenant-a",
  "status": "paid",
  "amount": 299.0
}

GET /orders/_doc/order-42?routing=tenant-a

自定义路由可以缩小单租户查询的分片范围,却可能让少数大租户成为热点。上线前要按路由键 的分布、峰值写入和查询模式压测;“同一用户数据放在一起”不等于“所有用户都会均匀”。

5 写入链路中的刷新(refresh)、事务日志(translog)和提交(flush)分别意味着什么?

答案:

一次写入大致经历协调、主分片执行、副本复制、近实时可见和持久化恢复几个阶段。

  1. 协调节点根据路由把请求送至主分片。
  2. 主分片校验映射并执行写入,再把操作复制给已同步副本。
  3. 变更先记录到事务日志(translog),用于崩溃后的恢复。
  4. 刷新(refresh)会让新段对搜索可见,因此 Elasticsearch 是近实时 (near real-time)系统;默认刷新间隔通常为一秒,但具体值应以索引设置为准。
  5. 提交与清理事务日志由后台的 flush 流程协调。它不是每次写入都要手工调用的运维动作。
PUT /logs-write-heavy/_settings
{
  "index": {
    "refresh_interval": "30s"
  }
}

批量导入期间适当拉长 refresh_interval 能减少小段和合并压力;导入结束后应恢复业务 需要的可见性。不要对每条请求使用 refresh=true,它会制造大量小段。确实需要“响应前 已可搜索”时,refresh=wait_for 通常比强制立即刷新更温和。

6 搜索请求为什么会经历查询(query)和获取(fetch)两个阶段?

答案:

搜索请求到达协调节点后,会在相关分片副本上执行查询阶段(query phase)。每个分片返回 候选文档、得分或排序值;协调节点做全局归并,确定最终命中列表,再向持有这些文档的 分片发送获取阶段(fetch phase)请求,取回 _source、高亮字段等内容。

  • 一个索引的搜索通常会触及每个相关主分片的一个副本,不是只访问一个节点。
  • size 增大、深度 from 分页、复杂高亮和高基数聚合都会增加分片侧及协调节点的内存 和网络开销。
  • 查询与获取耗时应分开观察。查询慢常见于词项、过滤、聚合或磁盘读取;获取慢则常与 _source 过大、脚本字段或网络传输有关。
GET /orders/_search
{
  "track_total_hits": false,
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "status": "paid"
          }
        }
      ]
    }
  },
  "sort": [
    {
      "created_at": "desc"
    }
  ],
  "size": 50
}

性能问题不要先归咎于“节点少”。先检查查询 DSL、命中规模、目标分片数、慢日志和 _profile 结果,才能知道瓶颈在检索、聚合、获取还是协调汇总。

7 深度分页应如何选择偏移分页、滚动(scroll)和 PIT + search_after?

答案:

from/size 适合普通分页,但默认的 index.max_result_window 会限制深度,以防每个分片 都保留过多候选结果。面向交互式深度分页,优先使用时间点(point in time,PIT)配合 search_after;面向全量导出、重建或离线处理,才考虑 Scroll。

  • search_after 使用上一页最后一条记录的排序值继续翻页;每一页必须使用相同的查询和 排序。
  • 在连续写入的索引上,单独使用 search_after 可能因 refresh 产生漏读或重复。PIT 固定 可见视图,并提供稳定的并列排序值。
  • Scroll 会持有搜索上下文,不适合实时用户翻页。完成后应主动清理 Scroll 或关闭 PIT。
POST /orders/_pit?keep_alive=1m

GET /_search
{
  "size": 100,
  "pit": {
    "id": "<最新 PIT ID>",
    "keep_alive": "1m"
  },
  "sort": [
    {
      "created_at": {
        "order": "asc",
        "format": "strict_date_optional_time_nanos"
      }
    }
  ],
  "search_after": [
    "2026-01-15T10:30:00.000Z",
    4294967298
  ]
}

DELETE /_pit
{
  "id": "<最新 PIT ID>"
}

不要依赖 _id 作为普通排序字段。为稳定分页设计显式的业务排序字段;使用 PIT 时还要把 响应中的最新 PIT ID 和末条 sort 值一起带到下一页。

8 当前 Elasticsearch 如何形成集群并完成主节点选举?

答案:

新版本使用基于投票配置的集群协调机制,不再使用旧版发现模块(Zen Discovery)及 discovery.zen.minimum_master_nodes。节点通过 discovery.seed_hosts 找到已有的 主节点候选;首次引导一个全新集群时,才用 cluster.initial_master_nodes 指定初始 候选集合。

cluster.name: search-prod
node.name: master-a
node.roles: [master]
discovery.seed_hosts:
  - master-a.example.net
  - master-b.example.net
  - master-c.example.net
cluster.initial_master_nodes:
  - master-a
  - master-b
  - master-c

cluster.initial_master_nodes 只用于从未形成过的集群。集群形成后应从所有节点配置中移除, 也绝不能把它加到加入现有集群的节点、重启节点或全量重启流程中;否则可能意外引导出另一个 集群。正常运行的三个主节点候选可以容忍一个故障,前提是网络和持久化的集群元数据都可靠。

9 分片分配、感知分配和磁盘水位如何共同影响可用性?

答案:

集群会在节点加入、退出、扩容、缩容、索引设置变化或磁盘压力出现时,自动分配、迁移和恢复 分片。副本不会与自己的主分片放在同一节点,但跨机架或跨可用区的隔离需要额外配置。

  • 分配感知(allocation awareness)根据节点属性,例如 zone,让副本尽量跨故障域。
  • 强制感知(forced awareness)能避免故障域缺失时把所有副本塞到剩余区域,但容量不足时 会留下未分配副本,集群可能保持黄色。
  • 磁盘水位(disk watermarks)会限制新分片分配或触发迁移。到达洪水阶段时,索引可能被 加上写入保护;先释放或扩充真实磁盘,不要把阈值长期调高。
GET /_cluster/allocation/explain
{
  "index": "logs-2026.01.15",
  "shard": 0,
  "primary": false
}

这个 API 给出的决定器(decider)结论比猜测更可靠。常见根因是节点数少于副本要求、属性 过滤规则冲突、分配被暂停、磁盘不足或恢复资源受限。

10 绿色(green)、黄色(yellow)、红色(red)三种集群健康状态分别代表什么?

答案:

  • Green:所有主分片和副本分片已分配。
  • Yellow:所有主分片可用,但至少一个副本未分配;服务通常可读写,容错能力下降。
  • Red:至少一个主分片未分配,相关数据不可完整读写,必须按事件处理。

先看状态,再解释原因,最后才考虑干预:

GET /_cluster/health?level=shards
GET /_cat/shards?v=true
GET /_cluster/allocation/explain
GET /_cat/allocation?v=true

应依次确认是否发生节点丢失、磁盘水位触发、分配过滤冲突、索引副本数与节点数不匹配, 以及恢复是否仍在进行。allocate_stale_primary 代表接受数据丢失后强行指定旧副本为主, 只能在已评估快照、业务恢复目标和数据损失范围后使用,不能当作 Red 状态的常规修复命令。

11 如何做分片和容量规划,而不是套用固定“每分片多少 GB”的规则?

答案:

分片既是并行度单位,也是恢复、迁移、合并、缓存和集群元数据的成本单位。合适的大小取决于 写入速率、查询形态、保留周期、可接受的节点恢复时间、磁盘吞吐、堆内存和节点数量。任何固定 分片大小都只能作为压测起点,不能替代容量模型。

规划时至少计算:

  1. 日增量、保留天数、压缩后的磁盘占用和副本倍数。
  2. 高峰写入与搜索并发会触及多少分片,以及单节点能承受多少并发恢复。
  3. 单节点故障后,剩余节点是否有足够磁盘和网络余量接收分片。
  4. 索引数量、字段数量和分片数量对主节点集群状态与堆内存的累计影响。
GET /_cat/indices?v=true
GET /_cat/shards?v=true
GET /_nodes/stats/jvm,fs,indices?human=true
GET /_cluster/stats?human=true

时间序列数据通常按数据流(data stream)和滚动条件管理;内容型数据则更关注查询延迟和 更新行为。两类数据不要因为都叫“索引”就复用同一套分片策略。

12 写入吞吐不足时,应从哪些方面优化批量写入(Bulk)、刷新和背压?

答案:

先确认写入瓶颈是客户端、摄取管道、映射、磁盘、段合并还是节点写线程池。Bulk API 是常见 入口,但批次大小和并发数必须用真实文档体积和失败率逐步压测,而不是照搬固定条数。

  • 以多个中等批次逐步提升并发,观察吞吐、延迟、GC、磁盘队列和 429 拒绝率。
  • 收到 429 或超时后使用有限重试和指数退避;盲目放大并发只会放大排队和恢复时间。
  • 大规模一次性导入可临时拉长 refresh 间隔,结束后恢复并等待必要的合并。
  • 尽量预先定义映射,避免把不稳定的 JSON 键动态建成字段。
  • 只有业务明确接受最近一小段已确认数据丢失时,才评估更激进的事务日志持久化策略。
POST /products/_bulk
{"index":{"_id":"p-1"}}
{"name":"keyboard","category":"peripheral","price":399}
{"index":{"_id":"p-2"}}
{"name":"mouse","category":"peripheral","price":199}

Bulk 请求是 NDJSON:动作行与数据行交替,末尾必须有换行。客户端要逐项检查响应里的 errors 和每条操作状态,不能只看 HTTP 200。

13 搜索和聚合慢时,优先检查哪些设计问题?

答案:

多数搜索性能问题来自数据建模和查询形状,而不是缺少某个“调优参数”。

  • 精确筛选、聚合和排序使用 keyword、数值或日期字段;不要默认在 text 上开启 fielddata。
  • 用 filter 承载无须计算相关度的条件,让查询结构更清晰,也更可能复用缓存。
  • 给用户可控的时间范围、返回字段和聚合桶设置上限,避免一次请求扫过过多索引和分片。
  • 高基数 terms 聚合、通配符前缀查询、深度嵌套、脚本和大范围高亮都应单独压测。
  • 通过慢日志和 _profile 识别真正昂贵的子查询;_profile 会增加开销,只用于诊断。
GET /logs-*/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "@timestamp": {
              "gte": "now-15m"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "by_service": {
      "terms": {
        "field": "service.name",
        "size": 20
      }
    }
  }
}

优化前后要用同一批生产特征数据和查询集比较 p95、p99、拒绝率及资源消耗。只比较平均耗时 很容易掩盖尾延迟问题。

14 堆内存、文件系统缓存、查询缓存和段合并之间有什么关系?

答案:

Elasticsearch 的 JVM 堆用于集群状态、查询执行、聚合和内部缓存;Lucene 索引读取还高度依赖 操作系统文件系统缓存(filesystem cache)。把可用内存全部分给 JVM 往往会让搜索和合并更慢。

  • 生产环境通常优先采用 Elasticsearch 自动计算的堆大小;如需覆盖,Xms 和 Xmx 应相同, 且总堆不应超过节点可用内存的一半,还要检查压缩普通对象指针是否仍有效。
  • 请求缓存(request cache)适合不频繁变化的聚合类请求,默认主要缓存 size=0 的结果; 刷新和映射更新会使相关缓存失效。
  • 段合并会带来明显的磁盘 I/O、CPU 和临时空间消耗。不要对仍在写入的索引频繁手动 force merge。
  • 断路器(circuit breaker)是防止单次请求耗尽内存的保护,不应通过长期调大阈值来掩盖 高基数聚合或过大的查询。
GET /_nodes/stats/jvm,breaker,indices?human=true
GET /_stats/request_cache?human=true

排查内存问题时同时看堆使用、GC 暂停、断路器触发、操作系统内存、页缓存命中和磁盘延迟。 只看到“堆没满”并不说明节点没有内存压力。

15 数据流、组合模板、数据层和索引生命周期管理(ILM)应怎样配合?

答案:

追加写入的时间序列数据优先使用数据流(data stream)。数据流由一组后台索引承载写入, 组合模板(composable index template)负责把映射、索引设置和索引生命周期管理 (ILM)策略一起应用到新建后台索引。

  • data_hot 处理最新时间序列数据的写入和高频查询;data_warm、data_cold、 data_frozen 适合访问频率逐渐降低的数据。
  • 普通内容数据通常停留在 data_content,不应机械套用热温冷迁移。
  • ILM 负责滚动、迁移、收缩、可搜索快照和删除等动作。删除阶段是数据保留策略的一部分, 不等于备份策略。
  • 变更 ILM 前,要确认现有节点角色、数据层容量、快照仓库和最小保留要求;没有目标数据层 时,迁移策略只会造成未分配或反复等待。
PUT /_index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "data_stream": {},
  "template": {
    "settings": {
      "index.lifecycle.name": "logs-retention"
    }
  }
}

滚动阈值、保留时间和副本数应由恢复目标、查询时效和成本共同决定。每次调整后都要检查 _ilm/explain,确认策略真的在执行,而不是只停留在配置里。

16 摄取管道适合做什么?如何避免把数据清洗变成集群瓶颈?

答案:

摄取管道在文档进入索引前执行处理器,例如字段重命名、日期解析、Grok 提取、GeoIP 富化和 脚本转换。它适合稳定、可观测、轻量的数据标准化;不适合把长时间外部调用或复杂大计算放到 每次写入路径上。

PUT /_ingest/pipeline/normalize-log
{
  "processors": [
    {
      "rename": {
        "field": "time",
        "target_field": "@timestamp",
        "ignore_missing": true
      }
    },
    {
      "set": {
        "field": "event.dataset",
        "value": "app.log",
        "if": "ctx.containsKey('message')"
      }
    }
  ],
  "on_failure": [
    {
      "set": {
        "field": "error.pipeline",
        "value": "{{ _ingest.on_failure_message }}"
      }
    }
  ]
}

POST /_ingest/pipeline/normalize-log/_simulate
{
  "docs": [
    {
      "_source": {
        "time": "2026-01-15T10:30:00Z",
        "message": "started"
      }
    }
  ]
}

上线前用 _simulate 覆盖正常、缺字段和异常格式样本。若管道处理延迟明显,应拆分流量、 增加专用摄取能力或把重计算移到上游,而不是让数据节点默默承担全部处理。

17 快照、快照生命周期管理(SLM)和恢复演练应如何设计?

答案:

可恢复的备份来自快照(snapshot),而不是复制数据目录。Elasticsearch 快照写入集群外的 快照仓库(snapshot repository),可由快照生命周期管理(SLM)按计划创建和清理。

  • 快照只包含打开的索引;关闭索引不会被备份。
  • 快照还可包含集群状态、模板、ILM 策略和系统索引等。是否恢复全局状态必须按目标集群现状 评估,避免覆盖已有配置。
  • 仓库权限、加密、跨区域冗余、保留期限和恢复速度属于同一份灾备设计,不能只验证“快照成功”。
  • 应定期在隔离环境执行恢复,校验索引、文档量、关键查询、权限和恢复时间目标。
PUT /_slm/policy/daily-backup
{
  "schedule": "0 30 1 * * ?",
  "name": "<daily-backup-{now/d}>",
  "repository": "primary-repository",
  "config": {
    "include_global_state": true
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 50
  }
}

GET /_slm/status
GET /_snapshot/primary-repository/_all

示例中的时间和保留量不是通用标准。恢复演练如果没有覆盖权限、系统功能状态和应用回切, 只能证明对象存储里有文件,不能证明业务可以恢复。

18 Elasticsearch 的传输层加密(TLS)、角色、用户和 API 密钥(API Key)如何实现最小权限?

答案:

安全设计至少覆盖 HTTP 接口、节点间传输、身份认证、授权和密钥生命周期。生产环境应启用 HTTP 层与传输层 TLS,按业务身份授予角色,而不是让应用长期使用超级用户。

PUT /_security/role/orders_reader
{
  "cluster": ["monitor"],
  "indices": [
    {
      "names": ["orders-*"],
      "privileges": ["read", "view_index_metadata"]
    }
  ]
}
  • 应用优先使用范围受限、可轮换的 API Key 或服务账号凭据。
  • 角色要按索引模式和具体权限拆分;read、write、manage、monitor 的影响范围不同。
  • 字段级和文档级权限适合确有多租户隔离需求的场景,但会增加设计、测试和订阅版本核验成本。
  • 审计日志、外部身份提供方和部分高级安全能力要按当前发行版与订阅确认可用性。

密钥不能写进索引模板、客户端代码、启动参数或日志。轮换时要验证新旧凭据的重叠窗口,并及时 撤销不用的凭据。

19 跨集群搜索(CCS)与跨集群复制(CCR)的边界是什么?

答案:

跨集群搜索(cross-cluster search,CCS)让本地集群通过远程集群别名查询其他集群的数据; 跨集群复制(cross-cluster replication,CCR)则把一个领导者索引(leader index)的操作 复制到远端的跟随者索引(follower index)。它们解决的问题不同。

  • CCS 适合统一查询多个地域或业务集群,数据仍在原集群;查询延迟、远程可用性和权限会影响 用户体验。
  • CCR 是单向复制。跟随者索引不应被应用直接写入;故障切换和回切需要明确谁是写入源。
  • 相关节点需要 remote_cluster_client 角色,并要规划传输层 TLS、网络连通性、远程别名、 索引自动跟随规则和监控。
  • 功能可用性与许可条件会随发行版和订阅变化,设计和升级前应核对当前官方说明。
PUT /_cluster/settings
{
  "persistent": {
    "cluster.remote.dr.seeds": [
      "<remote-seed-host>:9300"
    ]
  }
}

GET /_remote/info

不要把 CCR 当作快照的替代品,也不要把 CCS 当作数据合并方案。跨集群策略要同时回答数据延迟、 写入归属、区域故障、权限和成本五个问题。

20 如何进行滚动升级、节点下线和配置变更,尽量避免中断?

答案:

升级前先阅读目标版本的破坏性变更和支持路径,确认集群健康、快照可用、磁盘余量、索引兼容性 以及客户端版本。不能只升级一个节点后长期停在混合版本状态。

一个受控的节点维护流程通常是:

  1. 确认没有 Red 状态、恢复任务或异常积压,并记录基线指标。
  2. 对要永久下线的数据节点,先用分配过滤迁走分片,等待迁移完成。若所用部署平台支持 节点关闭 API,再按其编排流程申请下线。
  3. 若要移除主节点候选,先处理投票配置排除(voting configuration exclusions),确认它已不再 参与投票,再停止节点。
  4. 按支持顺序逐台升级或重启,等待每台节点重新加入并观察分片与业务指标。
  5. 完成后清理临时排除、恢复默认分配策略,并做功能回归和快照验证。
PUT /_nodes/<node-id>/shutdown
{
  "type": "restart",
  "reason": "planned maintenance"
}

节点关闭 API 只是在停止进程前登记迁移意图,本身不会终止节点;还要按部署环境的受支持流程 完成维护。动态设置可通过 API 修改,静态设置通常需要重启。不要在一次变更中同时调整版本、 节点角色、分片策略和客户端流量,否则出现问题时很难确定原因。

21 生产监控和告警应覆盖哪些信号?

答案:

监控的目标是及早发现可用性、容量和性能的趋势,而不是只盯一个 cluster_health 颜色。

  • 集群可用性:主节点变化、待处理任务、未分配分片、恢复进度和节点离线。
  • 容量:各节点磁盘余量与水位、分片数量、索引增速、快照仓库健康和最近一次成功备份时间。
  • JVM 与主机:堆使用、GC 停顿、断路器触发、文件描述符、CPU、内存、磁盘 I/O 和网络。
  • 业务路径:索引与搜索的延迟、拒绝率、线程池队列、Bulk 失败、慢日志和热点索引。
  • 数据治理:ILM 阶段停滞、数据流滚动失败、映射字段数量异常增长。
GET /_cluster/health
GET /_cluster/pending_tasks
GET /_cat/recovery?v=true
GET /_nodes/stats/thread_pool,jvm,fs,breaker?human=true
GET /_ilm/status

告警阈值应建立在业务基线和可恢复时间目标上。短暂的 Yellow 在扩容或恢复中可能合理; 持续 Yellow、磁盘持续逼近水位或拒绝率上升则需要明确负责人和处置时限。

22 遇到未分配分片、磁盘写入保护或断路器异常(Circuit Breaking Exception)时,如何排障?

答案:

先保留现场:记录健康状态、节点列表、分片分配解释、磁盘与 JVM 指标、近期变更和相关日志。 这三类故障的共同误区是急于“强制恢复”,结果把可诊断问题变成数据损失。

GET /_cluster/allocation/explain
GET /_cat/allocation?v=true
GET /_nodes/stats/jvm,breaker,fs?human=true
GET /_cluster/settings?include_defaults=true&flat_settings=true
  • 未分配分片:根据 allocation/explain 的决定器结果处理节点、磁盘、过滤条件、副本数或 恢复资源。不要先执行手工 reroute。
  • 磁盘写入保护:释放空间、扩容或完成 ILM 清理,再确认索引是否仍保留写入阻塞;不要把 磁盘水位长期放宽。
  • 断路器异常:缩小时间范围和聚合桶、修正字段映射、限制并发或拆分查询。提高断路器上限 只能作为经过容量评估的临时措施。

最后复核数据完整性、查询结果、备份链路和告警恢复情况。对造成 Red 状态或有数据损失风险的 操作,应在变更记录中写清决策人、影响范围和恢复依据。

参考:Elasticsearch 官方文档中的分布式架构、节点角色、集群形成、快照恢复与性能优化章节。