Elastic 构建 Elastic Cloud Serverless 的历程

无论数据、使用和性能需求如何,无状态架构均可自动扩展

Blog-extra-cloud-serverless2.jpg

如何将 Elasticsearch 这类有状态、性能关键系统改造为无服务器架构?

在 Elastic,我们重新构想了从存储到编排的一切,以建立一个真正值得客户信赖的无服务器平台。

Elastic Cloud Serverless 是一个完全托管的云原生平台,旨在为开发人员带来 Elastic Stack 的强大功能,而无需承担运营负担。在这篇博客文章中,我们将向您介绍其构建动因、架构设计思路以及在此过程中学到的经验。

为什么选择无服务器架构?

近年来,客户需求发生显著转变。用户不再希望关注基础架构管理的复杂性,例如规模调整、监测和扩展,转而寻求一种无缝体验,使其能够专注于自己的工作负载。这种不断变化的需求推动我们开发出一种解决方案,既能减少运营开销,提供顺畅的 SaaS 体验,又能引入按使用量付费的定价模式。通过消除客户手动配置和维护资源的需求,我们创建的平台既能根据需求动态扩展,又能实现效率最优化。

里程碑

Elastic Cloud Serverless 正在快速扩展以满足客户需求,已于 2024 年 12 月在 AWS、2025 年 4 月在 GCP 和 2025 年 6 月在 Azure 上实现全面上市 (GA)。从那时起,我们已扩展到 AWS 上的四个区域、GCP 上的三个区域和 Azure 上的一个区域,并计划在所有三个云服务提供商 (CSP) 上扩展更多区域。

重新思考架构:从有状态到无状态

Elastic Cloud Hosted (ECH) 最初是作为有状态系统构建的,依靠本地基于 NVMe 的存储或托管磁盘来确保数据持久性。随着 Elastic Cloud 在全球范围内扩展,我们看到了改进架构的机会,以更好地支持运营效率和长期增长。我们的托管方法在分布式环境中管理持久状态被证明是有效的,但在节点替换、维护、确保可用区冗余,以及扩展计算密集型工作负载(如索引和搜索)方面增加了操作复杂性。

我们决定采用无状态方法来改进我们的系统架构。关键的转变是将持久存储从计算节点卸载到云原生对象存储。这带来了多重好处:减少索引所需的基础设施开销,实现搜索/索引分离,消除复制的需要,并通过利用 CSP 的内置冗余机制增强数据持久性。

迁移到对象存储

我们架构的重大转变之一是使用云原生对象存储作为主要数据存储。ECH 旨在将数据存储在本地 NVMe SSD 或托管 SSD 磁盘上。然而,随着数据量的增长,有效扩展存储的挑战也随之增加。然后,我们在 ECH 中引入了可搜索式快照,这使我们能够直接从对象存储中搜索数据,从而显著降低了存储成本,但我们需要更进一步。

一个关键的挑战是确定对象存储是否能够处理高摄取工作负载,同时维护 Elasticsearch 用户期望的性能水平。通过严格的测试和实施,我们已验证对象存储能够满足大规模索引的需求。转向对象存储消除了索引复制的需要,减少了基础设施要求,并通过跨可用区域复制数据提高了耐用性,确保了高可用性和弹性。

下图展示了新的“无状态”架构与现有“ECH”架构的对比:

图表

优化对象存储效率

虽然向对象存储的转型带来了运营和可靠性方面的优势,但也带来了新的挑战:对象存储 API 成本。写入 Elasticsearch 的操作(尤其是事务日志更新和刷新)会直接转化为对象存储 API 调用,其规模可能会迅速扩展且不可预测,尤其是在高摄取或高刷新工作负载下。

为了解决这个问题,我们实施单节点事务日志缓冲机制,在将写入操作刷新到对象存储之前对其进行合并,从而显著降低了写入放大。我们还将刷新操作与对象存储写入操作分离,改为将刷新后的段直接发送到搜索节点,同时推迟对象存储的持久化。该架构优化使刷新相关的对象存储 API 调用降低了两个数量级,且丝毫不影响数据持久性。有关详细信息,请参阅此
博客文章

