Elasticsearch 升级7.17 → 8.17 版本差异与升级指南

一、版本概述与升级路径

Elasticsearch 8.0 于 2022 年 2 月正式发布,至 2025 年 1 月 8.17 版本发布,这是一次跨越三年的大版本升级。与 7.x 系列相比,8.x 在安全、性能、查询能力等方面带来了显著变化。本文档旨在为团队内部升级提供全面参考。

1.1 升级路径要求

从 Elasticsearch 7.x 升级到 8.x 必须遵宪以下路径:首先将集群升级到 7.17.x(建议最新的 7.17.28),然后才能继续升级到 8.x。Elastic 官方不支持从 7.16 或更早版本直接跨越升级到 8.0,这一限制主要是为了确保 Upgrade Assistant 能够正常工作。

⚠ 警告: 重要提醒:Elasticsearch 8.x 不支持版本回退(downgrade)。一旦升级到 8.x,无法直接降级回 7.x。如果需要回退,必须使用升级前的快照进行恢复。

1.2 版本对比概览

以下是 Elasticsearch 7.17 与 8.17 在各个维度上的对比概览:

|---------------|------------------------|-----------------------------|
| 对比项 | Elasticsearch 7.17 | Elasticsearch 8.17 |
| Lucene 版本 | Lucene 8.x | Lucene 9.x+ |
| 安全默认 | 默认关闭 | 默认开启(TLS+认证) |
| Java 版本 | Java 11+ | Java 17+ |
| 向量搜索 | script_score(暴力扫描) | dense_vector + HNSW(近似 ANN) |
| Mapping Types | 已弃用 | 已移除 |
| REST API 兼容 | 原生支持 | 需要兼容模式 |
| 快照插件 | 需要单独安装 | S3/GCS/Azure 内置 |
| 查询语言 | Query DSL为主 | Query DSL + ES|QL |

二、核心 Breaking Changes

Elasticsearch 8.0 引入了大量的 Breaking Changes,涵盖 REST API、安全、Mapping、JVM 等多个方面。以下是升级时必须重点关注的变更。

图2:Breaking Changes 分类统计

2.1 REST API 变更

REST API 是受影响最大的部分,8.0 版本对多个端点进行了修改或移除。这些变更大多数在 7.x 中已经被标记为弃用,在 8.x 中则彻底移除。

|--------------|---------------------------------|--------------------------|
| 变更项 | ES 7.x 写法 | ES 8.x 写法 |
| X-Pack 路径 | GET /_xpack/security/user | GET /_security/user |
| Tokenizer 名称 | nGram / edgeNGram | ngram / edge_ngram |
| 聚合排序键 | _term / _time | _key |
| 搜索向量函数 | cosineSimilarity(q, doc'f') | cosineSimilarity(q, 'f') |
| 索引路径 | PUT /idx/type/1 | PUT /idx/_doc/1 |

2.1.1 移除 _xpack 路径

在 8.0 之前,与 X-Pack 相关的 API 端点都包含 _xpack 前缀,如 GET /_xpack/security/user。从 8.0 开始,这些端点不再需要 _xpack 前缀,例如 GET /_security/user。所有包含 _xpack 的请求将返回错误。

2.1.2 移除 include_type_name 参数

Mapping types 在 8.x 中已完全移除。之前用于兼容性过渡的 include_type_name 查询参数已被移除。创建索引、索引模板和 Mapping API 的请求中不再支持此参数。

2.2 安全默认启用与 TLS/SSL

Elasticsearch 8.0 最大的变化之一是安全功能的默认启用。在新安装的 8.x 集群中,X-Pack Security 默认开启,包括:

  • 传输层 TLS/SSL 自动配置(节点间通信加密)
  • HTTP 层 TLS/SSL 默认启用(客户端 API 调用需要 HTTPS)
  • 超级用户 elastic 的密码自动生成(启动时在控制台输出)
  • Kibana 连接需要 enrollment token 进行配置

⚠ 警告: 升级影响:如果你的应用使用 HTTP 协议连接 ES,升级后必须切换到 HTTPS。建议在 7.17 环境中先启用试验性的安全功能,让应用逐步适应认证和加密通信。

2.3 Mapping 与索引变更

Mapping types 在 8.x 中已完全移除。这是一个历时多个大版本的变更,从 6.0 开始逐渐弃用,在 8.0 中彻底移除。

