你的云存储桶有2TB的无人触碰数据,已放置6个月(你多付了16倍费用) 💾
Source: Dev.to
(请提供需要翻译的正文内容,我将为您翻译成简体中文,并保持原有的格式、Markdown 语法以及技术术语不变。)
成本比较
| 类别 | 成本/GB / 月 | 最低时长 | 适用场景 | 检索费用 |
|---|---|---|---|---|
| Standard | $0.020 | 无 | 热数据,频繁访问 | 免费 |
| Nearline | $0.010 | 30 天 | 访问频率较低 | — |
| Coldline | $0.004 | 90 天 | 不常访问(每季) | — |
| Archive | $0.0012 | 365 天 | 很少访问(每年) | — |
注意: 所有存储类别均具备相同的 11 个 9 的耐久性和毫秒级访问延迟。Archive 存储 不是 磁带——数据可即时访问,只是检索费用更高。
为什么生命周期策略很重要
- 每个对象默认在 Standard 存储类,除非你手动干预,否则会一直保留在该层级。
- GCP 不会自动将 数据迁移到更便宜的层级。
- 如果没有策略,未被触碰的 2 TB 数据集在 6 个月后会产生 每月 $40 的费用,而实际可以降至 $2.40。
生命周期策略 会根据对象的年龄自动将其迁移到更便宜的存储类——无需手动操作、脚本或 cron 任务。只需几分钟即可使用 Terraform 部署它们。
常见的降层模式
Standard → Nearline → Coldline → Archive → Delete
Terraform 示例:简单降级
resource "google_storage_bucket" "data" {
name = "${var.project_id}-app-data"
location = "US"
storage_class = "STANDARD" # start in Standard
# 30 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 30
matches_storage_class = ["STANDARD"]
}
}
# 90 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 90
matches_storage_class = ["NEARLINE"]
}
}
# 365 days → Archive
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "ARCHIVE"
}
condition {
age = 365
matches_storage_class = ["COLDLINE"]
}
}
# 730 days (2 years) → Delete
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 730
}
}
labels = local.common_labels
}
⚠️ 注意: 生命周期规则执行的转换不会产生提前删除费用。手动将对象重写为不同的存储类会触发检索费用和提前删除费用——让规则来处理吧。
Terraform 示例:基于前缀的多层存储
resource "google_storage_bucket" "multi_tier" {
name = "${var.project_id}-multi-tier-data"
location = "US"
# ---------- Logs ----------
# 7 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 7
matches_prefix = ["logs/"]
matches_storage_class = ["STANDARD"]
}
}
# 30 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 30
matches_prefix = ["logs/"]
matches_storage_class = ["NEARLINE"]
}
}
# 90 days → Delete
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 90
matches_prefix = ["logs/"]
}
}
# ---------- Backups ----------
# 30 days → Coldline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = 30
matches_prefix = ["backups/"]
matches_storage_class = ["STANDARD"]
}
}
# 90 days → Archive
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "ARCHIVE"
}
condition {
age = 90
matches_prefix = ["backups/"]
matches_storage_class = ["COLDLINE"]
}
}
# 730 days → Delete (keep backups for 2 years)
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 730
matches_prefix = ["backups/"]
}
}
# ---------- User uploads ----------
# 90 days → Nearline
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = 90
matches_prefix = ["uploads/"]
matches_storage_class = ["STANDARD"]
}
}
labels = local.common_labels
}
一个存储桶,三种数据模式:
- 日志 会被快速降级,并在 90 天后删除。
- 备份 在一个月内保持热存储,然后转为冷存储,随后归档,最长保存 2 年。
- 用户上传 在标准存储保留三个月后,迁移至 Nearline。
Terraform 示例:版本化存储桶
resource "google_storage_bucket" "versioned" {
name = "${var.project_id}-versioned-data"
location = "US"
versioning {
enabled = true
}
# Keep only the 3 most recent versions
lifecycle_rule {
action {
type = "Delete"
}
condition {
num_newer_versions = 3
with_state = "ARCHIVED"
}
}
# Delete non‑current versions older than 90 days
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = 90
with_state = "ARCHIVED"
}
}
# Abort incomplete multipart uploads after 7 days
lifecycle_rule {
action {
type = "AbortIncompleteMultipartUpload"
}
condition {
age = 7
}
}
labels = local.common_labels
}
为什么? 版本化可以保护数据,但如果不进行清理,存储成本可能会 翻倍或三倍。上述规则可自动保持存储桶整洁。
底线
- 所有类共享相同的耐久性和延迟——您只需为所需的访问模式付费。
- 生命周期规则是将数据迁移到更低成本层并最终删除的最简单、最安全的方式。
- 在几分钟内使用 Terraform 部署它们,让 GCP 在您睡觉时处理其余工作。
成本效益高的 GCP 云存储与 Terraform
⚠️ 隐蔽的费用杀手
不完整的分段上传 在控制台中不可见,但仍会占用存储空间。如果您的应用进行大文件上传且有时在中途失败,这些碎片会悄然堆积。
AbortIncompleteMultipartUpload 规则是免费保险。
Autoclass – 自动分层
如果您不知道数据的访问频率,GCP 的 Autoclass 功能会根据实际访问模式自动在存储类别之间移动对象。
resource "google_storage_bucket" "auto_tiered" {
name = "${var.project_id}-auto-tiered"
location = "US"
autoclass {
enabled = true
terminal_storage_class = "ARCHIVE" # Lowest tier it can reach
}
labels = local.common_labels
}
Autoclass 将经常访问的数据 向上迁移 到 Standard(生命周期规则做不到这一点),并自动将未被触及的数据 向下 迁移到更低的层级。虽然会产生少量管理费用,但对于不可预测的访问模式,它节省的成本超过费用。
何时使用 Autoclass 与手动生命周期规则
| 场景 | 推荐做法 |
|---|---|
| 已知访问模式(日志、备份) | 手动生命周期规则 |
| 未知 / 混合访问模式 | Autoclass |
| 可能在数月后再次访问的数据 | Autoclass |
| 合规要求(必须在特定类别) | 手动生命周期规则 |
| 最大成本控制 | 手动生命周期规则 |
在每个团队的存储桶上部署相同的生命周期规则
variable "buckets" {
type = map(object({
location = string
lifecycle_type = string # "logs", "backups", "general", "autoclass"
}))
default = {
"team-alpha-logs" = {
location = "US"
lifecycle_type = "logs"
}
"team-beta-backups" = {
location = "US"
lifecycle_type = "backups"
}
"ml-training-data" = {
location = "US"
lifecycle_type = "autoclass"
}
}
}
locals {
lifecycle_configs = {
logs = {
nearline_age = 7
coldline_age = 30
delete_age = 90
}
backups = {
nearline_age = 30
coldline_age = 90
delete_age = 730
}
general = {
nearline_age = 30
coldline_age = 90
delete_age = 365
}
}
}
受管存储桶(非 Autoclass)
resource "google_storage_bucket" "managed" {
for_each = {
for k, v in var.buckets : k => v
if v.lifecycle_type != "autoclass"
}
name = "${var.project_id}-${each.key}"
location = each.value.location
storage_class = "STANDARD"
# → 移动到 NEARLINE
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].nearline_age
matches_storage_class = ["STANDARD"]
}
}
# → 移动到 COLDLINE
lifecycle_rule {
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].coldline_age
matches_storage_class = ["NEARLINE"]
}
}
# → 删除
lifecycle_rule {
action {
type = "Delete"
}
condition {
age = local.lifecycle_configs[each.value.lifecycle_type].delete_age
}
}
# → 中止未完成的分段上传
lifecycle_rule {
action {
type = "AbortIncompleteMultipartUpload"
}
condition {
age = 7
}
}
labels = local.common_labels
}
需要新存储桶? 在 buckets 映射中添加一条记录,然后运行 terraform apply。生命周期规则会立即生效。 ✅
快速获胜行动
| 操作 | 工作量 | 节省 |
|---|---|---|
| 为现有日志存储桶添加生命周期规则 | 5 分钟 | 日志存储节省 73‑94 % |
启用 AbortIncompleteMultipartUpload | 2 分钟 | 阻止静默成本泄漏 |
| 添加版本清理规则 | 5 分钟 | 版本化存储桶节省 50‑70 % |
| 创建可重用的生命周期模块 | 15 分钟 | 全组织一致的规则 |
| 为未知模式启用 Autoclass | 2 分钟 | 自动优化层级 |
从你的 日志存储桶 开始——它们通常是最大的问题根源(大量数据在一周后无人查看)。 🎯
Pricing Snapshot (US region)
| Class | Price / GB |
|---|---|
| Standard | $0.020(热数据,频繁访问) |
| Nearline | $0.010(≤ 1×/月,30 天最短保留) |
| Coldline | $0.004(≤ 1×/季度,90 天最短保留) |
| Archive | $0.0012(≤ 1×/年,365 天最短保留) |
所有类别在耐久性和延迟方面相同,唯一的区别是价格。
为什么生命周期很重要
- 没有生命周期 → 每个对象永远停留在 Standard 中 → 对旧数据的成本最高可达 16 倍。
- 几分钟的 Terraform → 消除多年浪费。 🪣
下一步
- 识别 您最大的存储桶。 在控制台中按“最近访问”排序。
- 应用 适当的生命周期或 Autoclass 配置。
- 监控 接下来一个月的成本节省。
结论: 如果您的存储桶缺少生命周期规则,您就会支付过高费用。只需几分钟的 Terraform 就能在陈旧数据上实现 80 %+ 的节省。
觉得这有帮助吗?关注获取更多使用 Terraform 的 GCP 成本优化技巧! 💬