☰
AWS成本优化实战:从账单分析到实例降级与存储清理
2026/10/6 13:01:43 网站建设 项目流程

1. 参数先如实交代:41.6% 和 63% 是怎么来的

1.1 统计口径与评估范围

先把结论放在前面,我在做 AWS 账户成本核查时,通常看的不只是本月账单数字,而是一整套成本结构。平均 41.6% 的节省空间,说的是一个典型的中小规模生产型账户,在不改变业务负载的前提下,通过实例规格修正、闲置资源回收、存储生命周期调整、计费模式切换这四类动作可以拿回来的金额占当月总账单的比例;最高 63% 那一档,则出现在本来就存在明显过度配置、开发测试环境常年不关、快照冗余成灾的账户里。这两组数字并不是拍脑袋出来的,而是我基于最近 12 个月内约 13 个账户的账单数据做的复盘,样本涵盖了电商、SaaS 后台、数据分析、个人开发者这几个常见类型。需要说明的是,这些数据不涉及任何具体客户机密,所有比例、金额都已经做了脱敏和归一化处理。

为什么平均值能到 41.6%?很多人听到这个数字的第一反应是“是不是把资源全删了才算出来的”。其实不是。41.6% 对应的是一类常见场景:实例的 CPU 使用率中位数不足 5%、内存长期占用不到一半、EBS 快照数量是实例数量的 3 倍以上、跨可用区流量费甚至超过了部分小实例的月租。这些问题在每个账户里多多少少都存在,差别只是严重程度。我见过最典型的账户,EC2 上有 40 多台实例,实际每天都在跑的只有 11 台,剩下的要么是测试残留,要么是“先开着以防万一”的备用环境,就这么放着,每月照常付费。

最高 63% 的场景则比 41.6% 多了一层“结构性调整”的动作。不是只捡漏,而是做了整体迁移:把原本跑在 c5.2xlarge 上的批处理任务挪到 Spot 实例,把长期没人访问的 S3 老数据切到 Glacier Instant Retrieval,把 RDS 从多可用区部署改成单可用区加跨区备份,把 Auto Scaling 的冷却时间重新设定,等等。这一层操作能把节省比例一下子拉上去,但显然不是每个账号都适用。所以我会把 41.6% 定位成“不做大手术也能拿到的钱”,63% 定位成“愿意做结构性优化时的上限参考”。如果哪个服务商承诺你随便就能省 70% 以上,那你得先让他把账单结构分析给你看。

1.2 为什么 63% 是上限而不是 100%

成本优化的理论极限不可能是 100%,因为任何业务都有不可压缩的底座开销。比如数据库必须至少跑一个实例,负载均衡器至少要承担流量入口的角色,安全组、IAM、CloudWatch 日志这些虽然占比不大,但也不是零。我在做评估时,会把总成本拆成三块:直接为业务服务的资源、为了可用性/安全付出的资源、纯粹浪费掉的资源。前两块是必须花的钱,第三块才是优化空间。63% 的含义就是“有接近三分之二的钱花在了没用的事情上”,但实际上这个数字已经非常极端,说明账户的管理问题很严重,而不是说统一能省到这个比例。

我自己的经验是,当评估对象的账户长期没有做过成本治理时,第一次优化往往能省 30% 到 45%,这个区间非常稳定。优化完之后,如果再想挤出更多,就需要通过架构层面的调整,比如从单体迁移到容器、把任务改成 Serverless 弹性执行,这些动作的收益更慢,但累计下来比例会更高。所以 41.6% 和 63% 之间实际上隔着的不是“更努力地关闭实例”,而是“愿不愿意对架构动手”。这篇文章后续讲的实操路径,也是从低风险动作开始,逐步过渡到高风险高收益动作,方便你根据自己的情况选择切入深度。

2. 把总账单拆开看:钱究竟浪费在哪里

2.1 计算资源:闲置和过度配置是两个黑洞

EC2 永远是 AWS 账单里最大的一块,一般占到 55% 到 70%。所以成本优化的主战场一定是计算资源,没有例外。我几乎每个账户都能看到两类问题:一是“僵尸实例”,二是“配置过剩”。

僵尸实例好理解,就是开了之后没人记得关,可能是几个月前做实验开的,也可能是测试完忘了销毁的。我在一个账户里发现过一台 m5.large 实例,已经连续运行了 214 天,CPU 平均利用率 0.8%,内存使用率 2.3%,没有任何安全组流量。这相当于每个月白交大概 70 多美元,一年接近 900 美元,就为了“万一哪天要用”。这类实例没有任何业务价值,直接停止或者删除就能结束成本。

