考古|ES 5.0 换了仓库域名和 jvm.options,节点能启动不代表参数生效了

简介: 5.0 的安装包层面有几处影响运维习惯的变更:apt/yum 仓库从 packages.elasti……

5.0 的安装包层面有几处影响运维习惯的变更:apt/yum 仓库从 packages.elastic.co 换成 artifacts.elastic.co;默认 JVM 参数加了 -XX:+AlwaysPreTouch,启动变慢、常驻内存提前升高;JVM 参数集中到 jvm.options,同时废掉 ES_HEAP_SIZE 等一批环境变量。迁移文档同一节还有几处容易被漏掉的:Windows 服务要自己配线程栈、/bin/bash 成为硬依赖、通过系统属性设置任何设置的做法被删、遇到 OOM 等致命错误时 JVM 会自行退出。

说明

实测环境:本地放的 Elasticsearch 5.6.16 官方 tar 包(JDK 8,堆内存按各次实验指定),每次用 bin/elasticsearch 拉起进程并给独立的 path.data 与端口(9420 / 9421 / 9422),堆大小读的是 _nodes/stats/jvm 里的 heap_max_in_bytes。图 4、图 5 出自这个实例。

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

01-packaging

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

apt/yum 仓库地址变了

5.0 迁移文档(migrate_5_0/packaging.asciidoc 第 4–9 行):

The repository for apt and yum packages has changed from https://packages.elastic.co to https://artifacts.elastic.co/.

这是纯基础设施变更,但自动化部署脚本、Dockerfile、配置管理里写死旧域名的都会失效。升级前先把源地址全量替换。文档没有提到 GPG key,是否需要一并更新以实际的仓库配置说明为准。

02-elasticsearch.in

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

systemd 下 stdout 进 journal

这一条的标题就写了 "since Elasticsearch 2.2.0"(第 11–20 行):

In previous versions of Elasticsearch, the default logging configuration routed standard output to /dev/null and standard error to the journal. However, there are often critical error messages at startup that are logged to standard output rather than standard error and these error messages would be lost to the nether. The default has changed to now route standard output to the journal and standard error to inherit this setting (these are the defaults for systemd). These settings can be modified by editing the elasticsearch.service file.

所以改动发生在 2.2,5.0 文档里重列了一次。启动阶段的关键错误常常打在 stdout 上,改之前这些信息会丢。需要调整就编辑 elasticsearch.service。

-XX:+AlwaysPreTouch

In Elasticsearch 5.0.0 the -XX:+AlwaysPreTouch flag has been added to the JVM startup options. This option touches all memory pages used by the JVM heap during initialization of the HotSpot VM to reduce the chance of having to commit a memory page during GC time. This will increase the startup time of Elasticsearch as well as increasing the initial resident memory usage of the Java process.

AlwaysPreTouch 的作用是:JVM 初始化时就把整个堆对应的内存页都摸一遍,让操作系统完成实际的物理页分配。否则这些页是在运行过程中、尤其是 GC 时按需提交的,一次提交一批页会带来停顿抖动。

文档给出的代价有两个(和上面引文一致):启动时间变长、Java 进程初始常驻内存升高。具体到"多少秒、多少 GB"取决于堆大小,官方没有给数字,本文也不编。

对监控和容量判断的影响:

  • 靠 RSS 判断"内存够不够"的监控会看到基线跳升,告警阈值要调;
  • 容器环境里如果 memory limit 卡得紧,RSS 提前升高之后,留给堆外内存(Lucene 用)的空间就少了,启动阶段被 OOM kill 的风险上升;
  • 反过来,它也避免了"平时看着内存够、GC 时突然申请不到页"的意外。

不想要这个行为,可以在 jvm.options 里显式关掉(-XX:-AlwaysPreTouch),代价是接受 GC 时的页提交抖动。

03-settings.asciidoc

图 3:官方页面 settings.asciidoc(v5.6.16 标签)。来源:GitHub elastic/elasticsearch v5.6.16 docs/reference/migration/migrate_5_0/settings.asciidoc

JVM 参数集中到 jvm.options

Arguments to the Java Virtual Machine have been centralized and moved to a new configuration file jvm.options. This centralization allows for simpler end-user management of JVM options.

This migration removes all previous mechanisms of setting JVM options via the environment variables ES_MIN_MEM, ES_HEAP_SIZE, ES_HEAP_NEWSIZE, ES_DIRECT_SIZE, ES_USE_IPV4, ES_GC_OPTS, ES_GC_LOG_FILE, and JAVA_OPTS.

默认位置:tar 或 zip 发行版在 config/jvm.options,deb 或 rpm 包在 /etc/elasticsearch/jvm.options(第 42–45 行)。可以用环境变量 ES_JVM_OPTIONS 指定别的位置。

2.4.6 的启动脚本能看出旧机制的样貌(elasticsearch.in.sh 第 15–35 行):ES_HEAP_SIZE 非空时同时赋给 ES_MIN_MEM 和 ES_MAX_MEM,再由 ES_MIN_MEM、ES_MAX_MEM、可选的 ES_HEAP_NEWSIZE 拼出 -Xms、-Xmx、-Xmn。5.0 起这套都没有了。

