一、3-2-1 到底指什么:三个数字各管一件事

3-2-1 备份原则是备份行业里最基础也最常被误读的一条规则。误读的表现是很多人以为它是一个「存储方案推荐」,其实它是一条容灾约束条件,三个数字各自约束一个独立的失效维度。
第一个 3:至少保留 3 份数据副本。这一条防的是「数据被误删或被覆盖」。任何一份数据都不能是唯一的一份——勒索软件加密你唯一的文件时,你连恢复的素材都没有。值得注意的是,原始生产数据本身就算一份副本,所以 3 份意味着你还需要额外做 2 份备份。
第二个 2:至少 2 份副本存在不同的介质或不同的存储系统。这一条防的是「存储介质整体损坏」。两块同型号的硬盘放在同一台机器上,同时坏掉的概率远高于一块;同一个对象存储桶的两份快照,本质上还是一份数据。这条约束经常被忽略——很多人在同一台 VPS 上做了两个备份目录,以为这算 2 份,但机器一坏,全没了。
第三个 1:至少 1 份副本放在异地(offsite)。这一条防的是「机房级故障」。火灾、地震、机房断电、机房网络中断、误操作导致整机重装——这些都会同时毁掉同一机房里的所有副本。异地副本还额外防一类问题:勒索软件如果横向移动到你的备份挂载点,本地副本也会被加密。
把三个数字翻译成一句可执行的话:生产数据 + 本机备份 + 异地备份,三份,其中两份在不同存储系统上,一份在物理上不与你同一台机器。
常见的一种实现组合是这样:
- 副本一:生产服务器上的原始数据(在跑业务的那台机器上)
- 副本二:同一台服务器或另一台机器上的本地备份(用不同磁盘、不同挂载点)
- 副本三:异地存储(对象存储桶、另一台异地 VPS、或者 NAS)
满足这个结构,你的备份才算符合原则。只有「生产机 + 同一块盘上的压缩包」是最常见的失败配置。
一个必须澄清的点:3-2-1 不是「备份三次」,而是「保留三份副本」。同一个备份任务把同一份数据反复写三遍,不增加任何容灾能力。
二、单机怎么实现:restic 与 borg 的对比和安装

在单机上做备份,2026 年有两个主流选择:restic 和 borg。两者都是去重、增量、加密、压缩的工具,理念接近,实现细节有差异。
先说共同点。两者都做块级去重:第一次备份时所有数据都写进去,之后每次备份只写变化的块。所以第二次备份 100GB 数据,实际占用可能只有几 GB。两者都支持加密,备份文件在远端是密文,泄露了也读不出内容。两者都支持快照式的目录结构,能看历史版本。
差异主要有三点。
第一,borg 的仓库是单个文件加索引,备份到远端用 SSH 和 rsync 协议;restic 的仓库是对象存储风格的目录,用自己的加密层。borg 的优势是可以直接 borg mount 挂载成一个文件系统目录,浏览备份非常方便。restic 的优势是后端选择多,S3、B2、SFTP、REST 都能用。
第二,restic 有 forget --prune 的保留策略机制,可以按「保留最近 7 个日备份、4 个周备份、12 个月备份」这种维度自动清理旧版本,borg 需要写脚本。
第三,restic 有一个独有的特性是 --cache-dir 加 --repository 的两层缓存机制,能让 --check 更高效。
装 restic 的步骤:
# Debian/Ubuntu
sudo apt install restic
# 或者官方二进制
sudo wget https://github.com/restic/restic/releases/download/v0.17.3/restic_0.17.3_linux_amd64.bz2 -O /tmp/restic.bz2
sudo bunzip2 /tmp/restic.bz2 && sudo install /tmp/restic /usr/local/bin/restic
restic version
初始化仓库并配置密码:
# 初始化 S3 兼容后端的仓库
export AWS_ACCESS_KEY_ID=你的key
export AWS_SECRET_ACCESS_KEY=你的secret
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/你的桶/vps-backup
export RESTIC_PASSWORD_FILE=/root/.restic-password
echo "一个足够长的随机密码" > /root/.restic-password
chmod 600 /root/.restic-password
restic init
密码文件权限必须是 600,不然 restic 会拒绝执行,这是它防止密码被其他用户读到的设计。
用 SFTP 后端也是常见选择:
export RESTIC_REPOSITORY=sftp:[email protected]:/var/backups/vps
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init
开始备份:
# 备份 /var/www 和 /etc,保留最近 7 天、4 周、6 个月
restic backup /var/www /etc \
--tag web-config \
--exclude '*.tmp' \
--exclude '/var/www/cache'
# 查看快照
restic snapshots
# 查看某个快照里有什么
restic ls latest
# 检查仓库完整性(重要,定期做)
restic check --read-data-subset=5%
restic check --read-data-subset=5% 是性价比最高的做法:随机抽 5% 的数据块实际读取校验,能发现大部分静默损坏,而完整 --read-data 在大仓库上要跑很久。
borg 的对应命令:
sudo apt install borgbackup
# 客户端
borg create --stats --list ::archive-{now} /var/www /etc
borg list ::archive
borg info ::archive
borg 的 borg init --encryption=repokey 或 repokey-blake2 是推荐选项,none 加密模式只适合纯本地备份。
三、异地存储怎么选:三类方案的真实取舍

