考古|模板冲突在 ES 2.4 提前到创建时报,升级前该导一遍模板

举报
岳涛 发表于 2026/10/27 11:33:49 2026/10/27
【摘要】 2.4 迁移文档只列了三条:设置 bootstrap.mlockall 改名为 bootstrap.memorylock;

2.4 迁移文档只列了三条:设置 bootstrap.mlockall 改名为 bootstrap.memory_lock;索引模板从此要"各自独立合法"才能创建,不再等到索引创建时合并后才校验;geo_distance 与 geo_distance_range 查询的 optimize_bbox 参数对 2.1 之后创建的索引废弃。

说明

来源和边界先交代:本文的依据出自 v2.4.6 标签下的官方文件(migrate_2_4.asciidoc、Bootstrap.java、configuration.asciidoc),文中引用的原文均来自这些文件。我没有启动集群、也没有跑测试,示例取自官方示例;哪些是文档写明、哪些是我的推断,正文里逐处标注。

01-migrate_2_4

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

三条里最容易踩的是模板那条

三条的风险不同,排序如下:

  1. 索引模板必须独立合法(最高):原本能成功的操作变成报错,而且发生在"建模板"这一步,通常是部署脚本的第一次调用,会卡住整个发布流程。出问题的模板往往已经跑了很久,没人记得它引用了公共模板里的 analyzer;
  2. bootstrap.mlockall 改名(中):配置改了就没事。文档说未来版本会拒绝启动,不改的话将来某次升级会起不来;
  3. optimize_bbox 废弃(低):只是废弃,对 2.1 之前创建的老索引不受影响。

所以我的建议是:升级 2.4 之前,先把所有模板导出来看一遍,不要等部署脚本报错。下面的命令可以直接跑。

02-Bootstrap

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

bootstrap.mlockall → bootstrap.memory_lock

2.4 迁移文档(migrate_2_4.asciidoc @ v2.4.6)的原文:

The setting bootstrap.mlockall has been renamed to bootstrap.memory_lock. Future versions of Elasticsearch will refuse to start if bootstrap.mlockall is set. You can switch to the new setting now.

这是命名调整:mlockall 是系统调用的名字,配置项改成了直接说明用途的 bootstrap.memory_lock。

2.4.6 的启动代码(Bootstrap 第 148–158 行)对这两个设置的处理是:只配了 bootstrap.mlockall,会写一条 deprecation 日志,仍然生效;两个都配了,抛 IllegalArgumentException,拒绝启动,消息是 both [bootstrap.mlockall] and [bootstrap.memory_lock] configured, just use [bootstrap.memory_lock]。文档里"未来版本会拒绝启动"指的是以后只配旧名也会被拒绝。所以升级路径是:

  1. 先把 elasticsearch.yml 里的 bootstrap.mlockall: true 改成 bootstrap.memory_lock: true,不要两个同时留着;
  2. 重启后验证内存确实锁住了;
  3. 再升级到 5.x。

验证方法见配置文档第 133–143 行:请求 GET /_nodes/process,看输出里的 mlockall。如果是 false,说明锁内存失败。文档给的最可能原因是运行 ES 的用户没有锁内存的权限,要在启动前以 root 执行 ulimit -l unlimited;另一个原因是临时目录(通常是 /tmp)以 noexec 挂载。这些系统侧限制在改名前后是一样的,改名不会解决它们。

03-configuration

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

索引模板必须独立合法

这一条改动的实际影响比它看起来大:

Prior to 2.4, validation was not performed upon creation of an index template. Rather, the index template was validated upon index creation after all matching templates were fully merged.

Each index template must now be independently valid prior to merging. This means, for example, that you can no longer reference analyzers, filters, or tokenizers from a shared template.

旧行为:创建模板时不校验,等到创建索引、所有匹配模板合并完成之后才校验。这样就可以把分析器定义放在一个"公共模板"里,业务模板只写 mapping 并引用那些分析器:合并后分析器确实存在,旧逻辑能过。这是文档隐含的用法,不是文档直接写的场景。

新行为:每个模板必须自己就是合法的。validateAndAddTemplate 在写入模板时,用模板自己的 settings 建一个临时索引,再把模板的 mappings 合并进去检验。引用别的模板里的 analyzer、filter、tokenizer,这一步就过不去。从代码读出来,报错应该出现在 PUT 模板的时候,具体错误文本本文没有实测。

