华为云 OBS 生命周期规则实战:自动转储冷数据、清理过期对象与碎片,降低存储成本
一、为什么要关注 OBS 生命周期规则
很多团队把日志、备份、训练数据、用户上传的附件统一放在对象存储服务 OBS 的标准存储桶里,前期省心,但半年后账单会明显上涨:大量对象只在写入后的头几天被频繁读取,之后基本无人访问,却一直按标准存储单价计费。OBS 的生命周期管理可以按规则自动把“变冷”的对象转换为更便宜的存储类别,或在到期后直接删除,整个过程不需要写定时脚本,也不占用自己的计算资源。
本文以一个典型的“应用日志 + 数据库备份”桶为例,梳理规则设计思路、控制台与 SDK 两种配置方式,以及实际落地时容易踩的坑。
二、先搞清楚 OBS 的存储类别
- 标准存储:适合频繁访问的热数据,访问延迟低,无最短存储时间限制。
- 低频访问存储:适合每月访问少量几次的数据,存储单价更低,但有最短存储时间要求,并按读取量收取数据取回费用。
- 归档存储:适合很少访问、可以接受“先恢复再读取”的数据,单价更低,读取前需要先执行恢复操作。
- 深度归档存储:适合长期合规留存、几乎不读取的数据,成本最低,恢复耗时也最长。
选择规则前,建议先看一下桶的访问特征:可以在 OBS 控制台的“概览/监控”中查看请求次数和流量趋势,或开启桶的访问日志做一段时间统计,确认哪些前缀的数据在多少天后基本不再被读取。不同存储类别的最短存储时间和取回费用以官方文档和价格页为准,规则设计时一定要把它们算进去,否则“提前删除”或“频繁取回”反而会更贵。
三、示例场景与规则设计
假设桶 app-data-prod 中有两类数据:
logs/:应用日志,写入后 7 天内用于排障查询,30 天后几乎不看,按审计要求保留 1 年。backup/:数据库每日全量备份,最近一个月可能用于恢复,之后只作为合规留存,保留 3 年。
对应的规则可以这样设计:
| 规则 | 前缀 | 转换 | 过期删除 |
|---|---|---|---|
| rule-logs | logs/ | 30 天后转低频访问,90 天后转归档 | 365 天后删除 |
| rule-backup | backup/ | 30 天后转归档,180 天后转深度归档 | 1095 天后删除 |
| rule-mpu | (整个桶) | — | 未完成的分段上传碎片 7 天后删除 |
几点设计原则:
- 按前缀隔离不同数据,不要对整个桶“一刀切”,否则静态资源等热数据也会被转冷。
- 转换天数要大于等于上一级存储类别的最短存储时间,避免产生提前转换/删除的额外费用。
- 别忘了清理分段上传碎片:大文件上传中断后遗留的碎片同样计费,而且在对象列表里看不到,是很多桶“莫名变大”的原因。
四、控制台配置步骤
- 登录 OBS 控制台,进入目标桶,在左侧选择“数据管理 > 生命周期管理”(不同版本控制台菜单名称可能略有差异)。
- 点击“创建”,填写规则名称,选择“按前缀”并输入
logs/。 - 在“当前版本”中勾选转换为低频访问存储(30 天)、转换为归档存储(90 天),并设置过期删除(365 天)。
- 如果桶开启了多版本控制,再为“历史版本”单独设置过期时间,否则被覆盖的旧版本会一直保留并计费。
- 保存后用同样方式创建
backup/规则和碎片清理规则。
五、用 Python SDK 以代码方式管理规则
多个环境(开发/测试/生产)需要保持一致时,建议把规则写成代码纳入版本管理。下面是使用 OBS Python SDK(esdk-obs-python)的示例,AK/SK 通过环境变量读取,不要硬编码在代码中:
import os
from obs import ObsClient, Lifecycle, Rule, Transition, Expiration
from obs import NoncurrentVersionExpiration, StorageClass
client = ObsClient(
access_key_id=os.environ["HUAWEICLOUD_SDK_AK"],
secret_access_key=os.environ["HUAWEICLOUD_SDK_SK"],
server="https://obs.cn-north-4.myhuaweicloud.com",
)
rule_logs = Rule(
id="rule-logs", prefix="logs/", status="Enabled",
transition=[
Transition(days=30, storageClass=StorageClass.WARM),
Transition(days=90, storageClass=StorageClass.COLD),
],
expiration=Expiration(days=365),
noncurrentVersionExpiration=NoncurrentVersionExpiration(noncurrentDays=30),
)
resp = client.setBucketLifecycle("app-data-prod", Lifecycle(rule=[rule_logs]))
print(resp.status, resp.errorCode, resp.errorMessage)
# 读取当前规则,便于核对
print(client.getBucketLifecycle("app-data-prod").body)
client.close()
注意:setBucketLifecycle 是整体覆盖语义,提交的规则列表会替换桶上已有的全部规则。修改前先用 getBucketLifecycle 取回现有配置,合并后再提交,避免误删别人配置的规则。不同 SDK 版本的参数名可能有差异,以所用版本的 SDK 文档为准。
六、上线后如何验证效果
- 规则生效有延迟:生命周期是后台异步执行的,规则创建后一般不会立刻看到对象变化,建议隔天再查看。
- 看对象的存储类别:在对象列表中查看“存储类别”列,或用 SDK 的
getObjectMetadata查看返回的存储类别字段。 - 看账单拆分:在费用中心按产品和存储类别查看 OBS 费用,对比规则上线前后一个计费周期的变化。
七、常见坑汇总
- 归档对象不能直接下载:需要先“恢复”,等恢复完成后在有效期内读取。如果业务偶尔需要秒级读取,就不要转归档,低频访问更合适。
- 小对象不划算:低频/归档存储通常有最小计费单位,海量 KB 级小文件转冷后节省有限,可以先合并打包再归档。
- 多版本桶要单独处理历史版本:只给当前版本配置过期,历史版本仍会无限累积。
- 规则前缀写错:
logs与logs/匹配范围不同,前者也会匹配logs-archive/等对象。 - 先在测试桶演练:过期删除不可恢复,生产环境上线前最好用测试桶和较短天数验证规则行为。
八、小结
OBS 生命周期规则本质上是“用策略代替人工”:按前缀区分数据、结合访问频率和最短存储时间设计转换天数、补上碎片和历史版本清理,就能在不改业务代码的前提下持续压降存储成本。建议把规则纳入代码管理,并在每个计费周期复盘一次实际效果。
- 点赞
- 收藏
- 关注作者
评论(0)