异地备份的目标存储有三大类,每一类的成本、可靠性和操作复杂度都不同。这一节按实际场景给建议。
第一类是对象存储(S3 兼容、Backblaze B2、阿里云 OSS、腾讯云 COS)。这是最主流的选择,理由有三个:容量按量付费不需要预先买盘、跨区域复制是内置能力、durability 通常标称 11 个 9。restic 对 S3 的支持也是最完善的。
成本可以算出来。以渠道库里能查到的真实价格作为对照基准,再套用对象存储的计费模型:
sixtynet LAX-Storage-1TB 700.00 美元 / 年 → 折合每月 58.33 美元
8 核 CPU、8 GB 内存、1000 GB 磁盘、10000 Mbps 带宽、15000 GB 月流量
每 GB 磁盘 0.058 美元、每 GB 内存 7.29 美元、每 TB 流量 3.982 美元
sixtynet LAX-Storage-500G 400.00 美元 / 年 → 折合每月 33.33 美元
4 核 CPU、4 GB 内存、500 GB 磁盘、10000 Mbps 带宽、10000 GB 月流量
每 GB 磁盘 0.067 美元、每 GB 内存 8.33 美元、每 TB 流量 3.413 美元
拿 LAX-Storage-1TB 当异地备份机来算:58.33 美元/月的机器,1000 GB 磁盘,按备份占七成算是 700 GB 有效备份空间,每 GB 空间成本 58.33 / 700 = 0.083 美元。对比对象存储的定价结构,它没有按请求次数计费,也没有 egress 流量费(从桶里下载数据通常免费或者很低)。
restic 的去重让这个账变得更好看。假设你的生产数据 100 GB,每天增量 2 GB,用 restic 备份到一个月:第一个备份写 100 GB,之后每天只写变化块,去重后每个快照的实际增量只有几百 MB 到 2 GB。一个月 30 个快照,粗算占 150 GB 到 160 GB。占 1000 GB 磁盘的 16% 左右。
如果用对象存储,restic 每次备份是完整快照视图但底层去重,实际存储量也是接近增量的量级。同样 160 GB 的数据在对象存储里按每 GB 每月的标准存储价计算,成本通常在每月几美元的量级,比 58.33 美元的整机便宜得多。
所以结论是:纯粹为了存备份,选对象存储;要「备份机本身还能跑点别的」,选另一台 VPS。
第二类是另一台 VPS 跑 SFTP 或者跑 restic 的 REST 服务端。它的优势是你可以完全掌控,可以有公网 IP 直接拉取,不用担心对象存储的区域限制。劣势是容量要一次性买,而且这台机器自己也需要备份——不过备份机通常只存加密后的备份文件,被入侵了也读不出内容,攻击价值低。
选这类时,看重的是三件事:磁盘单价、带宽(恢复数据时要从它下载,10 TB 流量只够拉 10 TB)、以及稳定性。上面的 LAX-Storage 系列每 GB 磁盘 0.058 到 0.067 美元、每 TB 流量 3.4 到 4.0 美元,在存储型产品里属于单价低的一档。
第三类是 NAS 或家用存储。这适合纯个人用户,数据完全在自己手里。但它有一个致命问题:它和你的家在同一地点,家着火了或者进水了,NAS 和你的电脑一起没了。真要这么用,必须再加一层对象存储。
还有一个变体值得知道:把备份写到「异地但同服务商」的位置,比如同一家 VPS 商家的另一个机房。这比同一台机器上的另一个目录强得多,但要注意跨机房传输是否产生流量费。
四、加密与密钥管理:备份方案里最容易翻车的一环