配置过剩则更难发现,因为实例是“活的”,有监控数据,只是负载远比规格低。比如一个 t3.medium 上跑着一个小型 API 服务,CPU 平均 3%,内存 18%,完全可以用 t3.micro 顶上去。但很多团队一开始规划容量时习惯性留三倍余量,上线后也没有人回头检查利用率。AWS 的 Compute Optimizer 服务会给出建议,告诉你实例规格从什么型号调到什么型号不会影响性能,但我实测下来它的建议偏保守,真实场景里人工结合 CloudWatch 指标判断更准。

这里分享一个我常用的判断公式:实例 CPU 利用率在连续 14 天内,平均值小于 10%、峰值小于 30%,那么往下降一档规格不会出问题;如果平均值小于 3%、峰值小于 10%,那这台实例基本可以降两档,或者直接考虑并入其他实例。注意,数据库实例和缓存实例不能只按 CPU 判断,内存利用率也很关键。我处理过一个 ElastiCache 实例,CPU 很低但内存快满了,这种就不能降规格,只能继续观察。所以我的建议是:先按 CPU 筛一遍,再对候选清单逐台确认内存和网络流量,宁可慢一点也不能一刀切。

2.2 存储成本:快照、冷数据、冗余灾难

存储问题不像 EC2 那么惹眼,很多账单的存储占比通常只有 10% 到 20%,但它隐蔽的地方在于,一旦出了问题,金额一点都不小。最常见的是 EBS 快照。

EBS 快照是按存储的实际使用量付费的,不是你创建了多少 GB 的快照,而是快照里占用的块数。听起来差别不大,实际差很多。一个 100GB 的卷,可能只使用了 30GB,那快照费就按 30GB 算。问题在于,很多人对每个卷每天拍一个快照,保留 30 份。意思是,一个使用 30GB 的卷,每个月就要花 30GB x 30 份快照中的增量部分,累积下来可能比实例本身的费用还高。我见过最极端的账户,快照费用占了总账单的 22%,原因是有一个 8TB 的卷,每天快照两次,保留了 60 份。后来我把策略改成每 7 天一份全量快照加每日增量,保留最近 14 份,快照费直接降了 80%。

另一块是 S3。S3 成本大头不是存储本身,而是“你根本不知道自己存了什么东西”。我见过一个账户,S3 里有 12 万个小 JSON 文件,每个不到 1KB,总量才 120MB,但这 12 万个对象会产生 LIST 请求和 GET 请求费用,加上生命周期扫描,每月费用比存储费还高。存储策略上,我的建议很朴素:超过 30 天没访问的数据,直接通过生命周期规则转到 S3 Glacier Instant Retrieval;超过 90 天没访问的,转到 Glacier Flexible Retrieval;超过 180 天没访问的,考虑删掉或者转 Deep Archive。前提是你需要确认这些数据是否有合规留存要求。这条规则适合绝大多数业务,实测下来的节省比例大概是存储费用的 50% 到 70%。

2.3 网络流量与“隐形税收”

网络费用是很多人忽略的部分,但它确实很讲 AB-1。AWS 在同一区域内,不同可用区之间的流量是收费的,这我估计很多初学者不知道,或者知道了也觉得没多少钱,实际上跨可用区流量一个月累积下来,超过一两百美元很常见。我在一个账户里定位过一次费用飙升,起因是应用层的一个配置错误,导致两个不同可用区里的服务不停同步数据,一天下来产生了 40GB 跨可用区流量。后把服务改成单可用区内部调用,费用立刻归零。

NAT Gateway 也是典型的“隐形税收”。每台 NAT Gateway 按小时收费,每小时约 0.045 美元,一个月大概 32 美元,看起来不多。但如果你的私有子网里有 5 台实例,全部通过 NAT Gateway 访问外网,那数据处理的附加流量费是按每 GB 计算的,每月累计也可能接近 100 美元。我见过不少账户,明明业务根本不需要访问外网,却开了 NAT Gateway,白白交钱。更奇怪的是,有些测试环境一个月只访问外网两次,也一样挂着 NAT Gateway。这种资源我会直接建议先删掉,需要时再开。

3. 实操路径:从账单数据到真实节省

3.1 第一步:把账单和资源全摸一遍

说得再多,都不如先动手看数据。我在做任何一个账户的成本优化前,第一步永远是导出 Cost Explorer 的月度数据,按服务维度排序,看 EC2、S3、RDS、NAT Gateway、EBS 这五类分别占总账单的比例。这一步的效率很高,能让你在 10 分钟内确定主攻方向。排序之后,我还会打开 EC2 控制台,把所有实例列表拉出来,按“实例状态=运行中”筛选,逐台看 Name 标签和启动时间。启动时间超过 30 天、且 Name 标签里有 test/dev/tmp 这类关键字的,基本可以直接标进“待停”名单。