选择 Kubernetes 进行编排

ECH 使用内部开发的容器编排器,该编排器也为 Elastic Cloud Enterprise (ECE) 提供支持。由于 ECE 的开发始于 Kubernetes (K8s) 出现之前,因此我们面临两个选择:是扩展 ECE 以支持无服务器,还是将 K8s 用于无服务器。随着 K8s 在业界的快速采用及其周边生态系统的不断发展,我们决定在 Elastic Cloud Serverless 中跨 CSP 采用托管的 Kubernetes 服务,这与我们运营和扩展目标相一致。

通过采用 Kubernetes,我们降低了运营复杂性,标准化了 API 以提高可扩展性,并为 Elastic Cloud 的长期创新奠定了基础。Kubernetes 使我们能够专注于更高价值的功能,而不是重新发明容器编排。

CSP 托管与自管型 Kubernetes

在过渡到 Kubernetes 的过程中,我们面临着是自行管理 Kubernetes 集群还是使用 CSP 提供的托管 Kubernetes 服务的抉择。不同 CSP 的 Kubernetes 实现方式差异很大,但为了加快部署进度并降低运营开销,我们选择了由 CSP 在 AWS、GCP 和 Azure 上托管的 Kubernetes 服务。这种方法使我们能够专注于构建应用程序和采用行业最佳实践,而无需处理 Kubernetes 集群管理的复杂性。

我们的关键要求包括:能够跨多个 CSP 一致地配置和管理 Kubernetes 集群;用于管理计算、存储和数据库的与云无关的 API;以及经济高效的简化操作。此外,通过选择由 CSP 托管的 Kubernetes,我们能够为
Crossplane 等开源项目上游做出贡献,改善整个 Kubernetes 生态系统,同时受益于其不断发展的功能。

网络挑战与 Cilium 的选择

在每个 Kubernetes 集群中运行数万个 pod 需要一个与云无关的网络解决方案,该解决方案提供高性能和最小延迟,并支持高级安全策略。我们选择了 Cilium,这是一种现代的基于 eBPF 的解决方案,以满足这些需求。我们最初计划在所有 CSP 中实施统一的自管型 Cilium 解决方案。然而,由于云实施的差异,我们采用了混合方法,在可用的情况下使用 CSP 原生的 Cilium 解决方案,同时在 AWS 上保持自管理部署。这种灵活性确保我们能够满足性能和安全需求,而无需不必要的复杂性。

入站流量

对于入站流量,我们选择调整并继续使用我们现有的、经过实战检验的 ECH 代理。评估不仅仅是我们是否可以用现成的解决方案替换代理,而是我们是否应该这样做。

虽然标准反向代理可以提供基本功能,但它缺乏 ECH 代理已处理的差异化功能。我们需要构建入站流量过滤器的扩展、支持 AWS PrivateLink 和 Google Cloud Private Service Connect,以及符合 FIPS 标准的 TLS 终止。现有的代理也已经通过所有相关的合规性审计和渗透测试。

采用新的解决方案需要付出巨大的努力,却不会给客户带来额外的价值。我们对 Kubernetes 代理的调整主要涉及更新服务终端的分发方式,而核心、经过充分测试的功能则保持不变。这种方法提供了几个优势:

  • 它确保客户可见的行为在 ECH 和 Kubernetes 之间保持一致。

  • 团队可以使用熟悉且易于理解的代码库更高效地工作,尤其是在实现需要脚本或扩展现有解决方案的新功能时。

  • 我们可以使用单一代码库来推进 ECH 和 Kubernetes 平台;因此,一个环境中的改进会转化为另一个环境中的改进。

  • 支持团队可以利用他们现有的知识,减少新平台的学习曲线。

Kubernetes 配置层

