家里的照片和视频快到 1T 了,之前一直用最土的办法:整个文件夹拖到移动硬盘,再拷一份到旧笔记本。麻烦在于每加几十张照片就得等一小时全量复制,更糟的是有次手滑把「照片」文件夹拖进了待删目录,同步工具很忠实地把备份端也删了。我真正想要的其实就三件事:只传变化的部分、能回到上周三的状态、仓库还能搁在 NAS 或网盘上。
restic 是这几年我反复回到的一个答案。单文件、跨平台、开源,仓库格式稳定,最要紧的一条是它只上传分块之后真正变了的内容。下面所有数字都是我在自己机器上跑出来的(Ryzen 5 3550H 八线程、SATA SSD、Windows 11),不是从文档里抄的。
先说结论:它到底省不省
数据集我特意做得像真实的家庭目录——961 个文件、933MB:240 张 1.2MB 的照片、一个 500MB 的视频、600 个 Markdown 笔记,另外把其中 120 张照片原样复制到另一个目录,模拟「手机里存了一份、电脑上又存了一份」。
- 首次备份:处理 937.3MB / 961 个文件,实际写进仓库 797.4MB,耗时 5.4 秒
- 新增 20 张照片 + 改 1 个笔记:处理 960.8MB,只写进 24.0MB,耗时 1.7 秒
- 复制 500MB 视频并在开头插 1 个字节后再备份:处理 1.43GB,只写进 1.25MB,耗时 3.5 秒
第一行就值得停一下:937MB 的处理量只写进去 797MB,差的 140MB 正是那 120 张重复照片。它是靠文件内容的哈希直接认出来的,在「已经存过这份内容」这件事上一个字节都没上传,而不是像很多人以为的那样「先传上去再判断重复」。
第二行是我日常最常见的场景:一天下来多了二十张照片、改了一段笔记,1.7 秒结束,写进去的 24MB 就是这二十张照片本身。
一个字节的错位,只多传了 1.25MB
这是我最想让人看到的一条,也是 restic 和「按固定大小切块比对」的方案真正拉开差距的地方。
传统增量方案按固定 512KB 一刀切,只要文件开头多一个字节,后面所有块的边界全体位移,哈希全对不上,等于整篇重新上传——一个 50GB 的虚拟机镜像改一行配置,就要重传 50GB。
restic 用的是内容定义分块(CDC),切点由数据本身算出来,插入内容只会影响断点附近的一小段。我把 500MB 的视频复制一份,在文件最前面塞了 1 个字节,整个文件的字节流因此全部错位,再备份:处理量 1.43GB,写进仓库 1.25MB,3.5 秒结束。
需要说清楚边界:换容器重新封装(remux)会把字节重新排布,命中率不会像插一个字节这么夸张,但通常仍然远好于定长分块。给大文件加个头、给压缩包加注释、往虚拟机镜像里写日志,这类改动基本是「免费」的。
恢复和校验:备份的意义在后半段
只写得进、取不出的备份等于没有备份,所以我专门测了反向路径:
- 恢复最新快照:987 个文件/目录、1.43GB,4 秒完成(算上进程启动是 6.0 秒)
check --read-data-subset=10%:抽查 10% 的 pack 文件,1.2 秒,没有发现错误forget掉一个快照再--prune:重打包 1 个 pack、删掉 3 个旧索引,1 秒内完成
prune 这一项值得单独拎出来说。很多号称增量备份的工具只会加不会减,半年后仓库膨胀到接近两倍,用户在「删不掉」和「不敢清」之间来回纠结。restic 的 forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune 一条命令就把保留策略落实了,在 GB 级仓库上快到可以直接塞进每天的定时任务。
内存:小主机上必须先看的那个数
第一次全量备份,峰值内存 341MB。这个数字对 N100 这类八G内存的小主机无所谓,但对 512MB 内存的轻量云主机(很多人拿它当中转仓库)就很要命,跑着跑着被 OOM 杀掉,备份 silently 失败是最坏的情况。
restic 是 Go 写的,内存大头是 GC 的呼吸空间。加一个环境变量 GOGC=20 再跑同样的备份:峰值降到 234MB,耗时从 6.26 秒变成 6.51 秒,慢了不到 4%。也就是说在内存紧张的机器上,用 4% 的时间换 31% 的内存,完全划算。
增量备份(只改了一个文件)峰值只有 64.7MB。这个数才是日常定时任务真正吃掉的资源,别拿全量备份的内存去估算每日开销。
压缩档位:不要无脑开 max
restic 0.19 默认是 auto 档(zstd)。我用 41MB 纯文本日志测了三档:
- off:仓库 5.00MB,耗时 0.82 秒
- auto:仓库 265KB,耗时 1.05 秒
- max:仓库 310KB,耗时 1.07 秒
auto 把 41MB 压到 265KB,效果很漂亮。但 max 反而比 auto 大了 17%,连跑两遍结果完全一致——在这个数据上,更高的 zstd 档位带来的是更长的字典搜索和更大的头部开销,收益是负的。
再看照片视频这类本来就压过的数据:整个仓库的压缩比稳定在 1.00x,节省 0.07%,开什么档位都白搭,只会多烧 CPU。所以结论很干脆:用 auto,别碰 max。
三个真踩过的坑
一、webdav: 不是它的后端。 我第一反应是把仓库扔进坚果云这类 WebDAV 网盘,restic -r webdav:https://... init 直接报 invalid backend。它支持 local、sftp、rest(rest-server)、s3、b2、azure、gs、rclone,唯独没有 WebDAV。想用 WebDAV 网盘,得先用 rclone serve restic 在本地起一个 REST 服务当桥,或者干脆找支持 S3 的对象存储开仓库。
二、Windows 版没有 mount。 在 Windows 上敲 restic mount 会直接报 unknown command,这个子命令依赖 FUSE。想「像翻文件夹一样浏览旧快照」只能在 Linux / macOS 上做;Windows 下的替代做法是 restore 到临时目录看完删掉,1.4GB 也就几秒钟,实际用起来不算难用。
三、密码丢了就是丢了。 没有任何官方的找回途径,仓库里每个数据块都是用你的密码派生的密钥加密的。所以别把密码写在命令行参数里(进程列表一眼能看到),用 --password-file 指一个文件,并且把这个密码文件本身再备份到别处——硬盘挂了、密码文件跟着一起没,那堆加密数据就只是随机字节。
接到 NAS 或网盘上的日常用法
定时任务大概长这样:
restic -r sftp:nas:/volume1/backup backup D:\照片 D:\文档 --exclude-caches --compression auto
restic -r sftp:nas:/volume1/backup forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
在 Windows 上挂计划任务有两个细节容易翻车:一是把 RESTIC_PASSWORD 写进任务的环境变量或者用密码文件,别指望它弹窗让你输密码;二是仓库路径绝对不能放在被备份的目录里面,自己备份自己,第二天体积就能翻倍。
值不值得换?如果你现在的「备份」还是复制粘贴,那 restic 给你的其实不是速度,而是「敢删」这两个字——知道任何一次改动都能退回去,才敢真正动手收拾那堆乱了五年的照片。
你们那边备份是怎么做的,还在整盘拷吗?