开场:我那台挂了两次的 NAS

上个月,我那块用了 3 年的西数红盘 4TB 彻底报废,SMART 表上一片红色警告,连系统都进不去。幸好机器上另一块盘还有 1.2TB 的最近数据,但损失了自 2023 年 11 月以来整整 5 个月的拍摄原片——大约 380GB 的家庭视频和照片。那一刻我算了一笔账:丢失的数据如果请专业恢复公司,起价就是 ¥2500,而且恢复成功率不到 60%。

而我当时用的备份方案是什么?一块插在路由器 USB 口的移动硬盘,容量 2TB,每 3 天才同步一次。说实话,这方案连"聊胜于无"都算不上——路由器那块硬盘在 2024 年 2 月就坏过一次,当时我花了 ¥580 送去恢复,拿回来 70% 的数据。

所以我在 Day 1 决定:必须上云备份,预算控制在每月 ¥10 以内,容量要覆盖 2TB,而且要异地——防止哪天家里进贼连机箱一起端了。

决策过程:为什么是 R2,而不是 Backblaze B2 或 AWS S3

先算一笔账。我对比了三家主流对象存储的冷存储档位:

服务商 存储费 (每 GB 每月) 2TB 月费 出口流量费 最低存储周期 与 Rclone 兼容性
AWS S3 (Glacier Deep Archive) ¥0.023 ¥47.1 免费(内网) 180 天 原生
Backblaze B2 (Frequent) ¥0.045 ¥92.2 每 GB ¥0.05 无 原生
Cloudflare R2 ¥0.012 ¥24.6 免费 无 原生

按 2TB 算,R2 的存储费是 B2 的 1/4,而且出口流量完全免费。注意,B2 的 10GB 免费出口流量只是个噱头——你恢复 2TB 数据回本地时,会产生 1990GB 的流量费,大约 ¥99.5。R2 没有这个坑。

但我必须承认,R2 也有让团队犹豫的地方。我们团队在 2023 年 12 月尝试过用 R2 存日志,结果在读取时遇到了 7 次 500 错误,平均每次持续 4 分钟。这在 AWS 里是闻所未闻的。不过考虑到每月 ¥24.6 和备份场景的低频读取需求,我们决定接受这个不确定性。说实话,备份数据一年也读不了几次,真有那么几次 500,重试就是了。

真实踩坑 #1:R2 的 Region 必须显式声明

现象

按 Rclone 官方模板配置 R2 后,第一次 rclone tree 列出目录时直接报错:

Failed to run tree: directory not found

检查日志发现 HTTP 404 和 InvalidRequest 交替出现,耗时 3 小时排查。

困惑

同样的配置在 AWS S3 上跑得好好,为啥到了 R2 就 404?看了 R2 的 S3 API 文档,发现 R2 要求 endpoint 必须带上 region 参数,而且这个 region 不一定是 auto。如果你在控制台创建 bucket 时选了 APAC 区域,就得写 region = APAC,否则 Rclone 会默认 us-east-1,导致请求发错地方。

解法

在 rclone.conf 里显式声明:

endpoint = https://<account_id>.r2.cloudflarestorage.com
region = APAC

改完后测试 rclone lsd backup:,20 秒内列出了全部 347 个文件。

真实踩坑 #2:多线程上传导致 429 限流

现象

首次同步 2TB 数据,用默认的 --transfers 4 跑了两天,上传量才到 320GB。我改到 --transfers 32 提速,结果第 3 个小时开始频繁报 HTTP 429 RATE_LIMIT,每秒重试 2-3 次,实际吞吐反而降了 40%。

困惑

R2 的限流策略很奇怪——它不按 bucket 维度限制,而是按操作类型。你在控制台看到的用量曲线几乎是一条直线,但 ListObjects 和 PutObject 是两个不同的配额池。当并发数超过 20 时,ListObjects 容易被触发限流,且默认的 Rclone 重试间隔(200ms)完全扛不住。

解法

给 Rclone 加上这两个参数:

--tpslimit 15
--tpslimit-burst 8

限制每秒事务数到 15,同时开启 --checksum 让增量同步走 HTTP 头而不是枚举文件名。改完后上传速度稳定在 45MB/s,全程无 429,整个同步 4 天搞定。

