当前位置: 首页 > news >正文

升级 Elasticsearch 到新的 AWS Java SDK

作者:来自 Elastic David Turner, Dianna Hohensee

Elasticsearch 使用官方的 AWS Java SDK 集成了某些 Amazon Web Services (AWS) 功能。这些集成最早在近 10 年前发布的 Elasticsearch 2.0 版本中引入。

最近,AWS 宣布 Elasticsearch 过去十年使用的 SDK 将于 2025 年 12 月 31 日停止支持。作为 Elastic,我们有责任只依赖受支持的组件,因此必须在此日期前迁移到新版 AWS Java SDK v2。

新版 SDK 不是旧版的直接替代品,且在多方面表现不同。本文讲述了迁移到新版 SDK 的项目过程,我们采取的步骤以保护 Elasticsearch 用户免受行为差异影响,以及你可能需要采取的适应新版 SDK 的操作。

所有 8.19 小版本系列的 Elasticsearch 版本,以及 9.1.0 及之后的版本,都将使用新的 AWS Java SDK v2。

什么是 SDK?

像 AWS 这样的网络服务提供商通过其暴露的应用程序编程接口(API)来描述其服务。API 文档说明如何构造请求以实现特定结果,以及如何解释对这些请求的响应(无论成功与否)。例如,AWS S3 的 API 文档详细说明了如何构造上传对象的请求,然后再下载该对象。

大多数服务提供商还为常用编程语言提供 SDK,允许开发者在不需要了解 API 低层细节的情况下与服务交互。每个 SDK 实现了与服务交互所需的通用行为和约定,并将其适配到开发者所用的编程环境中。开发者无需构造请求和解释响应,只需调用 SDK 中的函数,具体实现细节由网络服务提供商的 API 专家处理。

AWS 提供了一个 Java SDK,封装了 AWS 各服务如何协同工作及其运行环境的知识,并将所有功能映射到 Java 开发者熟悉的特性上。例如,它会自动将 API 错误转换为 Java 异常,简化编程体验。此外,运行在 AWS EC2 实例上的进程,使用 AWS Java SDK 与 AWS S3 交互时,默认可以自动确定大部分配置,简化最终用户体验。

自 2.0.0 版本以来,Elasticsearch 在两个主要方面使用 AWS Java SDK:在 AWS S3 中存储和检索快照,以及使用 EC2 的 DescribeInstances API发现其他集群成员。

为什么 AWS 创建了第二个 Java SDK?

AWS 最初的 Java SDK 于 2010 年 3 月发布,Elasticsearch 第一个使用该 SDK 的版本是在 2015 年 10 月发布。随着时间推移,发现原来 SDKv1 的一些设计决策经不起时间考验,且无法修复而不破坏现有客户端代码的兼容性。2018 年 11 月,AWS 发布了全新的 Java SDK,称为 SDKv2。新 SDK 更灵活,支持异步请求执行、可选的 HTTP 客户端,以及跨 SDK 客户端实例共享 HTTP 客户端以提高连接重用效率。新 SDK 也更严格,例如要求开发者明确指定服务所在的 AWS 区域,而 SDKv1 在未指定时会尽量猜测区域。

当时,Elasticsearch 开发团队评估了 SDKv2,认为新功能对 Elasticsearch 的需求并不关键,且部分与 SDKv1 的差异会导致用户可见的破坏性变更,因此为了用户利益决定继续使用 SDKv1。

为什么 Elasticsearch 要迁移到 SDKv2?

这一切在 2024 年改变,亚马逊宣布 SDKv1 支持将在 2025 年 12 月 31 日终止。虽然该 SDK 在此后仍可使用,但若发现关键漏洞或安全问题将不会再发布新版本。

安全和质量对 Elastic 非常重要,我们不能接受依赖的 SDK 出现未修补的安全漏洞或其他缺陷的风险,因此决定尽管迁移会带来用户可见的影响,仍必须迁移到 SDKv2。

不幸的是,SDKv1 的终止支持是在 Elasticsearch 8.x 系列发布过程中宣布的,该系列会维护至 2027 年中。我们面临艰难选择:要么在 8.x 小版本中切换到 SDKv2,可能带来破坏性变更;要么在 8.x 继续用 SDKv1,9.x 系列才用 SDKv2,这意味着在 SDKv1 维护结束后 8.x 会有 18 个月风险期,需依赖绕过新发现的安全问题。

我们找到了一条折中方案,允许在 8.x 小版本中迁移到 SDKv2,同时引入兼容性逻辑来处理行为差异。得益于兼容逻辑,大部分用户升级到基于 SDKv2 的 Elasticsearch 版本时无需采取任何操作。

