服务器运行久了,总会积累越来越多的重要数据:网站代码、数据库备份、上传文件、配置文件、日志以及各种业务数据。
这些数据平时可能不会引起太多关注,但一旦遇到磁盘损坏、误删除、服务器被攻击或者系统迁移,能不能快速恢复就显得非常重要。
很多人会使用 tar 打包,再通过 scp 或 rsync 上传到另一台服务器。这种方式虽然简单,但随着数据量增加,会逐渐暴露出一些问题:
- 每次都要处理大量文件,备份耗时较长。
- 多次备份会产生大量重复数据,占用存储空间。
- 缺少统一的历史版本管理。
- 需要自己编写脚本处理备份保留和清理。
- 备份文件缺少统一的加密和完整性检查机制。
如果希望有一套更完善的备份方案,可以了解一下 Restic。
Restic 是一款开源、跨平台的备份工具,支持增量备份、数据去重、加密存储和多种存储后端。通过它,我们可以用相对简单的命令,为 Linux 服务器建立一套自动化备份方案。
本文将从实际使用出发,介绍 Restic 的安装、配置、备份、恢复和自动化运维。
一、Restic 是什么?
Restic 是一款使用 Go 语言开发的开源备份工具,支持 Linux、macOS、Windows 等操作系统。
它的设计目标比较明确:让备份过程尽可能简单,同时保证备份数据的安全性和存储效率。
与传统的文件打包方式相比,Restic 有几个比较重要的特点。
1. 增量备份与数据去重
Restic 不会在每次备份时都重新上传所有文件。
它会分析文件内容,将数据拆分成不同的数据块,并通过内容识别和去重机制,复用仓库中已经存在的数据。
例如,服务器第一次备份了一个 10 GB 的目录,第二天只修改了其中一部分文件,那么第二次备份通常只需要保存新增或发生变化的数据块。
这样可以减少重复数据的传输和存储开销。
2. 自动加密
Restic 在保存数据之前会进行加密。
备份仓库中的文件内容、文件名等信息不会以普通明文形式直接暴露。即使备份数据存储在远程服务器或对象存储中,也不意味着存储服务提供商能够直接读取备份内容。
需要注意的是,加密密码非常重要。如果丢失了访问仓库所需的密钥或密码,又没有其他可用密钥,就可能无法恢复数据。
3. Snapshot 快照管理
Restic 使用 Snapshot(快照)记录某个时间点的文件状态。
例如:
- 周一备份了一次。
- 周二修改了配置文件,再备份一次。
- 周三误删了一个目录。
即使当前服务器上的文件已经发生变化,也可以选择周一或周二的快照进行恢复。
这意味着 Restic 不只是保存一份文件副本,还能帮助我们管理历史版本。
4. 支持多种存储后端
Restic 不局限于本地磁盘,可以将备份保存到多种存储位置:
- 本地目录
- SFTP 服务器
- HTTP REST Server
- Amazon S3
- MinIO
- Backblaze B2
- Microsoft Azure Blob Storage
- Google Cloud Storage
- 其他兼容存储或通过 rclone 接入的服务
因此,我们可以根据实际环境选择备份目标。
例如,将业务服务器的数据备份到另一台独立服务器,或者备份到 S3 兼容对象存储中。
二、安装 Restic
Restic 支持多种操作系统,这里以 Linux 服务器为例。
1. 使用系统包管理器安装
Ubuntu / Debian:
sudo apt update
sudo apt install restic
CentOS / RHEL 系列可以根据系统版本和软件源情况安装:
sudo dnf install restic
如果系统软件源中的版本较旧,也可以从 Restic 官方发布页面下载对应平台的二进制文件。
官方地址:
https://github.com/restic/restic/releases
2. 验证安装
安装完成后,执行:
restic version
如果能够正常输出版本信息,就说明安装成功。
还可以查看帮助信息:
restic --help
Restic 采用子命令的方式组织功能,例如:
restic init
restic backup
restic snapshots
restic restore
restic forget
restic prune
每个子命令都有自己的参数,可以通过以下方式查看:
restic backup --help
三、初始化备份仓库
在使用 Restic 之前,需要先创建一个 Repository(仓库)。
可以将 Repository 理解为 Restic 专门用来存储备份数据的目录或远程存储空间。
一个仓库可以保存多个时间点的快照,Restic 会负责管理其中的数据块、索引和元数据。
1. 创建本地仓库
先创建一个目录:
mkdir -p /data/restic-repo
然后初始化仓库:
restic init --repo /data/restic-repo
首次初始化时,Restic 会要求输入仓库密码。
初始化成功后,就可以向这个仓库写入备份数据了。
需要注意,本地仓库只是为了方便演示。如果备份数据和业务数据放在同一块磁盘上,那么磁盘损坏时,两份数据可能同时丢失。
生产环境更建议使用独立存储设备、远程服务器或者对象存储。
2. 创建 SFTP 远程仓库
如果有另一台 Linux 服务器,可以通过 SFTP 将备份保存到远程机器。
假设:
- 远程服务器:
192.168.1.100 - SSH 用户:
backup - 远程仓库目录:
/srv/restic-repo
首先确保远程服务器已经安装 SSH 服务,并且备份用户拥有对应目录的读写权限。
然后配置 SSH 密钥登录,确保自动备份时不会出现交互式密码输入。
初始化远程仓库:
restic -r sftp:[email protected]:/srv/restic-repo init
Restic 会连接远程服务器,并在指定目录中创建仓库。
后续备份只需要使用相同的仓库地址即可。
3. 配置仓库环境变量
每次执行命令都指定 --repo 比较麻烦,可以通过环境变量配置仓库地址。
例如:
export RESTIC_REPOSITORY="sftp:[email protected]:/srv/restic-repo"
仓库密码也可以通过环境变量或密码文件提供。
生产环境更建议使用密码文件:
export RESTIC_PASSWORD_FILE="/etc/restic/password"
创建密码文件:
sudo mkdir -p /etc/restic
sudo sh -c 'printf "%s" "替换成你的强密码" > /etc/restic/password'
sudo chmod 600 /etc/restic/password
sudo chown root:root /etc/restic/password
这里的密码只是示例,实际使用时应该替换成随机生成的强密码。
配置完成后,执行:
restic snapshots
如果仓库还没有快照,可能会提示没有可用快照,这是正常现象。
特别提醒:Restic 仓库密码丢失可能导致备份数据无法恢复。不要只把密码保存在正在备份的服务器上。 应该将密码和必要的恢复信息安全地保存在独立位置。
四、执行第一次备份
仓库准备好之后,就可以开始备份数据了。
假设服务器上有以下目录:
/etc
/var/www
/data
我们希望备份系统配置、网站文件和业务数据。
1. 执行基础备份
执行:
restic backup /etc /var/www /data
Restic 会扫描这些目录,并将需要保存的数据写入仓库。
执行成功后,会输出类似信息:
repository ... opened successfully
using parent snapshot ...
Files: 1200 new, 0 changed, 0 unmodified
Dirs: 180 new, 0 changed, 0 unmodified
Added to the repository: 1.234 GiB
processed 1200 files, 2.345 GiB in 0:01
snapshot 12345678 saved
其中比较重要的是:
new:新增的文件。changed:发生变化的文件。unmodified:没有发生变化的文件。Added to the repository:本次实际新增到仓库的数据量。snapshot:本次备份生成的快照 ID。
实际输出会根据 Restic 版本和备份内容有所不同。
2. 排除不需要备份的文件
并不是所有文件都值得备份。
例如:
- 临时文件。
- 缓存目录。
- 日志文件。
- 程序运行时生成的临时数据。
- 可以重新下载或重新生成的文件。
可以通过 --exclude 排除指定路径:
restic backup \
/etc \
/var/www \
/data \
--exclude="/var/www/*/storage/logs/**" \
--exclude="/data/cache/**" \
--exclude="*.tmp"
如果排除规则比较多,也可以单独维护一个文件。
例如创建:
/etc/restic/excludes.txt
内容如下:
*.tmp
*.log
**/cache/**
**/tmp/**
**/node_modules/**
然后执行:
restic backup \
/etc \
/var/www \
/data \
--exclude-file=/etc/restic/excludes.txt
需要注意,排除规则应结合业务实际情况配置。不要为了减少备份量,把上传文件、业务附件等重要数据也排除掉。
3. 给备份添加标签
当一个仓库中保存了多台服务器或多种备份任务时,可以使用 Tag 区分不同的备份。
例如:
restic backup \
/etc \
/var/www \
--tag server-01 \
--tag web
后续查看快照时,就可以根据标签进行筛选。
标签对于多服务器、多业务的备份管理很有帮助。
五、理解 Restic 的增量备份机制
第一次使用 Restic 时,很多人会关心一个问题:
如果每天都执行一次 restic backup,是不是每天都会重新上传全部文件?
答案是否定的。
Restic 会通过文件扫描、内容分块和数据去重等机制,尽可能复用仓库中已经存在的数据。
1. 什么是内容定义分块?
Restic 不只是简单地判断文件有没有修改,而是会将文件内容拆分成多个数据块。
它使用 Content Defined Chunking(内容定义分块,简称 CDC)技术,根据文件内容确定分块边界。
这样做有一个好处:当文件中间插入或删除了一部分内容时,后续数据块的边界不一定全部发生变化。
相比固定大小分块,内容定义分块通常更容易识别文件修改前后仍然相同的数据区域。
2. 什么是数据去重?
假设有两个目录:
/data/project-a
/data/project-b
它们里面有一些相同的文件。
如果使用普通压缩包分别备份,重复内容通常也会被重复保存。
而 Restic 会识别已经存在的数据块,在符合条件时直接复用,不需要再次存储相同内容。
这就是数据去重。
3. 为什么第二次备份会更快?
第一次备份时,Restic 需要读取并保存大量数据。
第二次备份时,如果大部分文件没有变化,就可以复用之前保存的数据块,只处理新增或变化的部分。
例如:
| 备份时间 | 文件总量 | 本次新增数据 |
|---|---|---|
| 第一天 | 10 GB | 10 GB |
| 第二天 | 10 GB | 100 MB |
| 第三天 | 10 GB | 20 MB |
| 第四天 | 10 GB | 0 MB |
以上只是用于说明机制的假设数据,实际新增量取决于文件变化情况和分块结果。
需要注意,增量备份不代表完全不读取文件。Restic 仍然可能需要扫描文件系统并读取文件内容,以判断哪些数据需要保存。
六、查看和管理备份快照
Restic 使用 Snapshot 管理每一次备份。
每次成功创建备份后,通常都会生成一个新的快照。
1. 查看所有快照
执行:
restic snapshots
输出类似:
ID Time Host Tags
-------------------------------------------------------
a1b2c3d4 2025-11-01 02:00:00 server-01 web
e5f6g7h8 2025-11-02 02:00:00 server-01 web
i9j0k1l2 2025-11-03 02:00:00 server-01 web
每个快照都有独立的 ID,可以通过它选择需要恢复的备份。
2. 查看快照中的文件
例如:
restic ls latest
可以查看最新快照中保存的文件和目录。
如果希望查看指定快照:
restic ls a1b2c3d4
3. 比较两个快照
如果想知道两次备份之间有哪些变化,可以使用 diff:
restic diff a1b2c3d4 e5f6g7h8
这对于排查文件变化、确认误操作以及检查备份内容非常有用。
4. 查看仓库统计信息
执行:
restic stats
可以查看仓库的基本统计信息。
如果想查看最新快照对应的数据量:
restic stats latest
如果想了解去重前的数据量:
restic stats --mode raw-data latest
通过对比数据量,可以大致了解去重带来的存储节省效果。
七、如何恢复备份数据?
备份的最终目的不是保存数据,而是在需要的时候恢复数据。
Restic 提供了 restore 命令,可以将指定快照中的文件恢复到目标目录。
1. 恢复整个快照
例如,将最新快照恢复到 /tmp/restore:
restic restore latest --target /tmp/restore
执行后,Restic 会将快照中的文件恢复到目标目录。
如果需要恢复某个历史快照:
restic restore a1b2c3d4 --target /tmp/restore
2. 只恢复指定目录
如果只需要恢复网站目录,可以使用 --include:
restic restore latest \
--target /tmp/restore \
--include /var/www
这样就不需要恢复整个快照。
3. 恢复指定文件
例如,只恢复某个配置文件:
restic restore latest \
--target /tmp/restore \
--include /etc/nginx/nginx.conf
恢复完成后,文件会位于:
/tmp/restore/etc/nginx/nginx.conf
建议先恢复到临时目录,检查文件内容和权限,再决定是否覆盖生产环境中的文件。
4. 挂载仓库查看历史文件
除了 restore,Restic 还支持通过 mount 将仓库挂载成一个可浏览的文件系统。
例如:
mkdir -p /mnt/restic
restic mount /mnt/restic
挂载成功后,可以在对应目录中浏览历史快照。
这种方式适合需要查找某个历史文件,但又不确定具体快照 ID 的场景。
具体使用还需要系统支持 FUSE,Windows 等平台的挂载方式有所不同。
八、配置备份保留策略
如果每天都执行一次备份,快照数量会不断增加。
虽然 Restic 会进行数据去重,但长期保留所有历史快照,仍然可能占用较多存储空间。
因此,需要制定合理的备份保留策略。
常见策略如下:
| 类型 | 保留数量 | 说明 |
|---|---|---|
| 每日备份 | 7 | 保留最近 7 天 |
| 每周备份 | 4 | 保留最近 4 周 |
| 每月备份 | 6 | 保留最近 6 个月 |
| 每年备份 | 2 | 保留最近 2 年 |
可以使用 forget 命令实现:
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--keep-yearly 2
执行前建议先使用 --dry-run:
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--keep-yearly 2 \
--dry-run
它只会展示计划删除的快照,不会真正执行删除操作。
1. Forget 和 Prune 有什么区别?
这两个命令很容易混淆。
简单来说:
forget:删除不再需要的快照记录。prune:清理仓库中已经没有快照引用的数据块,回收实际存储空间。
例如:
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6
这一步主要处理快照的保留策略。
随后执行:
restic prune
清理不再被快照引用的数据。
也可以使用 --prune 将两步合并:
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--prune
需要注意,prune 可能涉及数据包重写和远程数据传输,执行时间可能比较长,而且执行期间仓库会被锁定,影响其他备份任务。
因此,生产环境建议将清理任务安排在备份低峰期,而不是每次备份完成后都立即执行。
九、搭建 Linux 服务器自动化备份
前面介绍了 Restic 的基本操作,但实际生产环境中,不可能每天手动执行备份。
接下来通过 Shell 脚本和 Cron,搭建一个简单的自动化备份方案。
1. 准备配置文件
先创建配置文件:
sudo mkdir -p /etc/restic
sudo vim /etc/restic/backup.env
配置内容:
export RESTIC_REPOSITORY="sftp:[email protected]:/srv/restic-repo"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
设置权限:
sudo chown root:root /etc/restic/backup.env
sudo chmod 600 /etc/restic/backup.env
前面已经创建了密码文件,这里不再重复配置。
2. 编写自动备份脚本
创建脚本:
sudo vim /usr/local/bin/restic-backup.sh
脚本内容:
#!/usr/bin/env bash
set -Eeuo pipefail
CONFIG_FILE="/etc/restic/backup.env"
LOG_DIR="/var/log/restic"
LOG_FILE="${LOG_DIR}/backup.log"
mkdir -p "${LOG_DIR}"
# 加载仓库配置
source "${CONFIG_FILE}"
# 备份目录
BACKUP_PATHS=(
"/etc"
"/var/www"
"/data"
)
# 排除规则
EXCLUDE_FILE="/etc/restic/excludes.txt"
# 记录日志
exec >> "${LOG_FILE}" 2>&1
echo "========================================"
echo "Backup started at: $(date '+%F %T')"
# 执行备份
restic backup \
"${BACKUP_PATHS[@]}" \
--exclude-file="${EXCLUDE_FILE}" \
--tag "server-01" \
--tag "daily"
echo "Backup finished at: $(date '+%F %T')"
设置执行权限:
sudo chmod 700 /usr/local/bin/restic-backup.sh
这里使用了 Bash 数组保存备份目录,避免目录路径中存在空格时出现参数解析问题。
脚本中使用 set -Eeuo pipefail,可以让脚本在发生错误时尽早退出,避免备份失败后继续执行后续操作。
需要注意,set -e 并不能替代完整的错误监控。生产环境还应该结合退出码、日志和告警系统判断任务是否成功。
3. 配置排除规则
创建:
sudo vim /etc/restic/excludes.txt
例如:
*.tmp
*.log
**/cache/**
**/tmp/**
**/node_modules/**
根据实际业务调整排除规则。
4. 手动执行测试
先手动执行脚本:
sudo /usr/local/bin/restic-backup.sh
查看日志:
tail -f /var/log/restic/backup.log
确认备份成功后,再配置定时任务。
5. 使用 Cron 定时备份
编辑 root 用户的定时任务:
sudo crontab -e
添加:
0 2 * * * /usr/local/bin/restic-backup.sh
表示每天凌晨 2 点执行一次备份。
如果希望每周执行一次仓库清理,可以单独配置清理任务:
0 4 * * 0 /usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --keep-yearly 2 --prune
不过,这里需要注意:
- 执行清理命令的用户必须能够读取对应的仓库配置和密码文件。
- 清理操作可能耗时较长,应根据仓库大小和网络情况安排时间。
- 应确保清理任务不会与其他备份任务冲突。
- 建议先使用
--dry-run检查保留策略。
如果使用的是不同的执行用户,需要为清理任务加载相同的 RESTIC_REPOSITORY 和 RESTIC_PASSWORD_FILE 环境变量。
十、备份仓库检查与生产环境注意事项
自动备份配置完成后,并不意味着备份系统已经可靠。
一个真正可用的备份方案,还需要考虑数据完整性、恢复能力、权限隔离和异常监控。
1. 定期检查仓库
Restic 提供了 check 命令,用于检查仓库的结构和数据一致性。
执行:
restic check
如果希望进一步读取并校验备份数据,可以执行:
restic check --read-data
这会读取仓库中的数据进行更全面的检查,仓库较大时可能耗时较长。
因此,可以根据实际情况安排定期检查,而不是每次备份后都执行完整的数据读取校验。
2. 备份数据库时要保证数据一致性
如果服务器运行着 MySQL 或 PostgreSQL,不建议直接将正在写入的数据库数据目录交给 Restic 备份。
例如,直接备份 MySQL 的数据目录:
restic backup /var/lib/mysql
并不能自动保证备份时数据库处于一致状态。
更合理的方式是:
- 使用数据库自身的备份工具生成一致性备份。
- 将生成的备份文件保存到独立目录。
- 使用 Restic 备份这些文件。
- 定期验证数据库备份能否正常恢复。
例如,可以先使用 mysqldump 或其他适合业务规模的数据库备份方案生成文件,再执行 Restic 备份。
对于 PostgreSQL,可以使用 pg_dump、pg_basebackup 等工具,根据恢复目标选择合适的方式。
3. 不要让备份和业务数据处于同一个故障域
如果业务服务器和备份仓库都在同一台机器上,那么:
- 磁盘损坏可能导致两份数据同时丢失。
- 服务器被入侵后,攻击者可能同时删除业务数据和备份。
- 机房故障可能导致两份数据都无法访问。
因此,建议将备份保存到独立的远程存储中。
如果条件允许,可以进一步采用异地备份策略。
4. 做好备份权限隔离
备份账号不应该拥有远程服务器的全部权限。
可以专门创建一个备份用户,只允许访问指定的仓库目录。
如果使用支持追加写入模式的存储服务,还可以考虑将备份写入权限和删除权限分离。
这样即使业务服务器被入侵,攻击者也不一定能够直接删除所有历史备份。
需要注意,追加写入模式也不是万能的。日常备份账号和执行 forget、prune 的管理账号应尽可能分离。
5. 定期进行恢复演练
这是最容易被忽略、却非常重要的一点。
不要只关注备份任务有没有执行成功,还要定期验证数据能否恢复。
可以设计一个简单的恢复演练:
- 创建一个测试文件。
- 使用 Restic 备份。
- 修改或删除原始文件。
- 从历史快照恢复。
- 检查恢复后的文件内容是否正确。
例如:
mkdir -p /tmp/restore-test
restic restore latest \
--target /tmp/restore-test
生产环境中,还应该定期验证数据库恢复、应用启动和配置文件完整性。
只有经过恢复验证的备份,才真正具备灾难恢复价值。
十一、总结
Restic 是一款非常实用的开源备份工具。它通过增量备份、数据去重、加密存储和快照管理,解决了传统文件打包备份在存储效率、历史版本管理和数据安全方面的一些问题。
本文从实际使用出发,介绍了 Restic 的安装、仓库初始化、数据备份、快照管理、文件恢复、保留策略以及自动化备份。
如果只是个人使用,可以从本地仓库开始,熟悉 backup、snapshots 和 restore 等常用命令。
如果用于生产环境,建议至少做到:
- 使用独立的远程存储保存备份。
- 使用密码文件管理仓库密码,并做好异地保管。
- 配置自动化备份和历史快照保留策略。
- 定期检查仓库完整性。
- 对数据库采用一致性备份方案。
- 定期执行恢复演练。
- 做好备份账号和仓库管理权限隔离。
最后,记住一个原则:
备份不是为了证明数据已经保存,而是为了在数据丢失时能够可靠地恢复。