在为 Elastic Cloud Serverless 选择 Kubernetes 之后,我们选择了 Crossplane 作为基础架构管理工具。Crossplane 是一个开源项目,它扩展了 Kubernetes API,支持使用 Kubernetes 原生工具和实践来配置和管理云基础架构和服务。它允许用户在 Kubernetes 集群内跨多个 CSP 配置、管理和编排云资源。这是通过利用自定义资源定义 (CRD) 来定义云资源和控制器,以协调 Kubernetes 清单中指定的理想状态与多个 CSP 中云资源的实际状态来实现的。通过利用 Kubernetes 的声明式配置和控制机制,它提供了一种一致且可扩展的方式来以代码形式管理基础架构。

Crossplane 可使用与服务部署相同的工具和方法来管理和配置基础架构。这涉及利用 Kubernetes 资源、一致的 GitOps 架构和统一的可观测性工具。此外,开发人员可以建立一个完整的基于 Kubernetes 的开发环境,包括其外围基础设施,从而模拟生产环境。只需创建 Kubernetes 资源即可实现这一点,因为这两个环境都是由相同的底层代码生成的。

管理基础架构

管理基础架构

统一层是面向运营商的管理层,为服务所有者提供 Kubernetes CRD 来管理其 Kubernetes 集群。统一层可以定义包括 CSP、区域和类型在内的参数(详见下一节)。它丰富了运营商的请求,并将其转发至管理层。

管理层充当统一层与 CSP API 之间的代理,将来自统一层的请求转换为 CSP 资源请求,并将状态报告回统一层。

在我们当前的设置中,我们为每个环境中的每个 CSP 维护两个管理 Kubernetes 集群。这种双集群方法主要有两个关键目的:首先,它使我们能够有效地解决 Crossplane 可能出现的潜在可扩展性问题;其次,更重要的是,它使我们能够将其中一个集群用作金丝雀环境。这种金丝雀部署策略有助于分阶段推出我们的更改,从每个环境的较小且受控的子集开始,从而最大限度地降低风险。

工作负载层 包含所有运行用户交互应用程序(如 Elasticsearch、Kibana、MIS 等)的 Kubernetes 工作负载集群。

管理云容量:避免“容量不足”错误

人们普遍认为云容量是无限的,但实际上,CSP 会施加限制,这可能会导致“容量不足”错误。如果某个实例类型不可用,我们必须不断重试或切换到其他实例类型。

为了在 Elastic Cloud Serverless 中缓解这个问题,我们实施了
基于优先级的容量池,允许工作负载在必要时迁移以使用新的/其他容量池。此外,我们还投资了主动容量规划,在需求激增之前预留计算资源。这些机制在确保高可用性的同时,优化了资源利用率。

保持最新状态

Kubernetes 集群升级非常耗时。为了简化这一流程,我们采用了完全自动化的端到端流程,仅当问题无法自动解决时才需要人工干预。内部测试完成并且新的 Kubernetes 版本获得批准后,我们会进行集中配置。然后,自动化系统会以可控的并发度和特定的顺序启动每个集群的控制平面升级。随后,自定义 Kubernetes 控制器会执行蓝绿部署来升级节点池。即使在此过程中客户的 Pod 迁移到不同的 Kubernetes 节点,项目的可用性和性能也不会受到影响。

架构弹性

我们采用基于单元的架构,这使我们能够提供可扩展性且具有弹性的服务。每个 Kubernetes 集群及其外围基础架构都部署在单独的 CSP 帐户中,以便在不受 CSP 限制影响的情况下进行适当扩展,并提供最大的安全性和隔离性。每个工作负载都是独立的单元,管理系统的特定方面。这些单元独立运行,从而实现隔离式扩展和管理。这种模块化设计最大限度地减少了故障的影响范围,并促进了有针对性的扩展,避免对整个系统造成影响。为了进一步降低问题带来的潜在影响,我们对应用程序和底层基础架构都采用了金丝雀部署。

控制平面与数据平面:推送模型

推送模型

控制平面是面向用户的管理层。我们为用户提供 UI 和 API,用于管理他们的 Elastic Cloud Serverless 项目。在这里,用户可以创建新项目、控制项目的访问权限,并获取其项目概述。

数据平面是支持 Elastic Cloud Serverless 项目的基础架构层,用户在使用其项目时可与其交互。

