考古|warmers 没用之后被 ES 5.0 删掉,快照期间关索引改成请求失败

举报
岳涛 发表于 2026/11/08 08:25:51 2026/11/08
【摘要】 5.0 有三处和索引操作、监控相关的变更:warmers 及 warmer API 被移除(2.3 起已标记废弃……

5.0 有三处和索引操作、监控相关的变更:warmers 及 warmer API 被移除(2.3 起已标记废弃,doc values 和落盘 norms 让它没有用处);快照期间的关/删索引行为反了过来,以前是快照失败,5.0 起是关/删请求失败;节点统计的 load_average 从 os 顶层挪进 os.cpu 且变成对象。同一节还有 suggest 统计并入 search、索引名不能以 -/+ 开头。本文按 v5.6.16 与 v2.4.6 源码逐条核对。

说明

实测环境:本地起的 Elasticsearch 5.6.16 单节点实例(官方 tar 包直接跑,堆内存 512MB,机器学习关闭),curl 连本地 9200 端口。本文「实测」小节的命令和输出都出自这个实例。

来源和边界先交代:本文的依据出自 v2.4.6到 v5.6.16 标签下的官方文件(index-apis.asciidoc、warmers.asciidoc、indices.put_warmer.json),文中引用的原文均来自这些文件。示例取自官方示例;哪些是文档写明、哪些是我的推断,正文里逐处标注。

01-index-apis

图 1:官方文件 index-apis.asciidoc(v5.6.16 标签)。来源:GitHub elastic/elasticsearch v5.6.16 index-apis.asciidoc

快照期间关闭/删除索引:谁失败

5.0 迁移文档(migrate_5_0/index-apis.asciidoc 第 4–10 行):

In previous versions of Elasticsearch, closing or deleting an index during a full snapshot would make the snapshot fail. In 5.0, the close/delete index request will fail instead. The behavior for partial snapshots remains unchanged: Closing or deleting an index during a partial snapshot is still possible. The snapshot result is then marked as partial.

变化是:以前快照被弄坏,5.0 起操作被拒绝。partial snapshot(部分快照)的行为不变,期间仍可以关/删索引,快照结果被标记为 partial。

实际影响:自动化运维里"定时快照 + 定时清理旧索引"如果碰在一起,升级之后清理任务会收到失败响应,而不是让快照失效。处理方式见下文。

02-indices.put_warmer

图 2:官方文件 indices.put_warmer.json(v2.4.6 标签)。来源:GitHub elastic/elasticsearch v2.4.6 indices.put_warmer.json

Warmers 被删除

Thanks to several changes like doc values by default and disk-based norms, warmers are no longer useful. As a consequence, warmers and the warmer API have been removed: it is no longer possible to register queries that will run before a new IndexSearcher is published.

Don’t worry if you have warmers defined on your indices, they will simply be ignored when upgrading to 5.0.

2.x 的 warmers 文档对它的描述是(warmers.asciidoc 第 5–12 行):在索引可被搜索之前执行注册好的搜索请求来预热,包括 filter cache、文件系统缓存,以及加载字段数据。2.3.0 那一行废弃说明写的理由和 5.0 移除时一样:落盘 norms 和 doc values 让它没有用例了。

注册 warmer 的端点在 2.x 的 REST API 定义里是 PUT /{index}/_warmer/{name}(indices.put_warmer.json),索引级还有 index.warmer.enabled 可以整个关掉(warmers.asciidoc)。5.0 里这些都不存在了。

升级时不需要清理数据:索引里已定义的 warmers 在 5.0 会被忽略。要改的是会注册 warmer 的代码,删掉即可。

03-warmers

图 3:官方文件 warmers.asciidoc(v2.4.6 标签)。来源:GitHub elastic/elasticsearch v2.4.6 warmers.asciidoc

同一节里的其余几处

系统 CPU 统计

The recent CPU usage (as a percent) has been added to the OS stats reported under the node stats API and the cat nodes API. The breaking change here is that there is a new object in the os object in the node stats response. This object is called cpu and includes percent and load_average as fields.

完整的变化在 第 22–46 行:load_average 从 os 的顶层字段挪进 os.cpu,格式从单个值变成含 1m、5m、15m 的对象,任一字段不存在表示对应值不可用;cat nodes 里 cpu 默认输出,原来的 load 字段删除,换成 load_1m、load_5m、load_15m,取不到值时为 null。

"os": {
  "cpu": {
    "percent": 12,
    "load_average": { "1m": 1.2, "5m": 0.9, "15m": 0.7 }
  }
}

Java API 也变了:OsStats#getLoadAverage 删除,改从 OsStats.Cpu#getLoadAverage 取,返回值不再是 double,而是封装了 1m/5m/15m 的对象;CPU 使用率从 OsStats.Cpu#getPercent 取。

suggest 统计并入 search

Suggest stats exposed through suggest in indices stats has been merged with search stats.

读 indices stats 里 suggest 段的监控要改成读 search 段(第 48–51 行)。

索引名不能以 - 或 + 开头

Elasticsearch no longer allows indices to be created started with ‘-’ or ‘+’, so that the multi-index matching and expansion is not confused.

理由是多索引匹配和展开会被这两个字符弄混。已经存在的这类索引不受影响,照常工作(第 53–59 行)。

快照冲突怎么处理

升级前,清理任务遇到的是"快照静默失败";升级后遇到的是"清理请求被拒"。后者更好:错误暴露在发起方,发起时就知道。

按处理成本排:

  • 错峰:把快照窗口和清理窗口在时间上分开,从源头避免冲突,改的是定时任务配置;
  • 重试:清理脚本能识别这类失败并重试,而不是当成普通错误记个日志就跳过。重试要处理"什么时候重试、重试几次、快照会不会一直在进行";
  • 下一轮补:接受部分索引这一轮清理失败,下一轮再补,前提是脚本真有"下一轮"这个机制。

错峰优于重试:重试要考虑的情况多,错峰在配置层面就解决了。真要重试,加上退避和次数上限,别让清理任务在快照期间持续打。

冲突时保护更不可恢复的那一方

快照是恢复能力的最后一道防线,索引关闭或删除是常规运维动作。从影响面看也是同一结论:快照失败意味着这份备份不可用,而且要等下次做快照、或者要恢复时才发现;清理请求失败只是这次没删成,代价小得多。

顺着这个思路,5.0 之后 ES 在类似冲突上的取向是宁可拒绝操作,也不让数据或备份进入不确定状态。遇到同类变更可以先问"哪个更不可恢复",通常是保护它。这是读这一批迁移条目得到的归纳,官方没有这样总结。

warmers 没了之后,"冷启动"还要管吗

warmers 解决的是"新 segment 发布后第一次查询要付出加载代价"。它被删是因为要预热的对象没了——问题本身并没有消失:排序聚合走 doc values(在磁盘上按需读取)、norms 落盘、filter 结果由 filter context 自动缓存。既然没有"必须常驻内存、首次访问才加载"的东西,预热就无从谈起。

所以升级之后不用找替代方案,删掉相关代码即可。

如果遇到"刚打开的新索引头几次查询慢",排查方向是这几项(预热解决不了):

  • 操作系统文件缓存:ES 依赖 page cache,索引刚打开、数据还没进缓存时会慢。给节点留足内存,别把堆设得过大挤掉系统缓存;
  • 查询是否走了 doc values:确认排序和聚合字段有 doc values,显式关掉的要打开;
  • 分片数量:分片过多会让新索引打开时的初始化开销上升;
  • 是否真的需要预热:多数业务场景下头几次查询慢几十毫秒可以接受,专门为此做预热反而增加复杂度。

监控迁移的具体改法

load_average 从顶层挪进 os.cpu 且变成对象,监控侧要改的不只是路径:

  • 告警规则里引用 os.load_average > N 的,改成 os.cpu.load_average['1m'] > N(按需要选 1m/5m/15m);
  • 原来取单值的看板,现在必须指定窗口,不能把整个对象丢进去;
  • 字段缺失时解析要有默认值处理,别让整个监控项因为缺字段而报错。

这类"字段从值变成对象"的变更在监控迁移里容易漏:它不报错,取不到就是空,看板变成空白或 0,不容易第一时间想到是结构变了。升级后主动比对一次 CPU 和负载的曲线,确认还有数据。

升级检查清单

  1. 我的建议是让索引管理脚本处理"快照进行中"的失败响应(错峰或重试),不要当成普通错误忽略;
  2. 删掉注册 warmers 的代码,索引里已有的 warmers 不用管;
  3. 监控脚本改读 os.cpu.percent 和 os.cpu.load_average.{1m,5m,15m};
  4. cat nodes 的输出解析改用 load_1m / load_5m / load_15m;
  5. Java 客户端里 OsStats#getLoadAverage 改成 OsStats.Cpu#getLoadAverage;
  6. indices stats 的 suggest 统计改读 search 段;
  7. 建索引的脚本检查名字是不是以 - 或 + 开头。

在 5.6.16 上跑一遍

先确认下划线开头的端点还在,再看 warmers 该:

warmer

图 4:本地 5.6.16 单节点实例上的实测输出。上:_settings;下:_warmer

curl -s -X PUT "" \
  -H 'Content-Type: application/json' -d '{"index.number_of_replicas":0}'

curl -s -X PUT "" \
  -H 'Content-Type: application/json' -d '{"query":{"match_all":{}}}' \
  | jq -r '"HTTP \(.status): \(.error.root_cause[0].reason)"'

_settings 正常返回 {"acknowledged":true};_warmer 返回 HTTP 400: Document mapping type name can't start with '_', found: [_warmer]。

这句报错本身就是证据:URI 里第一段被当成 type 名解析了,也就是说 5.6.16 的路由表里已经没有 _warmer 这个端点,请求掉进了"创建文档"那条路。如果端点还在,报的会是 warmer 相关的参数错误,而不是 type 名不合法。

结论是:查这类"某个端点还在不在"的问题,别只看报错是不是 400——要看报错来自哪一层。type 名校验说明请求根本没走到目标 API,这是判断端点已删最干脆的信号。

写在最后

这几条的方向不完全一样:warmers 是删掉一个用不上的能力,快照冲突是把静默失败改成显式拒绝,CPU 统计和 suggest 统计是结构变化。前两条一个可以直接删代码、一个要改脚本,后两条要改监控解析。

它们都不在业务代码里:warmers 在索引定义里,快照冲突在运维脚本里,统计结构在监控里。升级排查从应用代码开始的话,这条路径覆盖不到这三处,而这三处恰恰是"改了也没人立刻发现"的地方。所以给它们单列检查项:索引定义可以用脚本批量扫一遍 settings 和 mappings,运维脚本数量通常有限,人工过一遍。

参考

本文对照 Elasticsearch v5.6.16 标签的官方文档核对,引文逐字取自原文。图 4 的两次请求来自本地 5.6.16 单节点实例。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。