Elasticsearch 是如何迁移到 SDKv2 的?

看似迁移很简单:移除对 SDKv1 的依赖,添加 SDKv2 依赖,修复编译错误,确认测试通过,即完成。

但事情从来不那么简单。Elasticsearch 有大量详尽测试代码与 AWS 服务交互。部分测试紧密依赖 SDKv1 的特性,而 SDKv2 并无对应部分。例如,我们通过检查 com.amazonaws.ClientConfiguration 对象确认客户端配置,但 SDKv2 没有对应对象。还有验证 SDK 指标采集的测试,而 SDKv2 的指标收集机制大不相同。

我们可以一边改生产代码一边修测试,但这样风险是可能同时引入生产和测试代码缺陷,导致测试掩盖生产问题。为降低风险,我们先重构测试,使其尽量独立于 SDK 版本。

我们已有部分测试通过模拟 AWS API 的 HTTP 服务器运行,验证 Elasticsearch 在 AWS API 失败、超时或限流时的行为。这些端到端测试独立于 SDK 版本,因为两个 SDK 发送相同网络请求。

我们重点将更多测试转为此类端到端测试,减少对 SDK 内部实现的依赖。即便如此,我们还是发现 SDKv1 与 SDKv2 行为间存在不一致,测试工具需做相应调整。

接着我们开启长期功能分支,团队可并行工作,避免影响生产代码。

当所有代码编译并通过测试后,我们回顾了改动,提取了几部分与 SDK 无关的改动先合入主代码库,减小升级改动范围,专注升级到 SDKv2。

开发过程中,我们持续追踪 SDKv1 与 SDKv2 间不兼容之处。端到端测试特别有效地发现这些问题,减少了测试改动也让我们有信心没有遗漏。合入后内部发布,一下游系统发现 SDKv2 更严格的另一个场景,测试未覆盖,我们快速修复和缓解了该问题。

发生了什么变化?

我们预计大多数集群升级到基于 SDKv2 的版本后,因 Elasticsearch 添加了兼容机制,不需要修改配置就能继续正常工作。

虽然你可能不需要立即调整配置,我们也修改了一些关于如何配置 Elasticsearch 集群的最佳实践建议,特别是关于 s3.client.${CLIENT_NAME}.region、s3.client.${CLIENT_NAME}.endpoint 和 s3.client.${CLIENT_NAME}.protocol 设置。未来版本可能会强制要求这些配置。以下部分介绍升级到基于 SDKv2 的 Elasticsearch 后你可能需要注意的区别。

区域自动检测

AWS 分为 30 多个独立区域。客户端通常向特定区域的 HTTPS 端点发送 API 请求,请求中包含依赖区域名的认证签名。

SDKv1 通过环境和配置的端点地址,使用启发式方法自动选择合适的区域名。SDKv2 去除了大部分启发式,要求调用代码明确指定区域。

作为迁移的一部分,Elasticsearch 引入了类似 SDKv1 的启发式方法,所以升级集群时一般不必调整配置来指定区域。特别是使用 AWS S3 存储快照时,Elasticsearch 会继续从指定的 S3 端点启发式判断区域(至少对于本文撰写时已知的所有区域)。

不过我们建议你为每个 S3 客户端配置 s3.client.${CLIENT_NAME}.region,而不是依赖启发式。新启发式可能与 SDKv1 不完全相同,遇到差异时需要明确配置正确的区域。

如果你使用 s3 仓库类型将快照存储在自己的 S3 兼容存储中,存储管理员会告诉你正确的区域名,许多此类存储会使用 us-east-1 作为区域名。

IMDSv1 支持

AWS EC2 实例可通过实例元数据服务(Instance Metadata Service - IMDS)访问自身元数据,包括实例所在区域和可用区信息,以及绑定的 IAM 角色凭证。

IMDS 有两个协议版本:IMDSv1 和更安全的 IMDSv2。SDKv2 不支持 IMDSv1,因此新版 Elasticsearch 只使用 IMDSv2。所有 EC2 实例均支持 IMDSv2,所以在 AWS 基础设施上运行不会有问题。但如果你在其他环境运行 Elasticsearch 并使用兼容 EC2 IMDS 的独立 IMDS,必须确保其支持 IMDSv2。

协议选择

SDKv1 允许你设置类似 ”hostname.domain.com” 或 ”hostname.domain.com:port” 的端点地址,然后单独选择使用不安全的 HTTP 还是安全的 HTTPS 协议,Elasticsearch 旧版本通过 discovery.ec2.protocol 和 s3.client.${CLIENT_NAME}.protocol 设置暴露了该选项。