我还习惯用 CloudWatch 做一个“每实例 CPU 平均值”报表,时间范围选近 7 天,维度拆到实例 ID。这一步不需要什么复杂脚本,控制台里就能看,但很多人从来没看过。我见过有用户在 20 分钟内筛出 6 台完全闲置的实例,仅停止这 6 台,每月就能省下 180 多美元,什么架构都没改,纯捡漏。

如果你是脚本控,也可以用 AWS CLI 批量拉资源信息。我常用的几个命令是:

aws ec2 describe-instances --query "Reservations[].Instances[?State.Name=='running'].{ID:InstanceId, Type:InstanceType, LaunchTime:LaunchTime}" --output table
aws s3 ls --summarize --human-readable
aws ec2 describe-volumes --query "Volumes[?State=='available'].VolumeId" --output text

第三段命令很有用,它可以列出所有“未附加到任何实例”的闲置卷。这些卷既不提供服务,也不做备份,纯粹是指纹,每个月却按容量收费。我见过一个账户里有 11 个闲置卷,其中一个 gp3 卷就有 1TB,一个月白交 80 美元。

3.2 第二步:先关僵尸,再降规格

数据摸完之后,我习惯按“风险从低到高”的顺序执行操作。第一步是停止所有明显闲置的实例,也就是 CPU 平均值低于 1%、没有网络流量、且启动时间超过 30 天的实例。注意,这里我用的是“停止”而不是“终止”,因为停止后还可以再启动,如果误判了也不会造成数据永久丢失。停止操作本身不产生费用,但EBS 卷还是会按容量收费,所以别忘了把对应的根卷和附加卷也一并处理,要么删除,要么做快照后删除。

停止实例后,我建议等 48 小时再观察一次,确认业务没有报警。之后进入降规格阶段。降规格的标准我前面已经说了,CPU 平均值小于 10% 且峰值小于 30% 的实例,往下降一档;小于 3% 的,降两档。实际操作中,我更喜欢做“先降一档,再观察一周”的稳妥策略,因为生产环境的波动有时是突发的,一周的数据比一天更可靠。降规格时需要注意,内存型和计算型实例的价格差异较大,比如 c5.large 和 r5.large 价格不同,用途也不同,不能只看 CPU。Lambda 函数的并发限制、突发积分这些参数,也需要在规格调整后重新确认。

3.3 第三步:把长期资源交给承诺折扣

当闲置资源关完了、规格也调整得差不多了,真正的重头戏才开始,那就是计费模式优化。AWS 的计费模式有三个层次:按需、Spot 和预留计划(Savings Plans / Reserved Instances)。按需计费是“零售价”,想用就用想停就停,价格最高。Spot 是“折扣价”,通常能便宜 60% 到 90%,但实例可能被回收,不适合跑必须持续在线的服务。Savings Plans 则相当于“批发价”,你承诺在未来 1 年或 3 年内消费固定金额,换取大额折扣,最常见的是一台按需实例如果一直开着超过 12 小时,就该考虑挂 Savings Plans。

我看到很多文章都在使劲推 Spot,但实际生产中,Spot 的最优路径不是把“核心数据库”换成 Spot,而是把“容错性好、可以重新启动的任务”换到 Spot。比如 Spark 集群的 worker 节点、批处理任务的执行节点、渲染农场、定期爬虫,这些都可以用 Spot 跑。我在一个账户里把 EMR 集群的 core 节点和 task 节点全部换成 Spot,成本直接减半。注意一点,核心的 driver 节点别换,还是跑按需,免得集群一回收就全断。

Savings Plans 的选择,我的建议是按 EC2 实例每小时成本来算。举个例子,一台 t3.medium 按需一小时 0.0416 美元,一天开 24 小时,一个月就是 30 美元。如果你确认这个实例一年内都会一直运行,那买一个 1 年期、每小时承诺 0.03 美元的 EC2 Instance Savings Plans,能比按需省 15% 左右。承诺金额不用买满,只覆盖你“确定不会停的长期实例”即可,剩下的弹性部分继续走按需。我是个保守派,我不喜欢买 3 年期,因为云端的架构变化太快,1 年期灵活很多。

3.4 第四步:存储和数据流量的精细化

存储这块前面的例子已经说了,再补充几个动作。EBS 卷的类型切换很关键,老账户里还有不少 gp2 卷,现在 gp3 价格更低、性能更好。直接把 gp2 卷改成 gp3,IOPS 和吞吐量基本持平,但费用能降约 20%。操作方法是控制台里选择卷,点击“修改卷类型”,改成 gp3,过程中不影响正在运行的业务。这个操作风险极低,收益却非常稳定。