迁移对照:

旧做法 5.0 做法
ES_HEAP_SIZE=8g jvm.options 里 -Xms8g / -Xmx8g
ES_HEAP_NEWSIZE=1g -Xmn1g
ES_DIRECT_SIZE=... -XX:MaxDirectMemorySize=...
ES_GC_OPTS=... 直接写 GC 相关参数
ES_GC_LOG_FILE=... -Xloggc:...(按版本语法)
JAVA_OPTS=... 写进 jvm.options

实际影响:靠环境变量注入堆大小的部署方式(尤其是容器镜像、systemd 的 Environment=)升级 5.0 后静默失效——环境变量不再被读取,JVM 用回 jvm.options 里的默认值。表现很隐蔽:节点起来了,但堆大小不是你配的它。

同一节里另外四条

这几条在迁移文档里篇幅很短,但都会卡住部署(第 47–82 行):

  • Windows 服务的线程栈:以前安装脚本会配线程栈大小(服务守护进程需要),5.0 因为 JVM 配置都移到了 jvm.options,安装脚本不再配,装 Windows 服务时要自己配;
  • /bin/bash 成为硬依赖:5.0.0 起启动脚本和 plugin 命令需要 bash,/bin/bash 是 RPM 和 Debian 包的硬依赖;
  • 环境变量占位符:以前可以用 ${env.ENV_VAR_NAME} 和 ${ENV_VAR_NAME} 两种方式引用环境变量,前者被删;另外以前能通过 JVM 系统属性设置任何设置,这个做法也被删了;
  • 致命错误时退出 JVM:以前遇到 OOM 等致命错误不退出,5.x 起会退出,理由是这种错误发生后 JVM 状态已经不可信。我的建议是按文档说的把服务配成崩溃后自动重启,别指望节点自己扛过去。

最后一条对运维方式的影响比较大:以前节点可能带着坏状态继续跑,现在会退出,服务管理器要能自动拉起。

这几条为什么容易被漏

5.0 打包层的改动有一个共同点:它们都不让 ES 起不来。

  • 仓库地址变了 → 只影响下一次 apt-get install,现有集群照常跑;
  • AlwaysPreTouch → 启动慢一点、RSS 高一点,能起来;
  • JVM 参数集中 → 环境变量静默失效,节点用默认值也能起来。

第三条最危险。它不报错、不告警,只是"你配的堆大小没生效"。表现可能是:

  • 节点起来了,但 GET _nodes/jvm 里 heap_max 不是你设的值;
  • 堆比预期小,运行一段时间后才出现 GC 频繁、查询变慢;
  • 或者堆比预期大,在容器里直接被 OOM kill。

排查时很少有人想到"环境变量没被读了",因为配置里明明写了(写的是环境变量那套)。升级脚本里加一步启动后核对:

curl -s 'localhost:9200/_nodes/jvm' | python3 -c "
import sys, json
d = json.load(sys.stdin)
for nid, n in d['nodes'].items():
    print(n['name'], 'heap_max =', n['jvm']['mem']['heap_max_in_bytes'] / 1024**3, 'GB')
"

把实际值和期望值对一遍,几秒钟就能做完。

容器环境要核对的几项

  • 堆配置方式:容器里常用环境变量传堆大小。5.0 之后这些变量不再被读取(ES_JVM_OPTIONS 只用于指定 jvm.options 文件的位置)。改成把 jvm.options 挂进镜像(ConfigMap 或 volume),或者用 ES_JVM_OPTIONS 指向挂载的文件,启动后再核对一次;
  • memory limit:AlwaysPreTouch 让 RSS 在启动阶段就接近堆上限,limit 要留出堆之外的空间,尤其是 Lucene 的堆外内存。具体留多少取决于索引量和查询负载,本文不给一个通用倍数;
  • 致命错误后的重启策略:5.x 起遇到致命错误 JVM 会退出,容器的重启策略要能自动拉起;
  • 基础镜像要有 bash:5.0.0 起 /bin/bash 是硬依赖,用精简镜像的要确认。

升级检查清单

  1. 替换 apt/yum 源地址;
  2. 检查容器和 systemd 里有没有用被废弃的环境变量设堆大小,一律迁移到 jvm.options;
  3. 启动后核对 _nodes/jvm 的 heap_max 是否符合预期;
  4. 调整内存监控基线(RSS 因 AlwaysPreTouch 跳升),确认容器 memory limit 有足够余量;
  5. 把启动超时时间放宽,滚动升级的等待窗口跟着调;
  6. Windows 服务补上线程栈配置;确认基础镜像有 /bin/bash;
  7. ${env.VAR} 占位符改成 ${VAR};确认没有依赖 JVM 系统属性传设置;
  8. 服务管理器配成致命错误后自动重启。

在 5.6.16 上跑一遍

标题里那句「节点能启动不代表参数生效了」,在这批改动里有两种截然相反的表现:有的写法直接拒绝启动,有的写法静默失效。下面三种都是 5.6.16 tar 包直接拉起来拍的。

04-old-env-vars-refused

