分布式系统成本优化与容量治理

分布式系统成本优化与容量治理:从成本结构与单位成本指标讲起,剖析容量水位与超卖、弹性伸缩的快扩慢缩与混部隔离、实例选型与请求级降本、存储分层与数据生命周期、跨区流量与 CDN 回源治理,并给出 FinOps 成本归属标签、预算与异常增长告警及常见踩坑清单

分布式系统建成之后,账单会成为第二个「性能问题」:它同样会随规模非线性增长,同样在事故前没人注意,同样需要指标、预算与治理流程。区别在于性能问题会以超时和报错的形式主动找你,而成本问题只会安静地出现在月度账单上。

成本治理的难点不是「不知道能省」,而是不知道该省哪里、省了会不会影响稳定性、省下来的钱算谁的。本文按「成本结构 -> 单位成本指标 -> 计算/存储/网络三条主线 -> 组织流程」的顺序,给出一套可执行的治理方法。

一句话:成本优化的第一原则是先建立单位成本指标(每单/每请求/每用户的成本),否则所有优化都是盲目的。

1. 成本从哪里来

1.1 成本结构

类别典型占比主要驱动
计算40% ~ 60%实例数量、规格、使用率
存储15% ~ 30%数据量、副本数、存储类型
网络10% ~ 25%跨区流量、出口流量、CDN 回源
托管服务10% ~ 30%数据库、消息队列、可观测性
许可与商业软件视情况商业数据库、监控平台

这张表的作用是排序优先级:如果计算占 60%,花大力气优化网络出口流量就是舍本逐末。多数团队的第一个动作应该是拉出账单按维度(服务、环境、可用区)拆分,而不是直接开始调参数。

1.2 单位成本指标

绝对成本没有意义——业务增长 50% 成本增长 30% 其实是优化,成本不变业务萎缩 20% 反而是恶化。因此必须建立单位成本指标:

单位成本 = 月度总成本 / 业务量指标

常见口径:
  电商   -> 每笔订单成本(cost per order)
  社交   -> 每 DAU 成本(cost per DAU)
  API    -> 每百万请求成本(cost per 1M requests)
  存储   -> 每 TB 月成本(cost per TB-month)
  推理   -> 每千 token 成本(cost per 1K tokens)
# 单位成本看板的核心计算
def unit_cost(total_cost, business_volume):
    if business_volume == 0:
        return float("inf")          # 业务量为 0 时单位成本无意义,需单独告警
    return total_cost / business_volume

# 判断优化是否有效:看单位成本的趋势,而不是绝对成本
# 单位成本下降 = 规模效应生效;单位成本上升 = 存在非线性膨胀

单位成本上升通常指向三类问题:数据膨胀(存储随业务量超线性增长)、N+1 放大(一次业务操作触发多次内部调用)、僵尸资源(无人使用的实例与索引)。这三类是成本治理的主要战场。

2. 容量治理

2.1 容量水位

容量治理的第一件事是给所有资源定水位线,而不是让资源自由增长:

资源目标水位告警阈值说明
CPU(在线服务)30% ~ 50%70%太低是浪费,太高无突发余量
内存(在线服务)50% ~ 70%85%需留 GC 与突发空间
数据库连接池40% ~ 60%80%超过 80% 时排队延迟陡增
磁盘使用率< 70%85%超过 85% 写入性能下降
消息队列积压接近 0持续增长积压即消费能力不足

CPU 长期低于 30% 是明确的浪费信号,通常意味着实例规格过大或副本数过多。但要注意:在线服务的低水位可能是刻意的突发余量,压缩前必须先确认流量模型(是否有明显峰谷)。

2.2 弹性伸缩

弹性伸缩的收益取决于流量模型与缩容速度:

伸缩三要素
  1. 指标:CPU / QPS / 队列深度(选与负载线性相关的那个)
  2. 阈值与冷却:扩容要快(1 分钟内),缩容要慢(10~30 分钟)
  3. 边界:min 副本数保证基线可用,max 副本数防失控