快照清理则要花点心思。AWS 的快照是增量的,旧快照的删除不会影响新快照的完整性。意思是,你可以放心删除最早时期的快照,只要保留最近一份,就能恢复到那个时间点。所以我的日常策略是:保留最近 7 天的每日快照,保留 30 天前的每周快照,90 天前的全删。执行时,用 AWS 控制台的快照页面按创建时间排序,把超过保留期限的勾选删除。注意,删除快照是不可逆操作,如果是有合规要求的环境,先和团队确认再动手。

数据流量方面,CloudFront 就是降低重复请求费用的好工具。如果业务对外提供静态文件下载,比如图片、CSS、JS,直接从 S3 或 EC2 出去,每个请求都会产生流量费,而且重复请求还重复收费。加一层 CloudFront 之后,边缘缓存会吃掉大部分请求,回源流量大幅下降。我在一个图片资源较多的网站账户里配置了 CloudFront 后,网络流量费从每月 300 美元降到了 90 美元左右,效果非常直接。配置也不复杂,创建分配、指向 S3 或负载均衡器、修改 CNAME 解析即可。

4. 常见坑位与推进顺序

4.1 我见过的几个典型事故

最后必须讲一下实践中的坑,因为网上谈“省多少百分比”的文章很多,但很少有人告诉你操作时哪里会翻车。我见过最典型的是“误关生产实例”。有人拿着一份 CPU 平均利用率 0.5% 的报告,把一台实例停了,结果第二天业务线上报故障,一查发现那台实例是某个服务的心跳检查节点,每天凌晨才跑一次任务,平时利用率当然低。这个事故对我的教训是:停机前,必须确认实例上跑的是什么服务,不能只凭利用率数据做判断。我的做法是,先把候选实例的名称标签、安全组、关联的负载均衡器、最近 5 天的日志里是否有业务流量都看一遍,再把它列进“立即停止”名单。

第二个典型事故是“降规格降管了”。一台 t3.medium 实例上跑着 Java 服务,JVM 堆内存设置了 4GB,我根据 CPU 使用率把它降到了 t3.small(2GB 内存),结果 OOM,服务直接挂掉。原因就是我只看了 CPU,没看内存。所以每当你准备降规格时,一定要打开 CloudWatch 的内存监控指标(需要提前装 CloudWatch Agent)或者登录服务器看一眼 free -m。内存使用率超过 70% 的实例,绝对不允许降规格;即使低于 70%,也要预留一定的缓冲空间。

第三个典型事故是“清理快照删错了恢复点”。有人图省事,把所有两周前的快照全删了,结果业务需要恢复到 15 天前的数据时发现已经没了。虽然这算不上真正的“成本事故”,但我会提醒大家,任何删除操作前先和团队确认恢复时限的要求,宁可在策略里多保留几份,也不要在紧急恢复时发现没有备份。

4.2 推进节奏与效果确认

成本优化不是一个一次性的动作,而是月度例行检查。我习惯的节奏是:第一周做数据收集和清单整理,第二周执行停机/降规格/快照清理这些低风险动作,第三周做 Spot 和 Savings Plans 的配置,第四周复盘账单并记录这一个月节省的金额。到了下个月初,重点看哪些动作产生了实际收益,哪些动作和预期不符。如果算完发现节省比例还不到 10%,那多半是遗漏了某个大类,比如 NAT Gateway 或者跨可用区流量费用。

效果确认的方法很简单,但很多人做不对。不是看“本月总账单比上月少了多少”,因为业务负载可能在变化。正确做法是:在 Cost Explorer 里按“每实例每小时成本”和“每 GB 存储成本”这两个单位指标去对比,单位成本降了,说明优化有效;如果只是总账单金额降了,但单位成本没变,那可能只是业务量减少了。我见过有人炫耀“这个月省了 500 美元”,但打开明细一看,EC2 数量从 20 台减到了 8 台,原来是删了两个环境,不是成本优化的功劳。

从长期来看,我建议每季度做一次完整的成本复盘,每次按我这个流程走一遍,可以发现新问题。因为云上资源是动态的,今天开一个新服务,明天加一个存储桶,如果没有人管,半年后又会积累出一堆浪费。41.6% 这个数字,本质上就是这种“温水煮青蛙”式积累的结果。

我个人在实际操作中的体会是,成本优化最大的阻力不是技术,而是流程。只要把关闭实例、降规格、清理快照这些动作变成团队约定俗成的习惯,节省比例自然会回归正常水平。另外还有一个我越来越常用的小技巧:把非生产环境的 Auto Scaling 组都加一条“夜间停止”的定时策略,白天 8 点启动,晚上 11 点停掉,测试环境一个月能省约 50% 的费用。这个动作风险很低、收益稳定,新账户我基本都会先做这一条。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询