亚马逊AWS官方博客

从 Intel 到 AWS Graviton 4:一次降本增效的技术迁移实践

关于美餐

美餐创立于 2011 年,专注为企业客户提供员工餐、活动餐、团队建设和商务宴请等服务,是全国领先的企业级餐饮综合解决方案运营商。服务覆盖全国各大城市,目前拥有企业级客户4000余家,日服务人数在百万级别。

背景:为什么要迁移到 Graviton

2023年,在云成本日益成为企业关注焦点的时候,降本增效成为了一个主流话题。AWS 的 CTO Werner Vogels 博士在 re:Invent 2024 上提出了 “The Frugal Architect” 的理念,在不牺牲性能的前提下优化基础设施成本。恰逢此时 AWS Graviton 2 系列处理器已在中国区推出,经过初步调研,我们发现:

  • Graviton 实例相比同规格 Intel 实例价格降低约 20%
  • 性能测试显示 Graviton 采用的 ARM 架构在我们的工作负载下表现更优
    基于这些发现,我们决定将基础设施从 Intel 芯片迁移到 Graviton 系列芯片上。时至今日,我们已经从 Graviton 2 一直迭代到最新的 Graviton 4。

关于 ARM CPU 架构

Graviton 采用的是 ARM 的芯片架构,即便对 ARM 不熟悉,也一定使用过智能手机,那就一定用过 ARM 芯片。市面上大多数移动设备搭载的都是 ARM 的芯片,这和 ARM 芯片的特性有关: 低功耗, 低散热以及较高性能。在云计算领域,我们更需要的是: 成本敏感,高并发和性能稳定。低功耗和低散热节约的是数据中心的电费和散热成本,这就将 ARM 的能效优势转化为成本优势。
在性能方面,传统的 Intel 芯片虽然单核极限性能很强,主频很高,但我们都或多或少能感觉到在极限负载的情况下,Intel 芯片的性能是难以保证的,这也就意味着通常我们在部署应用的时候,不敢将 CPU 打满,而是保留一部分(甚至会留到 40% ~ 50%)余量。这是因为 Intel 芯片往往通过超线程技术让一个物理核心同时运行两个线程,再加上 Intel 采用的 CISC 指令可能会跨多个时钟周期,在资源竞争时就会导致性能急剧下降。
而 Graviton 的优势包括但不限于:

  • 每个物理核心都是独立的,避免了高负载下的性能下降
  • RISC 简单指令、不追求极限的主频,有效减少散热和能耗
  • 与 Nitro 架构深度集成,拥有更高的 I/O 带宽

在相同预算下,Graviton 以更低的成本提供相同甚至更加稳定的性能,这就意味着 Graviton 芯片是非常适合云上负载的。

迁移准备:性能验证与兼容性测试

在大规模迁移之前,我们通过一系列测试,来验证 Graviton 芯片是否能满足我们的性能和兼容性要求。彼时仅 Graviton 2 在中国区可用,后续我们又补充上了 Graviton 3 和 Graviton 4 的测试。
鉴于篇幅有限,这里我们仅引用最具代表性的数据。

Go Web Server 性能测试

由于我们公司的大部分应用都使用 Go 语言开发,且 Go 在 1.10 版本以后对 ARM CPU 有比较好的支持,因此我们优先测试了 Go 语言的工作负载,涵盖不同资源配置和并发场景:

高负载场景(2 vCPU, 200 connections

芯片 请求数 RPS 平均延迟 p99 延迟
Intel 3,521,897 29.48k 8.06ms 45.26ms
Graviton2 4,245,043 35.54k 6.04ms 37.42ms
Graviton3 5,450,469 45.64k 3.27ms 24.54ms
Graviton4 6,823,793 57.1k 1.21ms 7.08ms

中等负载场景(1 vCPU, 100 connections

芯片 请求数 RPS 平均延迟 p99 延迟
Intel 1,761,056 29.3k 15.70ms 71.54ms
Graviton2 2,018,862 33.6k 12.92ms 63.55ms
Graviton3 2,721,580 45.3k 12.59ms 61.69ms
Graviton4 3,396,023 56.6k 9.90ms 53.37ms

低负载场景(2 vCPU, 10 connections

芯片 RPS p99 延迟
Intel 23.19k 9.44ms
Graviton2 25.62k 803μs
Graviton3 26.84k 826μs
Graviton4 27.95k 1.91ms

可以轻松看出:

  • Graviton 处理器在高负载、多核心场景下优势更明显
  • 即使在低负载场景,Graviton 也提供了更好的稳定性(更低的 p99 延迟)
  • Graviton 4 相比 Graviton 2/3 有显著的性能提升

RDS

在 RDS 中我们也观察到了类似的性能提升。这里不再罗列更多数据,仅将总结放在这里:

  • Graviton 在各种负载场景下都表现出更优的性能
  • 在高负载下优势更加明显
  • 相同性能下 CPU 使用率更低,意味着更大的性能余量

当然,需要注意的是,关系型数据库的性能提升(约10%)没有 Web Server 这种工作负载性能提升(大于20%)的那么明显,这是由于关系型数据库的特性导致————在超压测试的场景下,瓶颈往往不是 CPU 的性能,而是磁盘的 I/O。

在兼容性方面,无论是 MySQL 还是 PostgreSQL,无论是标准实例还是 Aurora,迁移到 Graviton 后均运行稳定,未遇到任何兼容性问题。

DevOps 支持:构建完整的 ARM64 工作流

在验证了 Graviton 的性能和兼容性以后,便可以开始着手准备迁移工作。为了能更好推进迁移的过程,则需要前期大量的准备工作。

应用负载迁移

由于公司内部存在大量的微服务,对每个服务进行改造是一件虽然不复杂,但比较耗时的工作。在本章节中我们也将着重介绍应用负载迁移的流程。

  1. 构建 ARM64 镜像

首先,我们需要明确的一点是整个迁移过程并不是一蹴而就的,我们一定会在整个迁移的周期内同时存在两种不同 CPU 架构的实例,因此我们需要为应用构建支持多架构的容器镜像,
以确保在迁移的过程中可以对比验证,随时回滚。

从 Docker 编译的角度,我们可以用以下例子说明如何编译多架构的镜像。

FROM golang:1.24 AS builder

WORKDIR /app
COPY . .
RUN go build -o app

FROM alpine:latest
COPY --from=builder /app/app /app
CMD ["/app"]

实际上,这个 Docker 的文件和普通的文件并没有太大的区别,关键点在于 golang:1.24 和 alpine:latest 这两个镜像自身就支持多种不同的 CPU 架构,那么利用该基础镜像进行编译的应用,在 AMD64 实例上便可以编译出 AMD64 的镜像,在 ARM64 实例上编译出的就是 ARM64 的镜像。

对于本地编译来说,新版本的 Docker 集成了 QUME 模拟,我们还可以使用 docker buildx --platform linux/arm64,linux/amd64 指令同时编译多种架构的镜像。

  1. CI/CD 流程改造

我们的 CI/CD 流程也需要支持同时构建 AMD64 和 ARM64 两种架构的镜像。这点由于各个公司使用的工具/技术不同,在实现上可能有较大的区别。
本文仅介绍一些核心的步骤。

假设单一 CPU 架构的 CI 简化流程是:

  • test
  • build
  • upload image

现在为了编译多CPU架构的镜像,流程则会变为:

  • test
  • build amd64
  • upload amd64
  • build arm64
  • upload arm64

没有使用前面提到的 docker buildx 的主要目的是为了避免 QUME 模拟带来的兼容性/性能问题,我推荐使用独立的 CPU 架构实例来编译对应的镜像,这就会产生一个问题:

  • AMD64 镜像名: meican/app:v0.1.0-amd64
  • ARM64 镜像名: meican/app:v0.1.0-arm64

由于不同的镜像名在使用上会带来一定的困扰,不利于混合部署,我们希望像主流的镜像一样提供一个统一的名字,这样无论在 Kubernetes 上还是 AWS ECS 上都可以用同一个镜像名适配不同的工作负载。

可以完成这个目的的工具非常多,这里我们仅举一个例子,例如 manifest-tool 可以将多个不同名字的镜像合并为同一个:

manifest-tool push from-args
      --platforms linux/amd64,linux/arm64
      --template meican/app:$v0.1.0-ARCH
      --tags v0.1.0
      --target meican/app:v0.1.0

于是我们就创建了一个 Image Index,该 Image 为索引类型,在使用该镜像时可以自动通过本地的环境,获取对应 CPU 架构的镜像。

RDS 升级流程

RDS 从 Intel 迁移到 Graviton 的过程可以有很多种方式,这里我仅介绍一种停机时间可控的步骤:

  1. 创建读副本:创建 Graviton 实例的读副本
  2. 验证兼容性:确保应用在新的实例上正常运行
  3. 切换主库:将读副本提升为写节点
  4. 确认结果:通过应用和数据库监控、日志确认正常运行

在主从切换的过程中,应用会经历短暂的(秒级)连接超时或中断,只要在应用侧处理好重试/重连就不会有什么影响。

这个迁移的步骤和 AWS RDS Blue/Green Deployment 的流程类似,因此我们也可以选择托管的服务完成这项操作。
如果我们对停机时间的要求非常严苛的话,还可以在 RDS 实例前部署一个 RDS Proxy 的托管服务,由该 Proxy 负责流量的分发,基本上可以做到 Zero Downtime。

推进团队迁移:策略与技巧

由于降本增效的基调在公司团队内部成为了一项共识,而对于 Graviton 的迁移在初期被证明是有效可行的,因此获得了公司管理层的全面支持,这是项目成功的关键因素之一。
同时,为了降低研发团队的迁移成本,我们在基础设施方面还提前准备了各种工具,让研发的同事可以极为方便的实现迁移工作,包括但不限于

  • 统一的脚手架工具,统一的应用项目结构和基础库
  • 可复用、模块化的 CI/CD 流程
  • 开箱即用的监控告警

我们必须承认的一点是,迁移的工作会对应用的开发者带来额外的负担,幸而我的研发同事们都十分崇尚极客文化,在宣传了 Graviton 处理器的优势以后,绝大多数人都非常积极的尝试 Graviton 的迁移,这也缩短了很多迁移的周期。

成果与经验教训

资源优化:最大化 CPU 利用率

迁移到 Graviton 后,我们进一步优化了资源利用策略。

精细化资源管理与部署策略

首先我们对所有的工作负载做了一次分级,这对应了 “The Frugal Architect” 中涉及到的 “Cost Aware Architectures”:

  • Tier1: 最高优先级的核心工作负载,如订单、支付等。这类应用对延迟敏感,且可用性要求高
  • Tier2: 中等优先级,可以容忍短暂的延迟升高,并对可用性的要求低于 Tier1
  • Tier3: 最低优先级,例如大数据跑批的任务,延迟不敏感,允许失败后重试

分级完成后,我们就可以对工作负载的资源进行精细化管理,例如:

  • Tier1 负载享有最高资源优先级,不允许超卖,全部部署在 Reserved 实例上
  • Tier2 允许一定的超卖,保证留有至少一份副本在 Reserved 实例上,在流量高峰期弹性扩容的副本部署至 Spot 实例上
  • Tier3 允许大比例超卖,全部部署在 Spot 实例上

时至今日, Kubernetes (1.33) Pod In-Place Resizing 还没有在 EKS 上 GA,因此我们实现了类似 DRA (Dynamic Resource Allocation) 的功能,基于上述的划分,并结合应用的历史数据,进行预测和资源分配,从而达成了:

  • 在 Kubernetes 节点中部署 90% CPU 负载
  • 设置 5 倍的自动扩缩容阈值

这也使得我们通过对应用申请资源的动态调整以及弹性扩缩容策略,在提升了 20% CPU 利用率的同时,节省了约 30% 的实例数量,并且达成了约 25% 的 Spot 实例利用率。

经验教训:过度优化的代价

在追求极致的资源利用率的过程中,我们也遇到了一系列的问题,在这里分享两个简单的案例供各位参考:

  1. 在大数据领域,通常我们需要比较多的内存资源用来进行计算,但由于网卡是通过 DMA 直接访问内存的,该资源的使用我们无法通过普通手段限制。因此当网络流量突增的时候,我们观察到了因为系统级别的内存溢出,导致节点上 kubelet 无法正常响应,节点出现 NotReady 状态,最终该节点上的 pod 失联,访问超时,通过人工介入才恢复。
  2. 一部分旧版本的语言,例如 Java 7 / Python 2.7 / Go < 1.10 对 ARM64 指令集的支持存在一部分问题,因此在迁移后观察到性能不增反降,需要优先确保使用的语言版本的兼容性。

迁移成果

经过半年的努力,我们取得了显著的成果。
覆盖率

  • 90% 的 EC2 已迁移到 Graviton,其他托管服务如 RDS / OpenSearch / MSK 等全部使用 Graviton 处理器
  • 仅有个别特殊服务(如需要特定 x86 指令集的应用或历史应用)仍保留在 AMD64 实例上
    成本节省
    结合 Graviton 迁移和 Spot 实例策略:
  • RDS 成本降低 50%
  • EC2 成本降低 70%

后续迭代

彼时我们使用的是 Graviton 2 处理器,后来 AWS 陆续在中国区推出了 Graviton 3 和 Graviton 4。由于后续的 Graviton 版本均是相同的 CPU 架构,因此在完成了对 ARM64 的改造后,我们只需要逐步更新机型,即可轻松且稳定的获得成本及性能上的提升。期待新一代的Graviton带来更大的性能提升。

总结

从 Intel 到 AWS Graviton 的迁移是一次成功的降本增效实践。通过充分的性能验证、完善的 DevOps 支持、规范化的迁移流程,我们不仅实现了显著的成本节省,还获得了更好的性能表现。

对于正在考虑 Graviton 架构迁移的团队,我们的经验表明,在云原生环境下,Graviton 不仅是一个成本优化方案,更是一个性能提升方案。只要做好充分准备,迁移过程可以非常平滑,收益也会非常显著。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

黄岩硕

美餐首席研发工程师,主要负责云原生平台的建设及基础设施的运维。具有先进的开发理念,持续提升产品质量和开发效率。目标是打造业内领先的技术实力,为用户提供卓越的体验。

杨昌君

亚马逊云科技解决方案架构师,曾服务于某 IDC&云服务提供商。拥有数据中心,互联网,云计算技术等经验,2021 年加入 AWS,负责零售,快消,餐饮等行业,多年服务于零售快消行业。擅长 CI/CD,Devops 等技术。

AWS 架构师中心: 云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用