
10 月 29 号 AWS Storage Blog 发了篇叫 Reducing petabyte-scale S3 storage costs with evidence-based lifecycle rules 的文章。标题里有个词很关键,evidence-based,用证据驱动。一个客户把约 5.8 PB 的可观测性和搜索索引日志摊在两个桶里,全躺在 S3 Standard、没配任何生命周期规则,月账单 24 万美元,用这套方法砍掉 70%,还保留了毫秒级访问。70% 这个数字够炸,但更值得看的不是数字,是它怎么算出该迁哪些数据。大多数降本故事止步于“换个省钱的存储类”,这篇往前多走了一步,先证明数据真的冷了,再动手。我把这套方法拆开,看哪些自托管侧能直接抄,哪些 AWS 托管能力得自己补。
冷数据是最大的隐性成本坑,难在你知道哪块冷了没
PB 级存储里最贵的往往不是热数据,是那些“万一哪天要查”而被一直供在高速存储上的冷数据。数据集涨到几百 TB 甚至 PB 之后,负责它的团队常常已经说不清它多久没被读了。安全的本能是把所有东西留在最贵最快的存储类上。访问模式从来不是均匀的,安全团队可能因为偶尔的调查要留日志,分析团队只在季末查一次同样的数据,两边最后都在为几乎不用的高速存储买单。难点从来不是决定要不要动,是知道哪些数据已经冷了、又能安全地挪到哪。
AWS 的方法:先用 Storage Lens 定位,再用 Storage Class Analysis 取证
方法的根基是两个 AWS 托管能力,分工很清晰。S3 Storage Lens 负责“在哪”——它用 groups 把存储指标按对象元数据过滤(前缀、后缀、标签、size、age)聚合,给你的是按决策维度的对象数和存储量,而不是一个桶级别的笼统数字。一个 S3 Storage Lens 配置最多 50 个 group,前缀分太细就得拆多个配置——自建侧按前缀分组时也记着这个上限。S3 Storage Class Analysis 负责“还读不读”——它按对象 age 分组,报每个 age band 的检索量,证明数据什么时候变冷。作者的态度很明确,把 SCA 的推荐当成访问模式的一个数据点,不是最终的存储类结论。它确认数据冷了,至于落到哪个类最贴合真实的延迟和成本要求,是另一个独立的选择。

一个反复出现的数字:128 KB 是这道算术题的开关
整篇方法里有个数字反复出现,128 KB。S3 Standard-IA、S3 Glacier Instant Retrieval 和 S3 Intelligent-Tiering 都把 128 KB 当阈值:更小的对象要么按 128 KB 计费,要么被排除在自动分层之外,要么根本不进 Storage Class Analysis 的评估。一个以小对象为主的存储 footprint,会直接改写省钱的算式。所以方法第一步量的就是数据有多少落在 128 KB 这条线以上。这一步不做,后面算的节省可能是负的——把一堆小对象迁到按 128 KB 最低计费的标准,反而更贵。
观察窗口不能偷懒,30 天是最短,45 天更稳
SCA 控制台 24 到 48 小时就出首批结果,但作者劝你别急着动。SCA 要观察访问 30 天或更久,他自己观察了超过 45 天,为了抓住周期性的读取——一个更短的窗口会漏掉季末或定期的访问尖峰。这点很重要,因为从归档层把数据取回来,远比从 S3 Standard 取贵。如果一个季节性的读取尖峰在你迁完数据之后才来,省下来的钱会被检索费吃掉一部分。在那次客户案例里,超过 90 天的对象访问率低于 0.1%,这是一个用数据撑起来的冷阈值。
从 Standard-IA 再往前一步:Glacier Instant Retrieval 的 68%
SCA 关注的核心是 S3 Standard 到 S3 Standard-IA 的迁移,这是个优秀的“数据已冷”第一信号。但对于几乎不读、却仍要毫秒级访问的数据,可以顺着同一个证据再往前走一步。Glacier Instant Retrieval 给的是和 S3 Standard、Standard-IA 一样的毫秒延迟和吞吐,对大约一季度访问一次的数据,比 Standard-IA 最高能省 68%。动手前得确认负载吃下它的约束:90 天最低存储期、128 KB 最低计费对象大小、按 GB 的检索费加上更高的按请求费。这些在 AWS 的定价页按区域列着,不是能拍脑袋的常数。

