2021 年 Elastic 把 Elasticsearch 与 Kibana 从 Apache 2.0 切到 SSPL 与 Elastic License 双许可,AWS 随即基于最后一个 Apache 2.0 版本 fork 出 OpenSearch。几年过去,两者在版本号、查询语言、安全模块与云托管上已经走出明显差异,「该用哪个」成了架构评审的常见议题。本文从分支历史、功能差距、迁移路径与运维成本四个角度给出可操作的判断依据,而不是停留在许可协议的口水仗上。
1. 分支历史与许可差异
1.1 从 Apache 2.0 到 SSPL
Elasticsearch 7.10 之前是 Apache 2.0,这意味着任何人都可以把它打包成托管服务出售。2021 年 1 月,Elastic 宣布 7.11 起改为 SSPL 与 Elastic License 2.0 双许可:SSPL 要求把服务化运行的完整栈开源,Elastic License 2.0 则限制把产品作为托管服务转售。这一变更的直接后果是云厂商无法继续以原许可提供托管 Elasticsearch。
1.2 OpenSearch 的诞生
AWS 在 2021 年 4 月基于 7.10.2 fork 出 OpenSearch 1.0,同样基于 Apache 2.0 发布,并把 Kibana 的 fork 命名为 OpenSearch Dashboards。2022 年 OpenSearch 2.0 起,它开始引入自己的功能演进,与上游 Elasticsearch 的 API 逐步分化。
1.3 许可的后续变化
2024 年 Elastic 又增加了 AGPLv3 作为可选项,理由是 AGPL 是 OSI 认可的开源许可,便于重新加入开源生态。但此时 fork 已成事实,OpenSearch 的路线不会因此回退。对使用者的现实影响是:自建场景下两个许可都不影响内部使用;做托管服务转售时,SSPL 与 Elastic License 2.0 都有约束,AGPL 相对宽松但仍有网络分发条款。
1.4 对使用者的实际影响
| 使用方式 | Elasticsearch | OpenSearch |
|---|---|---|
| 内部自建 | 无影响 | 无影响 |
| 二次开发后闭源分发 | 受限 | 无影响 |
| 作为托管服务转售 | 受限 | 无影响 |
| 嵌入商业产品 | 需评估 Elastic License | 无影响 |
结论:绝大多数企业内部使用两个都能选;真正被许可卡住的是做 SaaS 或托管服务的厂商。判断标准很简单——只要你的产品形态里有「把搜索能力作为服务卖给第三方」,就必须认真读许可条款。
1.5 社区与厂商反应
fork 发生时,AWS、Logz.io、Aiven 等厂商迅速加入 OpenSearch 阵营,理由是许可变更让它们的产品线失去合法性。另一批以 Elastic 官方云为主的用户则留在原阵营,看重的是功能领先与生态惯性。这场分裂至今没有收敛迹象,反而在两边各自积累了独立的用户群与贡献者。
2. 功能与插件差距
2.1 版本号不再对齐
fork 之后版本号彻底分家。Elasticsearch 走到 8.x 与 9.x,OpenSearch 走到 2.x 与 3.x。两边都保留了大量 7.x 时代的 REST API 形状,但新功能各自为政。看到「版本 2.11」时要先确认是 OpenSearch 还是 Elasticsearch 的旧版本,二者含义完全不同。
2.2 各自独有的能力
| 能力 | Elasticsearch | OpenSearch |
|---|---|---|
| ES | QL 管道查询 | 8.11+ 原生 |
| SQL 接口 | _sql | _plugins/_sql |
| 内置安全模块 | 8.x 基础版免费 | 一直内置且免费 |
| 向量检索 | kNN 原生 + ELSER | k-NN 插件 |
| 可搜索快照 | 原生支持 | 部分支持 |
| ML 异常检测 | 商业版 | 内置免费 |
| 告警 | Watcher(商业) | 内置 Alerting |
| 快照仓库 | S3/GCS/Azure/FS | S3/FS,插件扩展 |
一个常见的误区是「OpenSearch 只是 Elasticsearch 的旧版」。实际上 OpenSearch 在安全、告警、SQL 上把原本的商业功能做成了免费内置,这是它吸引中小团队的核心卖点;而 Elasticsearch 在查询语言(ES|QL)、向量检索与可搜索快照上领先。
2.3 向量检索的路线差异
两边的向量能力都建立在 HNSW 之上,但产品化路径不同。Elasticsearch 把 dense_vector 做成一等字段类型,kNN 检索可以直接嵌入 _search,与 BM25 通过 RRF 融合;OpenSearch 的 k-NN 以插件形式提供,支持 Lucene、Faiss、NMSLIB 三种引擎,参数调优空间更大但配置更繁琐。要做混合检索,Elasticsearch 的开箱体验更好。
2.4 插件与生态
Elasticsearch 8.x 之后不再支持任意第三方插件的自由安装,插件需要签名,生态收敛到官方与少数合作方。OpenSearch 保留了较宽松的插件机制,k-NN、SQL、Anomaly Detection 都以插件形式提供,第三方也能自行扩展。这既是灵活性,也是碎片化风险:插件与内核版本的兼容矩阵需要自己维护。
2.5 兼容层
OpenSearch 提供 Elasticsearch 7.x REST API 的兼容层,_search、_bulk、_cat 等常用端点形状基本一致。客户端方面,官方 Elasticsearch 8.x 客户端不再保证能连 OpenSearch,因为产品检查(X-Elastic-Product 响应头)会拒绝非 Elasticsearch 服务端。反向亦然:OpenSearch 客户端连 Elasticsearch 8.x 也会遇到兼容问题。跨用时要锁住客户端版本,或使用社区兼容客户端。
2.6 支持周期
| 项目 | Elasticsearch | OpenSearch |
|---|---|---|
| 大版本节奏 | 约 1 年 | 约 1 年 |
| 小版本维护 | 最近若干小版本 | 最近若干小版本 |
| 升级兼容 | 8.x 内平滑,跨大版本需评估 | 2.x/3.x 内平滑 |
| 回滚支持 | 不支持降级 | 不支持降级 |
两边都不支持降级,升级前必须先快照、先在测试集群验证。这一点常被忽略,直到线上出问题才发现没有退路。
2.7 分析语言的正面对比
两边都推出了 SQL 之外的管道式分析语言,但语法不同。Elasticsearch 的 ES|QL 用 | 串联:
FROM logs-*
| WHERE level == "ERROR"
| STATS cnt = COUNT(*) BY service
| SORT cnt DESC
OpenSearch 的 PPL(Piped Processing Language)形状类似,但关键字与函数名不同:
source = logs-*
| where level = 'ERROR'
| stats count() by service
| sort - count
两者都支持聚合与排序,但函数库、类型系统与执行引擎完全独立,查询不能互相移植。迁移时这部分是硬改写成本,无法靠兼容层绕过。
3. 迁移路径
3.1 快照仓库
快照迁移最快,但要求源与目标同发行版且版本兼容:
curl -X PUT "localhost:9200/_snapshot/migration_repo" \
-H "Content-Type: application/json" -d'
{
"type": "fs",
"settings": { "location": "/mnt/backup", "compress": true }
}'
创建仓库后先 _snapshot/migration_repo/snap1?wait_for_completion=true 打快照,再在目标集群注册同名仓库并 _restore。跨发行版(ES 到 OS)通常不能用快照直接恢复,因为索引文件格式虽同源,但集群元数据与版本校验会拒绝。
3.2 reindex from remote
跨发行版迁移的首选是远程重建索引,它对版本宽容度更高:
curl -X POST "localhost:9200/_reindex?wait_for_completion=false" \
-H "Content-Type: application/json" -d'
{
"source": {
"remote": {
"host": "http://old-cluster:9200",
"username": "elastic",
"password": "***"
},
"index": "orders",
"size": 1000
},
"dest": { "index": "orders" }
}'
源端要在 elasticsearch.yml 里把目标集群加入 reindex.remote.whitelist,否则连接会被拒绝。任务异步执行,用返回的 task id 轮询 _tasks/<id> 看进度。
3.3 数据重放
对写入链路本来就经过消息队列或 ETL 的系统,最省事的方式是重放:让消费端指向新集群,从最早位点重新消费一遍。这种方式能顺带修正映射、重算派生字段,是长期维护角度最干净的迁移,代价是需要能重新回放全量历史。
3.4 迁移步骤
一次稳妥的迁移按以下顺序推进:
- 盘点:列出索引、映射、别名、ILM 策略、模板、快照策略、角色与用户。
- 建目标:先在目标集群按新映射建索引,必要时修正
text/keyword双字段。 - 灌数据:用
_reindex或重放迁移存量,用双写或 CDC 追增量。 - 对账:对比两边的文档数、字段基数、抽样聚合结果。
- 切流量:改应用连接串或代理,灰度放量。
- 观察:跑一周确认无异常后再下线旧集群。
3.5 兼容性陷阱
迁移中最容易踩的坑集中在查询语法与客户端上:
| 陷阱 | 说明 | 处理 |
|---|---|---|
_sql 路径不同 | OS 是 _plugins/_sql | 改调用路径 |
| 客户端产品检查 | 8.x 客户端拒绝非 ES 服务端 | 锁客户端版本或换客户端 |
| 映射严格性 | 8.x 默认拒绝未定义字段 | 提前补 mapping |
| 模板语法 | 组件模板在旧版 OS 上不可用 | 改写为旧式模板 |
| 分词器差异 | 插件分词器可能缺失 | 换内置或自建 |
3.6 双写与灰度
对不能停机迁移的业务,双写是标配:应用同时写旧集群与新集群,读仍在旧集群。双写要处理两个问题:一是写入失败的一致性(新集群写失败不能让主流程失败,但要落补偿队列);二是双写期间的查询口径(新集群索引尚未追上,读不能切过去)。灰度切换时按租户或按功能逐步放量,配合对比日志验证两边结果一致。
3.7 对账与验证
迁移完成后必须做数据对账,否则很容易在切流量后才发现少数据:
# 文档数对比
curl -s "localhost:9200/orders/_count" | jq .count
curl -s "http://old-cluster:9200/orders/_count" | jq .count
# 抽样聚合对比
curl -s "localhost:9200/orders/_search?size=0" -H "Content-Type: application/json" -d'
{ "aggs": { "by_status": { "terms": { "field": "status" } } } }'
对账要覆盖三个层面:文档总数、关键维度的基数与分布、典型聚合的数值。三项都对得上,才能认为数据搬全了。若数量对不上,优先检查源端是否有写入在迁移期间发生、以及 _reindex 是否因冲突被跳过。
3.8 索引与别名的切换
应用通常通过别名访问索引,切换时只需把别名指向新集群的同名别名。若不能改应用配置,用代理层(如 Nginx、HAProxy)做连接串切换,再灰度放量。切换前把新集群的 _cluster/health 跑到 green,并确认副本数、分片数与旧集群一致,避免容量评估失真。
4. 生态与运维成本
4.1 云托管
Elasticsearch 的托管选项是 Elastic Cloud(官方)与自建云主机;OpenSearch 则是 AWS 的 Amazon OpenSearch Service,以及多家云厂商的兼容服务。如果团队已在 AWS 且希望免运维,OpenSearch Service 的集成度更高;如果依赖 ES|QL、ELSER 等新功能,则只能选 Elastic Cloud 或自建。
4.2 客户端与工具
Elasticsearch 官方客户端覆盖 Java、Python、JavaScript、Go、.NET、PHP、Ruby,版本迭代快。OpenSearch 也维护了同等的客户端矩阵,但更新节奏略慢。周边工具上,Kibana 与 OpenSearch Dashboards 功能相近,但 Kibana 的 Lens、Discover 体验更新更频繁;Beats 系列在 OpenSearch 侧由 Data Prepper 与 Fluent Bit 部分替代。
4.3 安全与合规
Elasticsearch 从 8.0 起把基础安全(TLS、认证、RBAC)免费开放,这在过去是商业版功能。OpenSearch 从一开始就内置安全插件,且免费提供审计日志。需要等保或 SOC2 审计时,两者的审计日志能力都够用,差别在于配置方式:ES 用 xpack.security.audit 系列配置,OS 用 plugins.security.audit。
4.4 人才与社区
Elasticsearch 的文档、教程、社区问答存量远大于 OpenSearch,招人与排错成本更低。OpenSearch 的优势在于完全开源、可自由审计与定制,适合有平台团队、需要深度改造的场景。
4.5 成本对比
| 成本项 | Elasticsearch | OpenSearch |
|---|---|---|
| 软件许可 | 自建免费,部分功能需商业版 | 全功能免费 |
| 托管服务 | Elastic Cloud 按资源计费 | 云厂商按资源计费 |
| 功能缺口 | ES | QL/ELSER 需对应版本 |
| 运维人力 | 生态成熟,成本低 | 插件矩阵需自维护 |
| 迁移成本 | 从 OS 迁回需改查询 | 从 ES 迁出相对平滑 |
5. 选型建议
5.1 决策要点
按优先级回答三个问题:
- 是否要做托管服务转售? 是,选 OpenSearch,许可最干净。
- 是否依赖 ES|QL、ELSER、可搜索快照等新功能? 是,选 Elasticsearch。
- 是否有强平台团队且需要深度定制? 是,OpenSearch 的插件机制更友好。
5.2 场景对照
| 场景 | 推荐 | 理由 |
|---|---|---|
| 日志分析、自建 | 两者皆可 | 功能重叠度高 |
| 电商搜索、要新特性 | Elasticsearch | ES |
| SaaS 产品内嵌搜索 | OpenSearch | 许可无转售约束 |
| 已有 AWS 全家桶 | OpenSearch | 托管集成度高 |
| 强合规、需审计源码 | OpenSearch | 全开源可审计 |
| 已有大量 DSL 与 Kibana 资产 | Elasticsearch | 迁移成本最低 |
5.3 常见误区
选型讨论里反复出现几个错误判断:一是把 OpenSearch 当成「免费版 Elasticsearch」,忽略了它在安全与告警上的独立演进;二是以为 API 兼容就等于客户端兼容,实际会被产品检查挡住;三是低估迁移中的查询改写成本,把「换个连接串」当成全部工作量;四是只看软件许可成本,不算运维与人才成本。
5.4 混合共存的现实
不少团队最终是「两边都用」:新业务用 OpenSearch 图许可省心,老业务留在 Elasticsearch 图资产复用。这种状态的代价是双份运维与双份技能栈,只有在组织确实被许可或云绑定卡住时才值得。若没有硬约束,把栈统一到一边,长期成本一定更低。
5.5 落地检查清单
无论选哪边,上线前把下面几项逐条确认,能规避大部分返工:
| 检查项 | 说明 |
|---|---|
| 许可形态 | 产品是否涉及转售或内嵌分发 |
| 功能依赖 | 是否用到对方独有的查询语言或插件 |
| 客户端版本 | 与服务端的产品检查是否兼容 |
| 映射策略 | 目标集群是否已按新映射建好索引 |
| 迁移工具 | 快照是否可用,reindex 白名单是否配置 |
| 对账方案 | 文档数与聚合口径是否可比 |
| 回滚方案 | 切换后能否快速切回旧集群 |
| 运维技能 | 团队是否具备对应发行版的排错经验 |
6. 总结
| 维度 | 结论 |
|---|---|
| 许可 | 内部使用无差别,转售与内嵌场景 OpenSearch 更宽松 |
| 功能 | ES 在新查询语言与向量检索领先,OS 把商业功能免费化 |
| 兼容 | 7.x API 形状相近,8.x 客户端与 OS 互相不保证兼容 |
| 迁移 | 快照限同发行版,reindex from remote 与重放更通用 |
| 生态 | ES 社区与文档存量更大,OS 可定制性更强 |
| 选型 | 先看许可约束,再看功能依赖,最后看团队与云环境 |
「ES 与 OS 谁更好」没有统一答案,只有约束下的取舍。做决定前把许可、功能依赖、迁移成本三项写成清单逐条打分,比看任何对比文章都可靠。迁移的具体操作可阅读《版本升级与迁移》,集群备份与恢复可阅读《部署运维与备份恢复》。
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。