SDKv2 要求端点地址为完整的绝对 URL,必须以 http:// 或 https:// 开头。作为临时兼容措施,Elasticsearch 仍根据 s3.client.${CLIENT_NAME}.protocol 设置(默认 HTTPS)为裸 S3 端点加前缀。但该行为已弃用,下一个主版本将强制 S3 端点必须是以 http:// 或 https:// 开头的绝对 URL。

系统属性移除

SDKv1 可能读取 aws.secretKey 和 com.amazonaws.sdk.ec2MetadataServiceEndpointOverride 这两个系统属性,SDKv2 不支持。Elasticsearch 安装中很少会设置这些属性,提及它们仅为完整性。

功能移除

SDKv2 不允许控制重试时的限流策略,s3.client.${CLIENT_NAME}.use_throttle_retries 设置被弃用且无效。生产集群中极少使用该设置。SDKv2 默认应用 AWS 推荐的限流策略。

SDKv2 要求使用 V4 签名算法,不支持更旧算法,s3.client.${CLIENT_NAME}.signer_override 设置被弃用且无效,生产集群中也极少使用。

SDKv2 不支持用于 S3 对象的 log-delivery-write 预设 ACL。该 ACL 仅适用于桶,不适用于对象,即使旧版 Elasticsearch 用 SDKv1 也无法生效,极少有人使用该 ACL。

指标报告

Elasticsearch 使用 SDK 内建功能收集对 S3 端点的 API 调用指标,这些指标主要用于内部,有时在部分 API 中可见。SDKv1 将部分 4xx 状态码响应视为未收到响应,SDKv2 则与其他错误响应同等计数,可能导致指标上出现细微差异。

STS 端点选择

SDKv1 可使用区域端点或全局 https://sts.amazonaws.com 端点获取短期会话凭证,SDKv2 仅使用区域端点。

其他差异

AWS SDK 文档列出了许多 SDKv1 和 SDKv2 的其他差异。本文未提及的差异均已由 Elasticsearch 处理,对最终用户不相关。但鉴于两 SDK 差异众多及 Elasticsearch 运行环境多样,升级时可能需要调整部分配置。

立即升级

Elasticsearch 8.19.x 及 9.1.0 及以后版本使用新版 AWS Java SDK v2。请在 2025 年底前升级到这些版本,避免继续使用已停止支持的旧版 SDKv1。

请注意新版 SDK 存在一些行为差异,某些特殊情况下可能需要小幅调整配置。升级前务必先升级测试集群并验证正常,再升级生产集群。

本文中描述的任何功能或特性发布及时间安排均由 Elastic 全权决定。当前不可用的功能可能不会按时或根本不会发布。

原文:Upgrading Elasticsearch to a new AWS Java SDK | Elastic Blog

http://www.lryc.cn/news/610570.html

相关文章:

  • iouring系统调用及示例
  • 学习游戏制作记录(将各种属性应用于战斗以及实体的死亡)8.5
  • 从循环嵌套到拓扑编排:LangGraph如何重构Agent工作流
  • 面向对象的七大设计原则
  • 【2025WACV-目标检测方向】
  • 目标检测、分割的数据增强策略
  • 智慧社区物业管理平台登录流程全解析:从验证码到JWT认证
  • 分布式网关技术 + BGP EVPN,解锁真正的无缝漫游
  • Java 异步编程工具类 CompletableFuture 详细介绍
  • CodeRush AI 助手进驻 Visual Studio:AiGen/AiFind 亮相(四)
  • 自然语言翻译--seq2seq
  • JavaWeb(苍穹外卖)--学习笔记17(Websocket)
  • 【题解】P3172 [CQOI2015] 选数(倍数莫反做法)
  • Spring-rabbit使用实战六
  • 智慧会所:科技赋能,开启休闲新体验
  • 计算机算术5-整形除法
  • 代码训练营DAY53 第十一章:图论part04
  • bpf系统调用及示例
  • K8S 性能瓶颈排查
  • CVE-2017-8291源码分析与漏洞复现(PIL远程命令执行漏洞)
  • 软件测试中,pytest 框架如何运行上传失败的测试用例?
  • docker国内镜像源列表
  • 软件测试中,pytest 如何运行多个文件或整个目录?
  • Python入门Day15:面向对象进阶(类变量,继承,封装,多态)
  • springboot + maven 使用资源占位符实现动态加载配置文件
  • Modstart 请求出现 Access to XMLHttpRequest at ‘xx‘
  • imx6ull-驱动开发篇9——设备树下的 LED 驱动实验
  • ubuntu的压缩工具zip的安装和使用
  • 【C++】类和对象1
  • 力扣106:从中序与后序遍历序列构造二叉树