restic 是一个单文件的备份工具,11237567 字节的 exe,支持本地目录、SFTP、S3、B2 等几十种后端。它的核心是内容寻址的去重:同样的数据块只存一次。
拿 500 个文件、142169088 字节的数据做完整实测:初始化仓库 3.57 秒,首次备份 3.09 秒,改一个文件再备份 1.29 秒且只新增 82.662 KiB,恢复全部数据 4.84 秒。
一个 exe,135.6 MB 数据
restic --version
restic 0.19.1
restic init --repo D:\rk_repo
created restic repository 9c1f... at D:\rk_repo
| 项目 | 数值 |
|---|---|
| exe 体积 | 11237567 字节 |
| 源数据 | 142169088 字节(500 个文件) |
| 文件分布 | 20 个目录,单个 1 KB 到 1 MB 混合 |
| 初始化仓库 | 3.57 秒 |
| 仓库体积(空) | 约 1.1 MB |
初始化只花 3.57 秒,做的事就是创建一组目录结构加几个配置文件。仓库本身占 1 MB 左右,全部是元数据。
它没有守护进程,也没有数据库服务,所有状态都在那个仓库目录里。备份完把目录拷走,换台机器装上同版本 exe 就能读。
首次备份 3.09 秒,仓库几乎 1:1
restic backup D:\rk_src --repo D:\rk_repo
processed 500 files, 135.583 MiB in 0:02
snapshot 441dc709 saved
| 指标 | 数值 | 换算 |
|---|---|---|
| 备份耗时 | 3.09 秒 | 约 44 MB/s |
| 处理文件数 | 500 个 | — |
| 源数据 | 142169088 字节 | 135.6 MiB |
| 写入仓库 | 135.929 MiB(实存 135.672 MiB) | 备份报告值 |
| 新文件 / 新目录 | 500 个 / 21 个 | 全部首次入库 |
1.001 倍这个数字说明压缩几乎没起作用。原因是测试数据用 os.urandom 生成,本身已经是随机字节,没有任何可压缩的冗余。换成文档、日志、代码这类真实数据,压缩比通常在 2 到 3 倍。
44 MB/s 这个速度包含了读取 500 个文件、切块、算哈希、写入仓库全过程。单个文件越小,文件系统的元数据开销占比越高,所以小文件多的时候速度会掉下来。
改一个文件,第二次只加 0.4 MB
在第一次备份之后,往其中一个 4 KB 的文件末尾追加 4096 字节,再备份一次:
| 指标 | 第一次 | 第二次(追加 4096 字节) |
|---|---|---|
| 耗时 | 3.09 秒 | 1.29 秒 |
| 文件变化 | 500 new / 0 changed | 0 new / 1 changed / 499 unmodified |
| 本次写入 | 135.929 MiB | 82.662 KiB(实存 46.267 KiB) |
| 增量占总量 | — | 0.06% |
只在一个文件末尾追加了 4096 字节,实际写进仓库的是 82.662 KiB,比 4 KB 多了 20 倍。原因是 restic 按内容切块,改动会让后续块的边界偏移,连带重新存储若干块。这是内容寻址备份的固有代价,改文件头比改文件尾影响更大。
即便如此,0.06% 的增量也很划算:135.6 MiB 的数据,日常改一次只多存几十 KB。耗时从 3.09 秒降到 1.29 秒,因为 499 个文件的块算完哈希发现已存在,直接跳过写入。
恢复 4.84 秒,142173184 字节
restic restore latest --target D:\rk_restore --repo D:\rk_repo
restoring snapshot 441dc709 of [...]
Summary: Restored 502 files/dirs (135.6 MiB) in 0:04
| 指标 | 数值 |
|---|---|
| 恢复耗时(首次) | 4.84 秒 |
| 恢复耗时(热缓存) | 1 秒内 |
| 还原字节数 | 142173184 字节 |
| 还原文件数 | 521 个(含目录) |
| 与源数据差异 | 4160 字节(就是后来追加的那部分) |
首次恢复 4.84 秒,接着再恢复一次只要 1 秒内,因为文件还在系统缓存里。restic 自己的输出会把秒数取整,命令里看到的是 Restored 521 files/dirs (135.591 MiB) in 0:01。走网络后端时会受带宽限制,这个数字会明显变大。
还原后的字节数比源数据多 4160 字节,正好是第二次备份前追加的 4096 字节加上一点对齐开销。说明恢复的是最新快照,数据对得上。
压缩比 1.00x 是怎么来的
restic stats --repo D:\rk_repo --mode raw-data
Snapshots processed: 2
Total Blob Count: 577
Total Uncompressed Size: 136.374 MiB
Total Size: 136.046 MiB
Compression Progress: 100.00%
Compression Ratio: 1.00x
restic 0.14 之后默认开启压缩(zstd),但随机数据压不动,所以比值停在 1.00x。577 个块对应 500 个文件,说明平均每个文件切成 1 块多一点,块大小在 1 MB 上下。
换成可压缩的数据,这个比值会明显变化。135.6 MiB 的纯文本大概能压到 40 到 60 MiB,压缩比 2 到 3 倍。这也意味着用随机数据测出来的速度会偏保守,真实场景通常更快。
它和 kopia、duplicati 的分工
站内另外两篇分别是 kopia 和 duplicati。三者的共同点是都做增量、都支持加密、都能对接多种存储。区别在交互模型:restic 是纯命令行加脚本,没有常驻服务;duplicati 带 Web 界面,适合不想写脚本的人;kopia 两者都有。
restic 的优势是可脚本化:一行命令备份,一行命令恢复,退出码明确,适合放进定时任务或者 CI。代价是所有参数都要记,第一次用得翻文档。
它不含调度器,定时备份要靠系统计划任务或者 cron。这一点和 duplicati 相反,后者自带调度面板。
三条使用前必须知道的事
第一,仓库密码丢了数据就打不开,没有找回机制。密码存在环境变量 RESTIC_PASSWORD 里最省事,但意味着任何能读到这个变量的人都能解密备份。
第二,forget 和 prune 是两个动作。删快照只是标记,真正回收空间要跑 prune,而 prune 会重写仓库、耗时明显长于备份。135.6 MiB 的仓库 prune 一次通常要十几秒。
第三,备份前想清楚要排除什么。默认会把目录里所有东西都收进去,包括缓存和临时文件,那些东西天天变,会让每次备份都产生大量新块,去重效果大打折扣。