别让一次全表扫描把省下来的钱吐回去
归档类的按请求和按 GB 检索成本,比 S3 Standard 高得多。一次全前缀扫描,或者一轮大批量对归档数据的读取,就能把存储省下的钱抹平。作者的护栏很实在,限制查询引擎和批处理作业直接扫归档类前缀,比如把全表扫描路由到 S3 Standard 里的一份副本或汇总。再给归档前缀设 S3 request metrics 报警,异常的检索尖峰尽早抓出来。生命周期规则要配着这道护栏一起上,而不是单独把迁移甩出去。
自建侧怎么抄:RustFS 的 lifecycle 和 tiering 是一套同构工具
方法里真正能抄到自托管侧的,是“用 object size、age、retrieval 证据决定分层”这套思路,不是 Storage Lens 那个 UI。开源 S3 兼容存储只要有 lifecycle 的 transition 和 expiration,就能落地同样的冷热迁移。RustFS 这块是现成的。
第一步不是写规则,是先注册 tier。transition 的目标不是一个 AWS 存储类,而是一个你在 tiered storage 里注册的大写 tier 名字,比如 COLDTIER。注册用 rc:
rc bucket lifecycle tier add rustfs COLDTIER local \
--endpoint https://cold.rustfs.internal:9000 \
--access-key <your-access-key> --secret-key <your-secret-key> \
--bucket my-bucket --region us-east-1
一个容易踩的坑:注册 tier 不会让任何对象动起来,必须再有一条 lifecycle 规则引用这个名字,转换才会触发。顺序不能反,先 tier 后规则。tier 背后可以接另一套 RustFS 部署,也可以是 S3、Wasabi、MinIO、阿里云 OSS、腾讯云 COS、华为云 OBS、Azure、GCS、R2 这些后端。
规则本身,过期和转换可以写进同一条:
rc bucket lifecycle rule add local/my-bucket \
--prefix logs/ --expiry-days 30 \
--transition-days 90 --storage-class COLDTIER
对象扫描器在后台异步评估规则,迁完之后对象元数据留在热集群、数据落到冷层,应用还是通过原来的桶和 key 读,不用改地址。版本化的桶还能单独给 noncurrent version 配转换和过期,这点跟 AWS 的“保留少量旧版本防误删”是一个思路。
冷了之后怎么秒级读回来
文章反复强调“冷了仍要毫秒访问”,对标 Glacier Instant Retrieval 的关键其实在这一条:把转换出去的对象临时拉回本地副本、保留七天,期间 HEAD 返回 x-amz-restore: ongoing-request=“true”:
rc bucket lifecycle restore local/my-bucket/hello.txt --days 7
不加这条,“毫秒访问”就是悬空的——读者会以为迁过去就完事,真要查的时候反而卡住。
一个高危坑,运维最容易翻车
RustFS 文档把这条写得很重:不要在目标桶里直接重命名、覆盖或删除被转换出来的对象,源对象一律通过热集群管理,否则本地的转换元数据和远端的实际数据会对不上。改动或删除一个 tier 之前,必须先禁用引用它的生命周期规则、确认没有转换任务还在跑、确认没有源对象依赖那个目标桶里的数据、并备份 tier 配置。正常的 tier 变更会检查后端占用、保护非空目标,别用 force 去绕过这些检查——除非你已经独立证明每个被转换的对象都还能找回。对一个还在用的 tier 删配置,可能让那些对象从源集群再也读不出来。
观测侧的差:Storage Lens 和 SCA 是 AWS 托管,开源侧得自己拼
诚实说,RustFS 没有 Storage Lens 或 Storage Class Analysis 这两个同名内置服务,它们是 AWS 的托管观测能力。但方法的内核——按 age 聚合出每个时间段的检索率,找出低于某个阈值的冷数据——在自建侧完全能重建。只不过重建用的不是 S3 那种 bucket access logging(RustFS 没有这个东西),而是两条路:
- 请求级记录走审计目标(audit targets),支持 webhook、Kafka、MQTT、MySQL、PostgreSQL、NATS、Redis、AMQP、Pulsar 这些出口,记录里含请求路径、身份、访问密钥标识、状态码,拿这些按对象创建时间分桶、统计每个 age band 的 GET 次数;
- 指标走 OTLP,RustFS 没有开箱即用的 Prometheus /metrics 端点,得跑一个 OpenTelemetry Collector 把信号接进 Prometheus / Grafana;
- 还有一个现成的层级活动端点,带 admin:ListTier 权限的 SigV4 请求就能看:GET /rustfs/admin/v3/tier-stats?tier=COLDTIER。
观测工具要自己拼,但决策逻辑是同一套。这恰恰是这篇值得抄的地方,它把“凭感觉分层”换成了“凭证据分层”,而证据这套东西,跟你在哪家存储上跑无关。
决策清单:哪些数据值得这么折腾
这套方法省的不是硬盘钱,是把“凭感觉留在高速存储”换成“凭证据分层”后的存储费。值得上这套流程的数据长这样:几百 TB 到几 PB、主要在 S3 Standard、没配任何生命周期规则;写一次很少读、有明确留存窗口(案例里是约五年);冷了之后仍要求毫秒访问,所以排除异步归档类;对象主要大于 128 KB,否则省钱的算式会翻车。四个条件都对上了,再走 Storage Lens 定位、SCA 取证、保守地设迁移 age(案例里 60 天对比 90 天,选了 90 天,因为早迁省的那点钱抵不过近期访问尖峰的检索费风险)、最后加防扫描护栏。
最后留一句。AWS 这篇把“冷数据降本”从口号变成了可重复的步骤,证据驱动是它最值钱的部分。自托管侧没有开箱即用的 Storage Lens,但 lifecycle 加 tiering 加审计目标(audit targets),三件套能把同一套逻辑跑起来。真正难的部分从来不是迁数据,是先把“哪块真的冷了”这件事,用数据说清楚。
案例原文在 AWS Storage Blog,RustFS lifecycle 与 tiered storage 的用法见 docs.rustfs.com。
本文解析AWS基于Storage Lens和Storage Class Analysis的证据驱动冷数据生命周期管理方法,聚焦PB级对象存储降本70%的核心逻辑:以128KB为计费阈值、45天以上访问观察窗口、毫秒级归档访问保障,并详解自建侧如何通过RustFS的lifecycle与tiering机制、审计目标(audit targets)及OTLP指标体系复现该方法,强调冷热分层决策必须依赖真实访问证据而非经验猜测。
1393

被折叠的 条评论
为什么被折叠?