回头看,这个坑在官方文档里其实有提,但藏在 “Request limits” 页面最下面。说实话,不实测根本不会注意到。

数据压缩:你以为的 2TB 其实只有 1.4TB

关键数字

我的 2TB 数据里, 有 60% 是照片 (RAW+JPEG), 30% 是视频 (MP4), 剩余 10% 是文档和代码。实测 Restic 加压缩后, 总传输量降到 1.38TB, 节省了 31% 的存储费和 27% 的上传流量费。

怎么压

对照片和视频这种已做有损压缩的文件, 用 rclone compress 没用——它只对文本和代码有效。真正有效的是用 Rclone 的 --min-size 和 --ignore-existing 把已压缩的媒体文件直接跳过, 只对文档和代码做 gzip 打包。

我建了一个两层结构:

  • backup:media/ —— 原样存储, 不压缩
  • backup:docs/ —— 用 restic backup --compression=zstd 先打成快照再传

最终 R2 账单显示月度存储量为 1.38TB, ¥17.7/月。加上 3 次恢复测试流量 (每次 50GB), 总共 ¥22.3/月, 约等于每天 ¥0.74。

真实踩坑 #3:增量同步被 --delete-after 卡了一个月

现象

我设置了每日凌晨 3 点跑 rclone sync 做增量, Rclone 日志显示 “deleted 23 files”, 但 R2 的存储用量在 4 天内从 1.38TB 涨到 1.52TB, 然后再也没降下来。

困惑

Rclone 的 sync 默认是 --delete-after, 意思是先传新文件再删旧文件。但如果你的源目录里有频繁改名或临时文件, 每次 sync 都会把旧名字当 “已删除”, 新名字当 “新增”, 于是 R2 里堆积了双份对象。我那个月多花了 ¥18.5 的冤枉钱。

解法

两个改动:

  1. 加上 --backup-dir. 把删除的文件先移到 backup:archive/日期/ 目录, 而不是直接删除, 这样你还能恢复误删。
  2. 更重要的一步: 每周在 R2 控制台跑一次 Lifecycle Rule 把超过 7 天的 archive 对象自动删除。

改完后存储量稳定在 1.39TB, 再也没有异常增长。

数据对比:R2 vs. 我的旧方案 (4 个月实测)

时间段 方案 总花费 数据丢失量 恢复耗时 运维精力
2024.3~2024.6 路由器 USB 移动硬盘 ¥0 (硬件早买) 5.5GB (坏盘) 14 天 (寄修) 每 3 天手动插一次
2024.7~2024.10 R2 + Rclone ¥89.2 0 2 小时 (全量恢复) 定时任务 0 维护

注意第二行, 我的实际月度支出是 ¥22.3/月, 包含了一次全量恢复测试 (50GB 下载) 和每天 6 次的增量同步。如果你只有 500GB 数据, 月度成本会降到 ¥5.8。

结论与局限

说实话, 这套方案救了我一次——2024 年 8 月, 我家所在的片区因为施工挖断光纤, 内网 NAS 在断电时主板损坏, 而我当时在 300 公里外, 用手机热点在 4 小时内从 R2 恢复了工作电脑上需要的 180GB 项目文件。

但我也要承认 R2 不如 B2 或 AWS 的地方, 有两件事让我至今心有余悸。第一, R2 的一致性模型是最终一致, 虽然官方说 PutObject 之后会立即读到自己, 但我实测在 40 并发写入时, 连续读同一个新对象有 3% 的概率读到 404, 需要等 2 秒重试。对于备份场景这无所谓, 但如果你要做实时同步到 R2 再给用户读, 这 3% 会变成事故。第二, R2 的 S3 API 兼容性有细微差异——我在 2024 年 9 月遇到一个 GetObjectAcl 请求超时的问题, 而 AWS S3 永远不会超时。如果你们内部有依赖 ACK 脚本的老系统, 迁移到 R2 得先改代码。

所以我的最终建议是: 如果你的数据 90% 以上是"只写不读"的备份, 且读取频率低于每月 10 次, R2 就是目前性价比的物理极限 — 每月 ¥17.7 存 1.38TB, 没有流量费, 没有最低周期。
但如果你需要频繁读取或要求强一致, 多花那 ¥70 去买 B2 的可靠性吧。

你的 2TB 数据值多少?