我们面临的一个基本设计决策是全局控制平面应如何与数据平面中的 Kubernetes 集群进行通信。我们探索了两种模型:

  • 推送模型:控制平面主动将配置推送到区域 Kubernetes 集群。

  • 拉取模型:区域 Kubernetes 集群定期从控制平面获取配置。

在评估了两种方法后,我们选择了推送模型,因为它简单、具有单向数据流,并在故障期间能够独立于控制平面运行 Kubernetes 集群。这种模型使我们能够维护简单的调度逻辑,同时减少运营开销和故障恢复的复杂性。

自动扩展:超越水平扩展和垂直扩展

为了提供真正的无服务器体验,我们需要一种智能自动扩展机制,能够根据工作负载需求动态调整资源。我们的旅程始于基本的横向扩展,但我们很快意识到,不同的服务有其独特的扩展需求。有些需要额外的计算资源,而有些则需要更高的内存分配。

我们通过构建自定义自动扩展控制器来改进我们的方法,这些控制器可以分析实时的、特定于工作负载的指标,从而实现既响应迅速又节省资源的动态扩展。因此,我们可以无缝扩展 Elasticsearch 的索引层和搜索层操作,而无需为 Elasticsearch 过度配置。此策略支持使用多维 Pod 自动扩缩,允许工作负载基于 CPU、内存以及自定义的工作负载生成指标进行水平和垂直扩展。

对于我们的 Elasticsearch 工作负载,我们使用特定于无服务器的 Elasticsearch API,该 API 可返回有关集群的某些关键指标。其工作原理如下:推荐器为给定层级推荐所需的计算资源(副本、内存和 CPU)以及存储。然后,映射器会将这些建议转换为适用于容器的具体计算和存储配置。为了防止快速的扩展波动,稳定器会过滤这些建议。然后,限制器开始发挥作用,强制执行最低和最高资源限制。在考虑一些可选限制策略后,限制器的输出用于修补 Kubernetes 部署。

智能扩展策略

这种分层的智能扩展策略可确保跨不同工作负载的性能和效率,这是迈向真正无服务器平台的重要一步。

Elastic Cloud Serverless 引入了专为搜索层量身定制的精细化自动扩展功能,利用增强数据窗口、搜索功率设置和搜索负载指标(包括线程池负载和队列负载)等输入。这些信号共同定义了基线配置,并根据客户搜索使用模式触发动态扩展决策。要深入了解搜索层自动扩展,请阅读此
博客文章。如需了解有关索引层自动扩展工作原理的更多信息,请查看此博客文章

构建灵活的定价模型

无服务器计算的一个关键原则是将成本与实际使用情况相结合。我们想要一个简单、灵活、透明的定价模式。在评估了各种方法之后,我们设计了一个模型来平衡核心解决方案中的不同工作负载:

  • Observability 和 Security:根据提取和保留的数据收费,采用分级定价

  • Elasticsearch (Search):基于虚拟计算单位的定价,包括采集、搜索、机器学习和数据保留

这种方法为客户提供按使用量付费的定价模式,从而提供更大的灵活性和成本可预测性。

为了实施这种定价模式(在开发阶段经历了多次迭代),我们深知需要一个可扩展且灵活的架构。最终,我们构建了一个支持分布式所有权模型的管道,由不同的团队负责端到端流程的不同组件。下面,我们将描述该管道的两个主要部分:通过
使用管道进行计量用量收集,以及通过计费管道进行计费计算。

使用管道

Elasticsearch 和 Kibana 等面向用户的组件将计量的使用数据发送到在每个工作负载集群中运行的 usage-api 服务。该服务会对数据进行一些增强处理,然后将其放入一个队列中。随后,usage-shipper 服务会从队列中拉取这些数据,并将其转发到对象存储中。这种解耦的架构是必要的,以便在跨区域和 CSP 传输数据时使管道具有弹性,因为我们优先考虑数据的送达而不是延迟。一旦数据到达对象存储,即可以只读方式提供给其他进程,以便进一步的转换或聚合(如用于计费或分析)。

使用管道

计费管道