图 4:上:ES_HEAP_SIZE=512m 起节点,进程直接退出,提示改用 jvm.options 或 ES_JAVA_OPTS,还把该写什么一并打出来。中:-Des.cluster.name=sysprop 报 ERROR: D is not a recognized option,命令行压根不认这种写法。下:默认的 jvm.options 第 43 行就是 -XX:+AlwaysPreTouch。本地实测输出。

ES_HEAP_SIZE=512m elasticsearch-5.6.16/bin/elasticsearch -Epath.data=/tmp/es508a
# Use jvm.options or ES_JAVA_OPTS to configure the JVM
# ES_HEAP_SIZE=512m: set -Xms512m and -Xmx512m in jvm.options or add "-Xms512m -Xmx512m" to ES_JAVA_OPTS

elasticsearch-5.6.16/bin/elasticsearch -Des.cluster.name=sysprop -Epath.data=/tmp/es508b
# ERROR: D is not a recognized option

grep -n 'AlwaysPreTouch' elasticsearch-5.6.16/config/jvm.options
# 43:-XX:+AlwaysPreTouch

05-es-java-opts-works

图 5:换成 ES_JAVA_OPTS='-Xms512m -Xmx512m',节点正常起来,_nodes/stats/jvm 里 heap_max_in_bytes 是 518979584(约 495MB,JVM 报出来的比 -Xmx512m 略少)。本地实测输出。

ES_JAVA_OPTS='-Xms512m -Xmx512m' elasticsearch-5.6.16/bin/elasticsearch \
  -Ehttp.port=9422 -Epath.data=/tmp/es508c &
curl -s 'http://localhost:9422/_nodes/stats/jvm' | jq -r '.nodes[] | .jvm.mem.heap_max_in_bytes'
# 518979584

两条对比说明一件事:ES_HEAP_SIZE 这类老变量在 5.x 上的表现是启动阶段就拦下,并给出替代写法——属于好排查的那类。真正麻烦的是另一类:节点起来了、日志里没报错,但参数没进去。判断办法只有一个,就是启动后读运行时的实际值:堆看 _nodes/stats/jvm 里的 heap_max_in_bytes,别看启动脚本里写了什么。图 5 那次如果不查,光看进程起来了也会以为设对了。

我的默认做法是把「起一次 + 读实际值」当成升级的固定动作,两类失效都能覆盖:拒绝启动的在启动日志里,静默失效的在 _nodes/stats 里。

边界:

  • 图 4 三段和图 5 都出自 5.6.16 的 tar 包,每次给独立的 path.data 和端口,跑完进程退出;
  • AlwaysPreTouch 只验到「默认 jvm.options 里有这一行」,它对启动时间、RSS 的实际影响没有量化——官方也没给数字;
  • apt/yum 仓库域名、systemd 走 journal、Windows 服务线程栈这几条都是部署环境层面的,本机不在这些环境里,没有实测。

写在最后

打包层的改动容易在"能启动"这件事上蒙混过关:节点起来了就以为没事,但 jvm.options 可能是旧文件、堆参数可能没生效。

我的默认做法是升级后用 jcmd <pid> VM.flags 看一次实际生效的 JVM 参数,再和 _nodes/jvm 里的 heap_max 对一遍。沿用旧配置文件是升级里最常见的情况,这两个核对动作成本很低。

参考

本文对照 Elasticsearch v5.6.16 标签的官方文档核对,引文逐字取自原文。图 4、图 5 是本地 5.6.16 tar 包实例的实测输出;AlwaysPreTouch 的实际影响与部署环境层面的几条未实测,正文中已标注。

目录
相关文章
|
13天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)
5314 40
|
13天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
4721 54
|
7天前
|
Linux 开发工具 iOS开发
2026最新codex下载安装保姆级使用教程(下载+安装+登录+使用,含所有历史版本)
本文详解OpenAI Codex国内快速上手指南:提供Win/macOS/Linux全平台免安装包、npm/Homebrew等多方式安装、账号/API Key双登录、简体中文切换,覆盖下载、安装、汉化、使用及高频避坑(如微软商店失败、npm超时等),10分钟即可跑通。
1882 5
|
14天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
2236 7
|
5天前
|
人工智能 安全 API
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(dsh)是DeepSeek AI于2026年开源的轻量级Agent运行框架,基于Cordis内核,践行“一切皆插件”理念。支持Web/桌面双端,开箱即用;内置多模型接入、丰富插件生态(超3.5万),适配编程、办公、创作等场景。(239字)
1193 0
|
8天前
|
云安全 人工智能 安全
|
1天前
|
云安全 人工智能 安全
|
7天前
|
人工智能 并行计算 调度
本地 AI 一键部署工具 LocModel:Windows 端集成画图、视频生成、Agent 的开源模型运行方案
LocModel 是专为 Windows 设计的一站式本地 AI 工具,支持零配置启动、自动硬件检测、GGUF 模型一键加载、文生图/视频生成及 Agent 自动化任务。适配 8G 显存,内置显存分片调度,轻松实现 AI 漫剧批量创作与离线大模型调用。(239 字)