备份数据在异地存储、加密是强制的——这一条没有讨论空间。真正的问题是怎么做才不把自己锁在门外。
restic 的加密模型:仓库本身用 RESTIC_PASSWORD(或其文件)作为主密钥派生出加密密钥,所有备份数据在写入前就已加密。攻击者拿到仓库文件,没有这个密码就完全读不出内容。这意味着即使你的对象存储桶被泄露,攻击者也拿不到明文。
这也是异地备份用 restic/borg 而不是明文 rsync 的核心理由。
但密钥管理是实践中最容易出错的地方。几种做法及其风险:
第一种,把密码写在环境变量里。方便,但 ps aux 能看到进程环境,任何能读该用户进程的人都能拿到。生产环境不建议。
第二种,把密码放在 root 权限 600 的文件里。常见做法,风险可控,但要注意备份的是「这台机器上的文件」——如果这台机器被入侵,密码文件同样会暴露。
第三种,用 systemd credential 或 keyring 托管。稍微复杂,但避免了明文落盘。
第四种,也是最推荐的:密码本身存在别的地方(密码管理器),需要备份时人工或通过脚本注入。这条路的缺点是自动化恢复时需要人工介入——但备份恢复本来就应该有人工介入环节。
无论用哪种,都要遵守两条纪律。第一,永远保留一份离线副本。加密备份的密码丢了,备份就等于不存在,而且因为数据是加密的,没有任何绕过办法。第二,定期验证密码可用。最简单的验证就是做一次真实的恢复演练(第八节)。
一个实用的密钥轮换流程:
# 查看当前仓库密钥 ID
restic key list
# 添加新密钥(保留旧密钥直到新密钥验证过)
restic key add
# 测试新密钥能读
restic snapshots
# 确认无误后删除旧密钥
restic key remove <旧密钥ID>
删除旧密钥是不可逆操作,必须在验证新密钥能正常读取之后。
还有一个加密相关的配置项:restic backup --exclude 的排除规则和加密无关,但 restic init --repository-version 2 可以启用仓库 v2 格式,对大量文件和超长路径有更好的支持。
密钥的存放介质选择也有讲究。密钥写在启动脚本里,脚本需要 root 才能读,但备份任务本身可能以非 root 用户运行,结果就是任务静默失败。解决办法是让任务以 root 运行并显式指定 RESTIC_PASSWORD_FILE,同时在脚本里检查权限:
#!/bin/bash
set -euo pipefail
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/你的桶/vps-backup
export RESTIC_PASSWORD_FILE=/root/.restic-password
[ -r "$RESTIC_PASSWORD_FILE" ] || { echo "密码文件不可读" >&2; exit 1; }
restic backup /var/www /etc --tag scheduled
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
set -euo pipefail 这一行很重要:备份失败时脚本必须以非零状态退出,否则 cron 不会告警,你会在某天需要恢复时才发现最后一次成功是三个月前。
五、备份哪些数据:值钱的东西和常见遗漏