2.3.1 Mapping Types 移除

在 8.x 中,每个索引只能有一个 mapping type,且 API 响应中不再返回 _type 字段。之前使用多个 type 的索引需要在升级前进行重新设计。如果你的应用依赖于 _type 字段,需要将其替换为自定义字段(如 type: keyword)。

2.3.2 索引兼容性要求

Elasticsearch 8.0 启动时会检查所有索引的创建版本。如果存在 6.x 或更早版本创建的索引,节点将无法启动。必须先通过 reindex 将这些索引迁移到新版本。

2.4 系统与 JVM 变更

Elasticsearch 8.0+ 要求 Java 17 或更高版本。此外,JAVA_HOME 环境变量不再被支持,需使用 ES_JAVA_HOME 或内置 JDK。

|-----------|--------------------------|-----------------------------|
| 变更项 | ES 7.x | ES 8.x |
| Java 版本要求 | Java 11+ | Java 17+(必需) |
| JDK 路径配置 | JAVA_HOME | ES_JAVA_HOME(JAVA_HOME 已废除) |
| 操作系统支持 | 支持 CentOS 6、Ubuntu 16.04 | 不再支持 EOL 系统 |
| 启动进程 | SysV init | systemd only |

三、兼容性改造指南

为帮助用户平滑过渡,Elasticsearch 8.x 提供了 REST API 兼容性模式。这不是长期解决方案,但可以在升级过渡期间减少代码改动量。

3.1 客户端兼容性模式

通过在请求头中设置 Accept 和 Content-Type,可以让 Elasticsearch 8.x 以 7.x 的方式响应。兼容性模式不保证完全相同的行为,仅作为过渡手段。

|---------------|------------------------------------------------------|
| 配置项 | 说明 |
| Accept header | application/vnd.elasticsearch+json;compatible-with=7 |
| Content-Type | application/vnd.elasticsearch+json;compatible-with=7 |
| 客户端版本 | 建议 7.17.x 客户端访问 8.x 服务端 |
| 过渡策略 | 先升级服务端,逐步升级客户端 |

// 用 RestHighLevelClientBuilder 构建,并开启兼容模式

RestHighLevelClient esClient = new RestHighLevelClientBuilder(restClient)

.setApiCompatibilityMode(true) // ★ 关键:开启与 ES 8.x 的兼容模式

.build();

3.2 常见代码改造示例

以下是升级过程中常见的代码改造场景:

3.2.1 搜索请求中移除 _type

// ES 7.x 写法(已弃用) GET /my_index/my_type/_search

// ES 8.x 正确写法 GET /my_index/_search

3.2.2 Tokenizer 名称更新

// ES 7.x 写法(已移除)

"tokenizer": "nGram"

"tokenizer": "edgeNGram"

// ES 8.x 正确写法

"tokenizer": "ngram"

"tokenizer": "edge_ngram"

3.2.3 聚合排序键更新

// ES 7.x 写法(已移除)

"order": { "_term": "asc" }

"order": { "_time": "asc" }

// ES 8.x 正确写法

"order": { "_key": "asc" }

四、Elasticsearch 8.x 新特性亮点

除了上述需要关注的 Breaking Changes,Elasticsearch 8.x 也带来了许多令人兴奋的新功能。这些新特性可以为业务带来显著价值。

图3:Elasticsearch 8.x 发布时间线与关键功能

4.1 向量搜索与 kNN

Elasticsearch 8.0 正式引入了基于 dense_vector 字段的近似 kNN 搜索功能,采用 HNSW(Hierarchical Navigable Small World)算法构建向量索引。这使得 ES 能够支持语义搜索、推荐系统、图像搜索等场景。

|------------|--------------|--------------------------|
| 特性 | 精确 kNN | 近似 kNN(8.x+) |
| 算法 | 暴力扫描 | HNSW图 |
| 精度 | 100% | ~95%+(可调) |
| 延迟 | O(N) 高延迟 | O(log N) 低延迟 |
| Mapping 要求 | index: false | index: true + similarity |
| 最大维度 | 2048 | 1024(8.11+ 支持 4096) |
| 适用场景 | 小数据集 | 大规模生产环境 |

4.1.1 kNN 搜索示例

PUT /my_vectors

{ "mappings": { "properties": { "vector": { "type": "dense_vector", "dims": 768, "index": true, "similarity": "cosine" } } } }