使用记录存入对象存储后,计费管道就会提取数据,并将其转换为 ECU(Elastic 消费单位,即不限货币的计费单位)数量,以供计费。基本流程如下:

计费管道

转换过程会使用对象存储中的计量使用记录,并将其转换为可实际计费的记录。此过程包括单位转换(计量应用程序可能以字节为单位测量存储,但我们可能以 GB 为单位计费)、过滤掉不计费的使用来源、将记录映射到特定产品(这涉及解析使用记录中的元数据,以便将使用情况与具有唯一价格的特定解决方案产品联系起来),并将这些数据发送到由我们的计费引擎查询的 Elasticsearch 集群。此转换阶段的目的是提供一个集中的位置,用于存放将通用的计量使用记录转换为特定产品的数量的逻辑,以便这些数量能够直接用于定价。这使我们能够将这些专门的逻辑排除在计量应用程序和计费引擎之外,我们希望保持其简单性并与产品无关。

计费引擎随后对这些可计费使用记录进行计价,此时这些记录已包含一个标识符,可映射至价格数据库中的对应产品。该流程至少需要汇总给定时间段内的使用量,并将该数量乘以产品价格,以此计算 ECU。在某些情况下,系统还需根据月度累计使用量将使用量划分为不同层级,并映射至各自独立定价的产品等级。为了在上游流程出现延迟时仍能确保记录无遗漏,系统会在使用量数据到达可计费数据存储时进行计费,但实际价格仍按发生时间执行(以避免对“延迟”到达的使用量应用错误的价格)。这给我们的计费流程提供了“自我修复”功能。

最后,一旦计算出 ECU,我们会评估任何附加成本(例如支持费用),然后将其纳入计费计算,最终生成发票(由我们或我们的云市场合作伙伴发送)。该流程的最后环节并非 Serverless 特有的新流程,而是由托管产品相同的计费系统进行处理的。

要点

构建一个为多个 CSP 提供相似功能的基础架构平台是一项复杂的挑战。平衡可靠性、可扩展性和成本效益需要持续的迭代和权衡。Kubernetes 的实现在不同的云服务提供商之间差异很大,要确保在它们之间获得一致的体验,需要进行大量的测试和定制。

此外,采用无服务器架构不仅是一项技术变革,更是一次文化转型。这要求团队从被动式故障处理转向主动式系统优化,并通过优先实现自动化来降低运营负担。我们在探索过程中深刻认识到,构建成功的无服务器平台,既取决于架构决策,也取决于培养一种拥抱持续创新和改进的心态。

展望未来

无服务器领域的成功取决于提供卓越的客户体验、主动优化运营以及持续平衡可靠性、可扩展性和成本效益。展望未来,我们的重点仍然是在 Elastic Cloud Serverless 上为客户构建新功能,使无服务器成为每个人运行 Elasticsearch 的最佳场所。

搜索、安全和可观测性的未来已到来,丝毫不会影响速度、扩展或成本。体验 Elastic Cloud Serverless 和 Search AI Lake,利用您的数据解锁新的机会。了解有关无服务器的可能性的更多信息,或立即开始您的免费试用

本文中描述的任何功能或功能性的发布和时间均由 Elastic 自行决定。当前尚未发布的任何功能或功能性可能无法按时提供或根本无法提供。

在本博文中,我们可能使用或提到了第三方生成式 AI 工具,这些工具由其各自所有者拥有和运营。Elastic 对第三方工具没有任何控制权,对其内容、操作或使用不承担任何责任或义务,对您使用此类工具可能造成的任何损失或损害也不承担任何责任或义务。请谨慎使用 AI 工具处理个人、敏感或机密信息。您提交的任何数据都可能用于 AI 训练或其他目的。Elastic 不保证您所提供信息的安全性或保密性。在使用任何生成式 AI 工具之前,您都应自行熟悉其隐私惯例和使用条款。 

Elastic、Elasticsearch 及相关标志是 Elasticsearch N.V. 在美国和其他国家/地区的商标、徽标或注册商标。所有其他公司和产品名称均为其相应所有者的商标、徽标或注册商标。