备份的核心不是「备份得多」,而是「恢复得出来」。这一节讲该备份什么、不该备份什么,以及最常被漏掉的几样东西。
不该备份的有三类。第一类是可重新生成的数据:node_modules、vendor 目录、pip 缓存、Docker 的中间层、编译产物。这些重新装一次就有,备份它们纯粹浪费空间和时间。用 restic 的 --exclude 排除:
restic backup /var/www \
--exclude node_modules \
--exclude vendor \
--exclude '.cache' \
--exclude '*.log'
第二类是临时文件:/tmp、/var/tmp、编辑器备份文件。
第三类是大而可再生的对象:虚拟机镜像、容器镜像层。如果你的站点是 Docker 部署的,需要备份的是 compose 文件和挂载出来的数据卷,不是镜像本身。
该备份的,值得单独列一张清单:
| 内容 | 路径示例 | 丢了会怎样 |
|---|---|---|
| 网站代码 | /var/www、/srv/app、~/app |
站点直接不可访问 |
| 数据库 | /var/lib/mysql、/var/lib/postgresql |
用户数据全丢,最致命 |
| 配置文件 | /etc/nginx、/etc/apache2、/etc/systemd/system |
服务起不来或行为改变 |
| 证书与密钥 | /etc/letsencrypt、/etc/ssl/private |
HTTPS 失效,需重新签发 |
| SSH 授权密钥 | /root/.ssh、/home/*/.ssh |
失去管理入口 |
| 定时任务 | /etc/cron.d、/etc/cron.* |
业务逻辑静默停止 |
| 环境变量与密钥 | .env、secrets/ |
应用连不上外部服务 |
| 用户上传的文件 | /var/www/uploads |
用户内容丢失 |
最常被漏掉的三样:.env 这类环境变量文件、SSH 私钥、以及 systemd 的自定义 unit 文件。前两个漏掉的概率最高,因为它们不在「网站目录」里,用户凭直觉不会想到。
数据库的备份方式需要单独讲,因为直接备份数据库的数据目录是不安全的——正在写入的 InnoDB 文件拷出来可能是不一致的。需要用数据库自己的导出工具。
MySQL 的逻辑备份:
mysqldump --single-transaction --quick --routines --triggers \
--default-character-set=utf8mb4 数据库名 > /backup/db-$(date +%F).sql
--single-transaction 保证 InnoDB 表的一致性快照而不锁表,--quick 避免一次性把整表读进内存,--routines 和 --triggers 带上存储过程和触发器——漏掉这两个,恢复出来的库行为会不一样。
PostgreSQL:
pg_dump --format=custom --compress=9 -f /backup/db-$(date +%F).dump 数据库名
--format=custom 支持并行恢复和选择性恢复。
更彻底的做法是数据库的物理热备(MySQL 的 replica、PostgreSQL 的流复制),它保证的是实时可用,但成本更高,而且它本身也需要备份——否则复制链路断了你就发现两台机器数据一样错。
数据量大时,逻辑备份会非常慢,这时应该用物理备份工具(Percona XtraBackup、pgBackRest、barman)。判断标准:数据库小于 50 GB 用逻辑备份够用,超过这个量级考虑物理备份。
六、备份频率与保留策略:算清楚要存多少

备份频率和保留策略是一个整体决策,核心问题只有一个:你的恢复点目标(RPO)和恢复时间目标(RTO)是多少。
RPO 是你能接受的数据丢失量。RPO 是一小时,意味着你最多接受丢掉一小时的数据,那么备份频率至少是每小时一次。RTO 是你能接受的恢复时长。RTO 是两小时,意味着从「发现故障」到「服务恢复」必须在两小时内完成,这个数字决定了恢复方案的速度(从对象存储拉 500 GB 数据要多久、从备份机 rsync 拉要多久)。
按 RPO 划分频率档位:
| RPO 需求 | 建议频率 | 实现方式 |
|---|---|---|
| 24 小时 | 每天一次 | cron 每日任务 |
| 1 小时 | 每小时一次 | cron 每小时任务 |
| 15 分钟 | 每 15 分钟一次 | cron 或 systemd timer |
| 接近实时 | 持续 | 数据库复制 + 定期快照 |
但这里有一个容易被忽略的权衡:频率越高,备份窗口越多,对生产机的 IO 压力越大。restic 每次备份都要遍历文件、读取元数据,对一个文件数极多的目录(node_modules 那种),即使排除了也会消耗大量 inode 读取。生产机磁盘 IO 吃紧时,把备份放到业务低峰期跑,或者用 ionice 降低优先级:
# 低优先级运行备份,不抢占业务 IO
ionice -c3 nice -n 19 restic backup /var/www /etc --tag nightly
-c3 是 idle 优先级,nice -n 19 是最低 CPU 调度优先级。这样备份不会影响业务响应。
保留策略用 restic 的 forget 命令表达:
# 保留最近 7 个日备份、4 个周备份、6 个月备份、3 个年备份
restic forget \
--keep-hourly 24 \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--keep-yearly 3 \
--prune
这四条不是互斥的,restic 的语义是「满足任意一个条件的快照都保留」。也就是说,日备份保留 7 份,同时周备份保留 4 份、月备份保留 6 份、年备份保留 3 份——总共可能是 15 到 18 个快照,而不是 20 个。理解这个语义很重要,否则你会以为快照数量等于各条件之和。
--prune 会真正删除不再需要的快照数据,这一步是 IO 密集的,要放在低峰期。
算一下保留期的空间占用。假设生产数据 100 GB,每天增量 2 GB,用上面这套保留策略:
- 日备份 7 份:7 × 2 GB = 14 GB
- 周备份 4 份:4 × 2 GB = 8 GB
- 月备份 6 份:6 × 2 GB = 12 GB
- 年备份 3 份:3 × 2 GB = 6 GB
- 加上初始的全量 100 GB
总共约 140 GB。这是个可以接受的结果——1000 GB 的备份盘用掉 14%,500 GB 的用掉 28%。
容量规划的公式是:总占用 ≈ 初始全量 + 增量 × 保留快照数。拿这个公式去对照你的备份盘容量或对象存储预算,就知道够不够。
七、自动化:定时任务怎么写才不出错

手动执行备份和自动执行备份的可靠性差距很大,但自动任务本身也会出错。这一节给出一份可靠的实现。
先看 cron 版本的完整脚本:
#!/bin/bash
# /opt/backup/backup.sh
set -euo pipefail
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/你的桶/vps-backup
export RESTIC_PASSWORD_FILE=/root/.restic-password
export AWS_ACCESS_KEY_ID_ID=xxx
LOG=/var/log/backup.log
{
echo "=== 备份开始 $(date '+%F %T') ==="
# 1. 数据库逻辑备份
mysqldump --single-transaction --quick --routines --triggers \
--default-character-set=utf8mb4 mydb | gzip > /var/backups/db-$(date +%F).sql.gz
# 2. 文件备份
restic backup /var/www /etc /var/backups --tag auto --exclude '*.tmp'
# 3. 清理旧快照与本地临时备份
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
find /var/backups -name 'db-*.sql.gz' -mtime +7 -delete
# 4. 校验仓库完整性
restic check --read-data-subset=5%
echo "=== 备份完成 $(date '+%F %T') ==="
} >> "$LOG" 2>&1
注意 set -euo pipefail 和 >> "$LOG" 2>&1 的组合。前者保证任何一步失败脚本立刻退出并返回非零状态,后者保证日志不丢。
cron 条目:
# 每天凌晨 3 点 20 分执行(错开整点,避开备份服务的高峰)
20 3 * * * root /opt/backup/backup.sh
错开整点是有实际意义的:很多人写 0 3 * * *,而备份服务在整点的前后负载最高,错开几分钟能让备份更快完成。
systemd timer 版本(更推荐):
# /etc/systemd/system/backup.service
[Unit]
Description=VPS backup job
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/opt/backup/backup.sh
# 限制资源,避免备份抢满 IO
Nice=10
IOSchedulingClass=idle
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 03:20:00
RandomizedDelaySec=600
Persistent=true
[Install]
WantedBy=timers.target
Persistent=true 保证机器在这个时间点关机时,开机后补跑。RandomizedDelaySec=600 让执行时间随机浮动最多 10 分钟,避免所有机器同时打备份服务。IOSchedulingClass=idle 让备份的磁盘 IO 排在业务 IO 之后。
启用并验证:
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer
# 手动触发一次测试
sudo systemctl start backup.service
journalctl -u backup.service -n 50
自动化之后必须加两件事。
第一是失败告警。备份失败但没人知道,等于没有备份:
# 在脚本最后加:只有成功才发成功通知,失败走另一条路
if [ $? -eq 0 ]; then
/usr/local/bin/alert.sh "备份成功 $(date '+%F %T')"
else
/usr/local/bin/alert.sh "备份失败,检查 /var/log/backup.log"
fi
第二是异地验证告警。有一类故障是「备份任务每天都成功,但备份写到的是一个坏桶或者一个已经停服的服务」。用另一个渠道监控异地存储的写入时间戳,超过 24 小时没更新就告警。
八、恢复演练:多久做一次,怎么做才算数

备份的价值只有在恢复成功时才兑现。一个从没验证过的备份,成功率应该按零来算。这一节讲演练的频率和正确的做法。
演练的频率建议是每季度一次全量演练,加上每月一次抽样验证。理由是:全量演练耗时长(从异地拉 500 GB 数据可能要好几个小时),不适合频繁做;而每月一次抽样验证成本低,能及早发现「备份任务还在跑但数据已经损坏」这类慢性问题。
抽样验证的做法是从最新的快照里随机恢复几个文件出来:
# 列出快照里的文件
restic ls latest | head -50
# 恢复单个文件到临时目录
restic restore latest --include '/var/www/index.php' --target /tmp/verify
# 比对校验和
sha256sum /tmp/verify/var/www/index.php
关键是要做内容比对,而不只是看命令退出码。restic 内置了校验和校验:
# 校验恢复出来的文件内容是否与备份一致
restic restore latest --target /tmp/verify --verify
全量演练的完整流程应该是这样的:
1. 准备一台干净机器(规格接近生产机)
2. 从异地存储拉取最近一个快照
3. 恢复数据库:mysql < db-xxx.sql.gz
4. 恢复配置文件与网站代码
5. 启动服务:systemctl start nginx php-fpm mysql
6. 用真实 URL 验证:curl -sI https://你的域名 | head -1
7. 跑一遍关键业务流程(下单、登录、上传)
8. 记录恢复总耗时,作为 RTO 的实测值
9. 恢复完成后销毁这台测试机
第 6 步和第 7 步是关键。只验证「服务起来了」是不够的——配置里少一个环境变量,服务也能起,但功能是坏的。真实业务流的验证才能暴露问题。
演练要记录三个数字并追踪趋势:恢复总耗时(验证 RTO)、数据丢失时长(验证 RPO)、以及演练中发现的配置缺失项数量。
演练中发现的典型问题包括:数据库文件权限不对导致服务起不来、证书没备份导致 HTTPS 起不来、.env 没备份导致应用连不上外部 API、systemd unit 缺失导致服务不随开机启动。这四类问题只能靠演练发现。
顺便说一个反向建议:不要在生产机上做恢复演练。恢复会覆盖生产数据,出错的代价远大于演练收益。永远在另一台机器上演练。
九、什么情况下不该做全量备份

备份不是越多越好,有些场景下全量备份是错的选择。这一节讲三个反直觉的场景,以及每个场景的替代方案。
第一个场景:数据量大但变更率极低。比如一个 5TB 的媒体库,每天只有几十 MB 变化。restic 的去重让增量备份已经很小,但每次备份仍然要遍历 5TB 的文件元数据,这个遍历本身要几十分钟到几小时,而且每次都要重复做。
替代方案:改用文件系统层的快照(ZFS、LVM snapshot、Btrfs snapshot)。快照是秒级的,然后只备份「快照之间的差异」。zfs send/recv 加 zfs 增量是这类场景的标准解法。或者用 rsync --link-dest 做硬链接式增量,只传变化的文件。
第二个场景:数据本身可以重新生成,且生成成本低于存储成本。容器镜像、编译产物、依赖包——这些重新构建一次就行。
替代方案:把「生成配方」备份好(Dockerfile、package.json、lock 文件、CI 配置),不备份生成结果。恢复的时候跑一次构建。这个方案的好处是备份体积极小,而且恢复出来的版本一定和当前依赖一致。
第三个场景:数据库用了复制或有托管服务,备份能力已经由平台提供。
替代方案:不要重复备份,但要确认三件事:复制是否真的跨故障域(同一台机器上的两个从库不算)、备份快照的保留期是多久、以及平台的备份是否包含你需要的全部数据(有些托管服务只备份实例数据,不备份对象存储里的文件)。
第四个场景:单文件巨大(超过 100GB)且很少变化。
替代方案:对大文件单独处理,其余用 restic。restic 支持分块传输,但一个超大文件每次备份仍然要传全量。
第五个场景,也是最容易被忽视的:你只有一台机器,且它同时是生产机和备份目标机。这时候「备份」实际上是同一份数据的两份拷贝,共用同一个失败域。
替代方案:至少增加一份异地副本,哪怕只有最关键的数据。这份数据的成本远低于一次数据全丢的代价。
最后讲一个反向的检查——你的备份是否真的有效,取决于三个数字:最近一次成功备份的时间距今多少小时(超过 24 小时就该查)、异地副本的写入时间戳距今多少小时、以及最近一次恢复演练的日期距今多少个月(超过 3 个月就该做一次)。把这三个数字记在监控面板上,比记「备份任务运行成功」这个状态有用得多。
按你的情况,下一步该看哪家
上面讲的是判断标准,但多数人最后还是想问一句「那我该买谁」。按你的实际情况对照下面几条,直接去看对应的机型页比继续比价更快:
- 跑游戏服或实时业务:看上行抖动与防御能力,普通套餐往往不达标。看 iwebfusion 当前机型与价格
- 只是开发测试、临时用:按小时或月付,用完就删,别买年付。看 racknerd 当前机型与价格
价格与库存以商家页面当日显示为准,下单前建议先确认退款窗口与是否支持按月付费。
十、常见问题

3-2-1 备份原则具体是哪三个数字? 至少 3 份数据副本、至少 2 份副本存在不同的存储系统或介质、至少 1 份副本在异地。生产数据算第一份,所以实际需要额外做 2 份备份。注意是 3 份副本不是备份 3 次。
restic 和 borg 选哪个? 要支持 S3 等对象存储、需要保留策略自动清理,选 restic;要直接浏览备份内容、能用 SSH 推送到另一台机器,选 borg。两者都做块级去重和加密。
备份密码忘了,数据还能救回来吗? 救不回来。restic 和 borg 都是客户端加密,没有密码就没有解密途径。所以密码必须另外保存一份在密码管理器或离线介质上,并且定期验证。
备份任务每天显示成功,但仓库其实是空的,怎么排查? 依次检查:仓库路径变量是否正确(echo $RESTIC_REPOSITORY)、备份是否真的产生了快照(restic snapshots 看数量是否随时间增加)、快照的标签是否匹配(restic snapshots --tag auto)、以及 restic check 是否报告错误。常见原因是变量在 cron 环境里没加载。
VPS 被挖矿了,备份会不会也被加密? 有可能,所以备份必须存在生产机之外,且不能以读写方式挂载到生产机上。用 restic 推到对象存储,攻击者即使拿到凭据也只能提交新的加密数据,原始备份文件本身在远端是密文且不受影响。永远不要把备份目录用 NFS 或 CIFS 挂载回生产机。
需要备份数据库吗? 需要,而且是最需要备份的东西。但要备份的是逻辑导出或物理备份文件,不是数据库的数据目录。用 mysqldump --single-transaction 或 pg_dump,注意带上存储过程和触发器。
1TB 的数据备份一次要多久? 取决于带宽和文件数量。传 1TB 数据到异地,100 Mbps 的上传带宽理论上是 22 小时,实际会因为协议开销和文件数量更多;1 Gbps 大约 2.2 小时。restic 因为有去重,第二次及以后的备份只传增量,通常是首次的几十分之一。
备份应该放云盘还是另一台 VPS? 纯存储用对象存储更便宜也更省心;要「备份机本身还能跑别的」或者需要公网直连拉取,选另一台 VPS。如果数据合规不允许出境,那就选同区域的对象存储或同城另一台机器。
怎么知道我的备份够不够? 看三个数字:最近一次成功备份距今多少小时、异地副本写入时间戳距今多少小时、最近一次恢复演练距今多少个月。第一个超过 24 小时说明任务有问题,第二个超过 24 小时说明异地链路有问题,第三个超过 3 个月说明你的恢复流程未经检验。
只备份网站代码不备份数据库行不行? 不行。代码可以从 Git 仓库重新拉,但数据库里的用户数据往往不在任何版本控制里。正确做法是代码用 Git 管理,备份只管数据库、配置、证书、密钥这些 Git 管不了的部分。
restic 备份时 CPU 占用很高影响业务怎么办? 用 ionice 和 nice 降低优先级:ionice -c3 nice -n 19 restic backup ...,或者放到业务低峰期跑。文件数量极多的目录(node_modules)即使排除了也会消耗 inode 读取,用 --exclude 提前排除掉。
备份文件本身占多少空间怎么估算? 公式是「初始全量 + 增量 × 保留快照数」。100 GB 数据、每天 2 GB 增量、保留 7 日 + 4 周 + 6 月 + 3 年大约是 140 GB。restic 的去重让这个数远小于「全量 × 快照数」。

喜欢
高兴
鬼脸
呵呵
无聊
伤心