POST /my_vectors/_search

{ "knn": { "field": "vector", "query_vector": 0.1, 0.2, ..., "k": 10, "num_candidates": 100 } }

4.2 ES|QL 新查询语言

ES|QL(Elasticsearch Query Language)是 Elastic 在 8.x 中引入的全新查询语言,采用管道符号(|)连接各个查询步骤。它提供了更简洁的语法和更强大的分析能力。

  • 管道语法:FROM | WHERE | STATS | SORT | LIMIT
  • 内置全文搜索函数:MATCH、MATCH_PHRASE、QSTR、KQL
  • 数据增强:ENRICH 命令支持与外部数据源关联
  • JOIN 支持:LOOKUP JOIN 命令实现简单关联查询

4.2.1 ES|QL 查询示例

POST /_query?format=txt { "query": """ FROM logs-* | WHERE @timestamp > NOW() - 1 day | WHERE MATCH(message, "error") | STATS count = COUNT() BY service.name | SORT count DESC | LIMIT 10 """ }

4.3 学习排序 (Learning to Rank)

Learning to Rank(LTR)是 Elasticsearch 8.15+ 引入的预览功能。它允许使用机器学习模型(如 XGBoost)来优化搜索结果的排序。通过分析用户点击行为、历史查询等信号,模型可以学习哪些因素对结果相关性最重要,并自动调整排序策略。

  • 支持 XGBoost 模型直接部署到 ES
  • 可定义多达 48+ 个排序特征
  • 支持实时重排(rescore)和筛选后排序

4.4 其他重要新特性

|---------------|--------|---------------------------------|
| 特性 | 版本 | 说明 |
| LogsDB | 8.9+ | 专为日志数据优化的索引模式,更高压缩率 |
| BBQ 索引 | 8.8+ | 二进制量化向量索引,极大降低内存使用 |
| zstd 压缩 | 8.15+ | 替代 DEFLATE 的更高效压缩算法 |
| RRF 搜索 | 8.5+ | Reciprocal Rank Fusion,多路搜索结果融合 |
| Synonyms API | 8.7+ | 管理同义词的专用 REST API |
| Inference API | 8.13+ | 内置模型推理,支持 ELSER 和向量嵌入 |

五、升级步骤与注意事项

官方推荐的升级方式是滚动升级(Rolling Upgrade),即逐一升级每个节点。这种方式可以在不中断服务的情况下完成版本过渡。

5.1 升级前准备

  • 备份集群:创建完整的快照(snapshot),确保可以恢复
  • 升级到 7.17.x:确保所有节点运行 7.17 最新版本
  • 运行 Upgrade Assistant:在 Kibana 中检查并解决所有严重问题
  • 检查弃用日志:查看 deprecation 日志确认没有潜在问题
  • 检查插件兼容性:确保所有插件都有 8.x 兼容版本

5.2 滚动升级步骤

|--------|---------|------------------------------------------------------------------------|
| 步骤 | 操作 | 说明 |
| 1 | 禁用分片分配 | PUT _cluster/settings { cluster.routing.allocation.enable: primaries } |
| 2 | 执行同步刷新 | POST _flush/synced |
| 3 | 更新插件 | 移除旧版插件,安装 8.x 兼容版本 |
| 4 | 停止并升级节点 | systemctl stop/start elasticsearch |
| 5 | 监控恢复状态 | GET _cluster/health,等待 green 状态 |
| 6 | 重复 4-5 | 对每个节点执行(数据节点 → master 节点) |
| 7 | 恢复分片分配 | PUT _cluster/settings { cluster.routing.allocation.enable: all } |

⚠ 警告: 节点升级顺序建议:先升级数据节点(非主节点),再升级 master-eligible 节点。这是因为新版本数据节点可以加入旧版本 master 节点的集群,但反之可能不行。

5.3 常见问题与解决方案

|----------------|------------------------------------------------------|
| 问题 | 解决方案 |
| Kibana 无法连接 ES | 使用 enrollment token 或手动配置 elastic / kibana_system 用户 |
| 应用报 HTTPS 错误 | 更新客户端配置为 https://,或关闭 xpack.security.http.ssl |
| 索引创建失败 | 检查 mapping 中是否使用了已移除的字段或参数 |
| 插件启动失败 | 确保所有插件均为 8.x 兼容版本 |