常见错误
  - 用 CPU 做指标但服务是 IO 密集 -> CPU 不涨,永不扩容
  - 缩容冷却太短 -> 抖动式扩缩,反复创建销毁
  - max 设置过大 -> 一次流量异常拉起大量实例,账单暴增

缩容比扩容难:缩容太快会把还没处理完的请求掐断,缩容太慢则夜间低峰期白付钱。实践做法是给缩容加「延迟窗口」——只有当指标持续低于阈值 15 分钟以上才缩,并优先缩最新创建的实例。

2.3 混部与资源隔离

混部(Colocation)把在线服务与离线任务部署在同一批机器上,用离线任务填满在线服务的空闲资源,理论上可把整体利用率从 20% 提到 50% 以上。代价是隔离复杂度:

隔离维度手段风险
CPUcgroup 权重 + 绑核离线任务抢占导致在线 P99 抖动
内存cgroup 上限 + 内存回收离线任务触发全局内存压力
磁盘 IOIO 权重 + 限速离线任务打满 IO,在线服务变慢
网络带宽限速 + QoS离线任务占满带宽

混部的前提是有可靠的干扰检测与快速驱逐能力:一旦检测到在线服务的 P99 因离线任务劣化,必须能在秒级驱逐离线任务。没有这个能力的混部,等于把稳定性押在离线任务的「自觉」上。

3. 计算成本优化

3.1 实例选型

策略收益适用
按实际负载选规格10% ~ 30%通用,先做
抢占式/竞价实例60% ~ 90%无状态、可中断任务
预留实例/节省计划30% ~ 50%稳态基线负载
架构升级(ARM)20% ~ 40%编译型语言、无 x86 依赖
降配20% ~ 50%水位长期过低的实例

组合使用是常态:稳态基线用预留实例,峰值用按需,离线批任务用竞价实例。把这三层对应到流量曲线上,通常能拿到 40% 以上的降幅。

3.2 请求级降本

单机利用率提升有天花板,真正的大头往往在请求路径本身:

请求级优化的三类手段
  1. 减少请求数
     - 合并接口(一次返回多个资源,消除 N+1)
     - 前端聚合(BFF 层合并下游调用)
  2. 减少单请求成本
     - 加缓存(命中率每提升 10%,后端压力降约 10%)
     - 减少序列化开销(换更紧凑的协议)
  3. 削峰
     - 请求排队 + 平滑消费
     - 把同步调用改异步,用批处理摊薄成本

缓存是性价比最高的一环,命中率与后端压力几乎线性相关,分层缓存与失效策略的设计见 https://plumephp.com/distributed-cache-strategies/。批处理则适合日志、指标、离线计算这类可延迟的场景:把「来一条处理一条」改成「攒一批处理一批」,固定开销被摊薄,单位成本往往能降一半以上。

不过批处理有明确的适用边界:延迟敏感的业务不能批(用户等不了 5 分钟),有严格顺序要求的数据不能批(批内重排会破坏顺序)。判断标准是「业务能容忍多大的处理延迟」,能容忍 1 分钟以上才值得批。

3.3 Serverless 的账单陷阱

Serverless 按调用次数与执行时长计费,看起来省钱,但两类场景会反噬:

场景问题结果
高频短请求每次调用有固定冷启动/调度开销单位成本高于常驻实例
长连接/长任务按时长计费且无法复用成本随连接数线性上升
内存配置过大计费与内存成正比为省 CPU 调大内存反而更贵
无并发上限流量突增触发大量并发实例单小时账单暴增

Serverless 的适用边界与成本模型,见 https://plumephp.com/distributed-serverless-architecture/。判断标准很简单:如果请求频率高且延迟敏感,常驻实例几乎总是更便宜;Serverless 的优势在于低频、突发、事件驱动的场景。

4. 存储成本优化