改法有两条:

  1. 把分析器定义复制到每个需要的模板里:我的默认做法是走这条,简单直接,代价是重复定义、改一处要改多处;
  2. 后来的版本提供了可组合的模板机制,把公共部分单独定义、业务模板组合引用。2.4 里没有这个机制,只能用第一条。

迁移期最常见的现象应该是:升级到 2.4 之后,原来能执行的"新建模板"脚本突然报分析器找不到。排查方向是模板里引用了不属于自己的 analyzer。

geo_distance 的 optimize_bbox 废弃

The optimize_bbox parameter for geo_distance and geo_distance_range queries has been deprecated when querying indexes created after 2.1.

optimize_bbox 控制地理距离查询是否先用边界框做一层粗筛。文档没有说废弃的原因。一种推测是 2.2 换了 geo_point 的新格式(见 2.2 的 geo_point 变更),这个参数对新格式索引已经没有意义,但这只是推测。

注意限定条件"indexes created after 2.1":对老索引没有变化。所以清理这项参数不必一次性改完,可以跟着索引重建的节奏走:老索引的查询继续带着也没事,新建索引的查询里别再传。

三类自查命令,升级前先跑一遍

文档只给了改动说明,没给排查方法。下面的命令是补的:

第一类,找配置里的旧名字:

grep -rn "mlockall" /etc/elasticsearch/ /etc/default/elasticsearch 2>/dev/null

改完之后确认它真的生效了(配置文档用的就是这个请求):

curl -s 'localhost:9200/_nodes/process?pretty'

第二类,把所有模板导出来看引用:

# 列出所有模板
curl -s 'localhost:9200/_cat/templates?v'

# 逐个看内容,重点找 analysis 里引用了别的模板定义的 analyzer/filter/tokenizer
curl -s 'localhost:9200/_template/my_template' | python3 -m json.tool

判据是:模板自己的 settings.analysis 里必须包含它 mapping 里引用的全部分析器。缺了的,要补进来。

第三类,geo 查询里的废弃参数:

grep -rn "optimize_bbox" . | head -20

命中的如果是"新建索引的查询",删掉参数即可;老索引上的可以先留着。

这条改动的取舍

旧逻辑(合并后再校验)允许把公共部分抽出来共享,写法上很方便。代价是模板创建成功不代表它可用,真正的校验推迟到索引创建时,错误在合并后才暴露,排查起来绕。

2.4 改成各自独立合法,把校验提前,建模板时就知道对不对。代价是牺牲了共享写法,要复制定义。这个取舍是对的:早报错比晚报错便宜,尤其"晚"指的是某次偶发的索引创建失败。升级时要为此做一次整改,上面第二类命令就是用来提前找出这部分工作量的。

升级 2.4 前做什么

  1. 全局替换配置里的 bootstrap.mlockall,并确认 LimitMEMLOCK/memlock 已放开;
  2. 把现有所有模板过一遍,找出引用了外部 analyzer/filter/tokenizer 的模板,改成自带定义或组件化;
  3. 新建索引的 geo 查询去掉 optimize_bbox;
  4. 如果当前版本是 2.3.0 或 2.3.1,这两个版本的 CORS 预检有缺陷,见 2.3 的变更,直接升到 2.4 不受影响。

写在最后

  • 模板那条是 2.4 唯一会让原本能做的操作突然做不了的改动,升级前把所有模板导出来看一遍;
  • bootstrap.mlockall 现在改掉,并确认系统侧的 memlock 限制已放开;
  • optimize_bbox 只是废弃,跟着索引重建的节奏清理。

2.4 的迁移文档只有三条,比 2.0 那一大批少得多,升级工作量也小,但模板那条属于"一直在用的写法突然被拒",容易在最后关头卡住,要预留时间。

如果升级后建模板报 analyzer 找不到,先确认它是不是本来定义在另一个模板里。这时应该把定义放进当前模板,而不是新建一个同名的公共模板:后者仍然过不去 2.4 的校验,因为它解决不了"模板自身不完整"。

锁内存这件事,ES 侧的 bootstrap.memory_lock 和系统侧的 ulimit -l 少配任何一边都不会生效,具体的系统配置方式以配置文档为准。

参考

本文对照 Elasticsearch v2.4.6 标签的官方文档核对,引文逐字取自原文。撰写时未启动集群、未运行测试。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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