OBS 存储成本优化实战:生命周期规则怎么配才不踩坑

举报
yd_292302676 发表于 2026/10/25 09:46:28 2026/10/25
【摘要】 从账单结构出发,讲清 OBS 各存储类别的最小存储期差异,给出按前缀拆分生命周期规则的配置示例,并记录版本控制、转档后仍被读取两个真实踩坑,最后附对象分布盘点脚本与落地顺序。

上个月复盘一个内容类项目的云账单,存储费用占了 68%,而这里面又有接近七成是三个月前上传、之后再也没被读过的图片和视频素材。这不是个例——大部分项目的 OBS 桶用久了都会变成「只进不出」的状态:上传路径写得很顺,清理策略从来没人管。

这篇文章把我自己踩过的坑整理一遍,重点不是「生命周期规则在哪儿点」,而是几个配错之后会反噬的地方。

一、先搞清楚钱花在哪一类存储上

OBS 不是只有一种「存储」,不同类别的单价差好几倍,代价是取回的速度和灵活性。配置生命周期规则之前,先明确这些差异:

存储类别 最小存储期 取回特点 适合放什么
标准存储 无 实时访问 线上正在用的图片、接口返回的 JSON、日志热数据
低频访问存储 30 天 实时,但按取回量计费 一个月看几次的历史素材、备份快照
归档存储 90 天 需先恢复,分钟级到小时级 合规留存的合同、审计日志
深度归档存储 180 天 恢复更慢 一年都不一定翻一次的冷备

关键在「最小存储期」这一列。它不是你「最少要放这么久」,而是「放不满这么久也要按这么久收钱」。很多人把规则配成「上传 7 天后转低频」,看起来省钱,实际上低频有 30 天最小期,短期对象反而更贵。

二、生命周期规则的正确写法

我的做法是按前缀拆规则,而不是一条规则管全桶:

{
  "Rules": [
    {
      "ID": "media-cold-archive",
      "Prefix": "media/",
      "Status": "Enabled",
      "Transitions": [
        { "Days": 35, "StorageClass": "STANDARD_IA" },
        { "Days": 100, "StorageClass": "GLACIER" }
      ],
      "Expiration": { "Days": 730 }
    },
    {
      "ID": "tmp-cleanup",
      "Prefix": "tmp/",
      "Status": "Enabled",
      "Expiration": { "Days": 7 }
    }
  ]
}

两个细节值得说。

转档天数要比最小期多留几天。上面写 35 而不是 30,是因为对象的「天数」按创建时间算,而转档动作本身有延迟窗口,卡在 30 天整容易触发提前转档的计费争议。留 5 天缓冲,账单更好对。

临时目录一定要单独一条过期规则。上传中转、图片处理中间产物通常放在 tmp/ 下,这类对象没人认领,靠人清理必然会忘。

三、两个真实踩过的坑

坑一:开了版本控制之后,删除不等于不收费。桶开启多版本后,过期删除只是加了一个删除标记,历史版本仍然占空间、仍然计费。要么在规则里同时配非当前版本的过期天数,要么定期跑一次清理。

坑二:转档之后才发现业务还在读。有个相册功能把原图转进了归档,前端缩略图走的是另一套路径没受影响,但「查看原图」按钮点下去要等恢复。补救办法是转档前用访问日志确认前缀的真实读取频率,而不是凭感觉。

四、先盘点再动手

配规则之前,我习惯先跑一遍对象分布,看清楚到底哪些前缀占空间:

from obs import ObsClient

client = ObsClient(
    access_key_id=AK, secret_access_key=SK,
    server="https://obs.cn-north-4.myhuaweicloud.com"
)

stat = {}
marker = None
while True:
    resp = client.listObjects("my-bucket", prefix="", marker=marker, max_keys=1000)
    for obj in resp.body.contents:
        top = obj.key.split("/")[0]
        s = stat.setdefault(top, {"count": 0, "size": 0})
        s["count"] += 1
        s["size"] += obj.size
    if not resp.body.is_truncated:
        break
    marker = resp.body.next_marker

for k, v in sorted(stat.items(), key=lambda x: -x[1]["size"])[:10]:
    print(k, v["count"], "个", round(v["size"] / 1024 ** 3, 2), "GB")

这段跑完,通常前三个前缀就占了 80% 以上空间,规则直接照着它们配就行,不用全桶撒网。

五、落地顺序

我现在的固定流程是:先看账单确认存储占比 → 跑盘点脚本定位大前缀 → 用访问日志确认冷热 → 按前缀配转档和过期 → 观察一个计费周期再调天数。

这套做完,那个项目的存储费用降了大约一半,改动只有几条规则和一个定时清理任务,业务侧完全没有感知。成本优化很多时候不是要重构架构,只是把「上传完就不管」这个习惯补上后半段。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。