4.1 存储分层

层介质单位成本访问延迟适用
热SSD / 内存高微秒~毫秒近期活跃数据
温标准云盘中毫秒~十毫秒偶发访问
冷对象存储标准低十毫秒~百毫秒归档、备份
冰归档存储极低分钟~小时合规留存

分层的关键是自动化的数据生命周期策略,而不是靠人工搬数据:

# 对象存储生命周期规则示例
lifecycle:
  - prefix: logs/
    transitions:
      - { day: 30,  storage_class: STANDARD_IA }   # 30 天后转温
      - { day: 90,  storage_class: GLACIER }       # 90 天后转冷
      - { day: 365, storage_class: DEEP_ARCHIVE }  # 1 年后转冰
    expiration:
      day: 1095                                    # 3 年后删除

4.2 数据生命周期

存储成本失控的第一大原因是只写不删:

数据常见问题治理动作
应用日志全量长期保留分级保留,超过 30 天转冷
监控指标高精度永不降采样按时间降采样(1s -> 1m -> 1h)
数据库历史表无归档策略按时间分区 + 定期归档
备份快照快照链无限增长保留最近 N 个 + 月度全备
消息队列消费完不删除设置 TTL 与保留上限

监控指标的降采样收益尤其显著:把 1 秒精度保留 7 天、1 分钟精度保留 90 天,通常能砍掉 80% 以上的指标存储成本。

4.3 副本数与压缩

副本数决策
  3 副本:默认,容忍 1 节点故障
  2 副本:成本降 33%,但容错性下降,需评估可接受性
  EC(纠删码):1.5 倍冗余即可达到 3 副本的可靠性
               代价是恢复时带宽与 CPU 开销大

压缩决策
  对日志、JSON、时序数据:压缩率常达 5:1 ~ 10:1
  代价:写入与查询时的 CPU 开销
  判断:如果存储成本 > 压缩 CPU 成本,就该压

纠删码(Erasure Coding)是对象存储与冷数据的标准做法,它把冗余从「整份复制」改成「分片 + 校验块」,1.5 倍空间即可达到多副本的可靠性。代价是恢复一个分片需要读取多个其他分片,恢复期间的网络开销远高于副本复制。

5. 网络成本

5.1 跨区流量

云厂商对内网跨可用区、跨地域流量均计费,且跨地域单价通常是同区内的数倍:

流量成本排序(从低到高)
  同可用区        免费或极低
  同地域跨可用区  低(但量大时不可忽视)
  跨地域          高(常为同区内的 5 ~ 10 倍)
  公网出口        最高

降本手段
  1. 让计算靠近数据:把服务部署在数据所在可用区
  2. 减少跨区调用:批量合并、结果缓存
  3. 压缩传输:gRPC + protobuf 优于 JSON
  4. 拓扑感知路由:优先同区副本,故障时才跨区

第 4 条尤其有效:很多分布式数据库默认在副本间随机读,配置成「优先读同区副本」后,跨区流量能降一个数量级。跨集群与跨云的拓扑设计,见 https://plumephp.com/distributed-multi-cluster-cross-cloud/。

5.2 CDN 与回源

CDN 的成本结构是「CDN 流量单价 + 回源流量」:

优化点手段收益
提升缓存命中率合理设置 Cache-Control、去除无意义查询参数回源流量显著下降
减少回源次数合并静态资源、使用长缓存文件名回源 QPS 下降
分级缓存边缘 -> 中间层 -> 源站源站压力下降
压缩与图片处理自动 WebP/AVIF、按需裁剪传输体积下降 30%+

缓存命中率是 CDN 成本的核心杠杆:命中率从 80% 提到 95%,回源流量直接减少 75%。

6. 组织与流程

6.1 成本归属

技术手段之外,成本归属(Cost Attribution) 是能否持续降本的决定因素:

归属三原则
  1. 每笔成本都能打到具体团队(标签:team / service / env / owner)
  2. 共享资源按可解释的规则分摊(按请求量、按 CPU 使用)
  3. 每个团队能看到自己的单位成本趋势

反模式
  - 所有资源无标签 -> 只能看到总账,无法归因
  - 共享资源按人头分摊 -> 用得多的团队没有压力
  - 只看总成本不看单位成本 -> 业务增长时误判为恶化

标签体系是基础工程。没有标签,成本优化只能靠「猜哪个服务贵」。FinOps 的完整方法论与组织实践可延伸阅读数据 FinOps 成本优化 。

6.2 预算与告警

告警类型触发条件动作
预算告警月度消耗达预算 80%通知负责人
异常增长日环比增长 > 30%立即排查(常是配置错误或流量异常)
僵尸资源实例 CPU < 5% 持续 7 天自动标记待回收
单位成本恶化单位成本连续 3 周上升进入专项治理

「异常增长」告警的价值最高:成本突然跳涨往往不是业务增长,而是某个配置错误(如缓存失效导致全量回源)或流量异常(如爬虫)。这类问题的排查时间窗口很短,早一天发现就少一天损失。

6.3 降本与稳定性的权衡边界

降本必须有明确的禁区,否则会以稳定性为代价换取短期账面收益:

动作省下的钱潜在代价是否可做
缩减副本数(3 -> 2)33% 存储容错能力下降需评估,通常不可
关闭跨区容灾跨区流量与冗余资源机房故障即全站不可用不可
提高水位到 80%20% ~ 30% 计算突发流量即雪崩需保留突发余量
延长缓存 TTL后端压力下降数据陈旧视业务可容忍度
降低日志级别存储与采集成本排障信息缺失可做,但保留错误日志
缩短监控保留期监控存储成本无法回溯历史问题可做,需保留降采样数据

判断标准是一句话:这项优化是否降低了系统吸收故障的能力? 如果是,它就不是成本优化,而是风险转移——省下的钱迟早会以事故的形式还回去。

7. 常见坑

坑后果修法
只看总成本不看单位成本业务增长被误判为成本恶化建立单位成本指标并看趋势
无标签直接优化不知道省在哪里,无法归因先做成本归属再动手
过度压缩水位一次流量高峰即雪崩保留突发余量,按流量模型定水位
混部无干扰检测离线任务拖垮在线服务上混部前先建干扰检测与驱逐
存储只写不删存储成本线性增长生命周期策略 + 降采样
忽略跨区流量网络账单占比超预期拓扑感知路由 + 结果缓存
为省钱砍冗余可用性下降,事故成本远超节省冗余是底线,不参与成本优化

最后一条是原则性的:成本优化不能突破可用性底线。单副本省钱、跨区容灾砍掉、备份只留一份,这些「优化」在事故发生时造成的损失通常远超省下的钱。

总结

主题关键内容
成本结构计算、存储、网络、托管服务四类,先排序再动手
单位成本每单/每 DAU/每百万请求成本,看趋势而非绝对值
容量治理水位线、弹性伸缩(快扩慢缩)、混部需干扰检测
计算降本实例分层(预留+按需+竞价)、请求级合并与缓存
存储降本分层存储、生命周期、降采样、纠删码
网络降本拓扑感知路由、减少跨区、提升 CDN 命中率
组织保障成本归属标签、预算与异常增长告警

成本治理与性能治理在方法上高度相似:先度量、再归因、后优化、最后固化到流程。区别在于成本治理天然是跨团队的——它需要财务、平台、业务三方协作,因此组织手段(标签、归属、预算)往往比技术手段更决定成败。把单位成本指标接进日常看板,让每个团队看到自己服务的成本趋势,比任何一次专项优化都更持久。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「distributed-systems」更多文章

  1. 边缘计算架构与就近接入
  2. 单体到分布式:遗留系统迁移与绞杀者模式
  3. Quorum 复制协议:读写多数派与 Paxos 变体