我曾读到一句评论,说人分为两类:那些遭受过灾难性数据丢失的人,和那些将会遭受的人。试图找来源写博客时发现每个系统管理员都有改版引用,但核心一致。数据丢失发生得比希望频繁,多数人毫无准备。我小时候曾把全家照片从笔记本和台式机转存到外接硬盘,直到父亲想用其作电视接驳盒存储,被提示格式化,他确认后磁盘被重格。
正文
备份并不简单
另见 John Salvatier 的博客《现实有惊人数量的细节》。
我在某处读到一条评论,一直记着,大意是:“有两种人:已经经历灾难性数据丢失的人,和将要经历的人。”为了找出处,发现每个系统管理员都有自己的改写版,但意思都一样。数据丢失发生得比我们希望的多,而我们大多毫无准备——它几乎总在最糟的时候袭来。
我也有过类似经历。小时候我们把家庭照片从家里的笔记本和 PC 挪到一块外置硬盘上腾空间。一直挺好,直到某天我爸想拿这块盘当电视机顶盒的存储(那种老式机顶盒),系统提示要格式化。他照做了,磁盘被重新格式化,文件索引被删掉,我们面对一块名义上空的盘。
很容易怪他搞砸了,但入了技术行业才明白,这类错误是一连串失误造成的。第一,我们把所有照片放在一个地方,没做备份。第二,消费级软件通常会醒目地警告格式化磁盘会丢数据(那个机顶盒没有,界面很糟)。再说,凭什么指望一个非技术用户知道这些?
幸好照片最后恢复了,这算是一堂便宜的数据处理课。重要东西永远不能只存一处。可能出错的地方成千上万:硬盘会坏、会被偷,位会腐烂(机械硬盘有磁粒子,可能莫名其妙偏移;SSD 由 NAND 晶体管组成,会漏电,久了就损坏数据)。
所以第一条原则是拥有备份,也就是文件在别处有一份副本。这还不错。
但这没覆盖一块插着电的硬盘能闯的祸。勒索软件会加密你的文件,你可能犯下诚实错误比如删错文件,也可能犯下灾难性错误比如跑个脚本把所有东西覆盖成零。
所以备份不该是第一块盘的镜像,因为我们还想在搞砸时回到过去。这意味着用 RAID 1 之类的镜像磁盘方案不行。我们需要能快照的方法。
多久快照一次?就照片那个例子,也许该每周备份一次。丢掉6天23小时的数据可以接受。IT 里这叫恢复点目标(RPO),真实场景中,关键金融机构要求小于30秒,它们真的不能丢数据;一些小企业则是24小时或更久(如果它们真有灾难恢复策略的话)。
拍快照意味着存储负担不断增加。RPO 为24小时,一周会有7个快照,一个月30个,一年365个——如果你真不去修剪的话。所以你需要轮换备份。
假设我用天真做法,保留14天的快照。新快照进来,删掉最老的,加上最新的。很简单,但这强迫我时刻盯着。也许我数据很多,懒得检查过去两周里有没有东西损坏?但我也不能存一整年的备份,它们对我没意义。在第364天,一年里第2天到第3天之间发生了什么几乎没有意义。所以备份的粒度必须变化:离今天越近,快照越频繁;越久远,快照越稀疏。
也许每日备份每14天轮换,同时每周备份每7周轮换,每月备份每12个月轮换。这样效率高得多。但复杂度又涨了。我们现在有了GFS 轮换、基于快照的备份。这一串形容词还会继续变长,下面就能看到。
也许你去看 MPEG 如何压缩视频,着迷于电影里平静场景——主角说话但不动,背景完全静止——如何被用来压缩视频。你注意到视频由彼此相似的帧组成,只有某些运动能表示为向量,占很小存储。于是你得出很合逻辑的结论:快照也遵循同样模式。更进一步,文件改动遵循胖尾分布,给定时期内绝大多数文件根本不变,极少数一直在变。
所以显然不该存完全相同的文件副本,而要去重。需要引用已有文件时用硬链接。这样磁盘上只存一个文件,每个快照引用它。这也经得起备份轮换,因为我们从不删除文件,只删目录项。这正是 rsnapshot 的做法,最好称为增量备份,因为只存相邻快照之间的变化,而不是自上次完整备份以来的所有变化(那叫差分备份,恢复时更稳健,但为简短起见不展开)。
省存储不是唯一好处。开头提过,我们不会把所有东西存在一台机器上。这个过程显然还涉及网络,因为要把文件从一台机器传到另一台。去重备份节省大量带宽,用云服务当第二台机器时尤其重要,直接影响账单。
到这一步,我们造出了一个增量、去重、GFS 轮换、基于快照的备份。可以用 rsync 从主机拉文件,用 cronjob 跑备份脚本。可以在任意多台机器上运行,再加一台也很容易。更好的是文件元数据保留下来,访问权限和文件所有权都没问题。
受此鼓舞,我们想拿它备份有10个 Docker 容器的 homelab。后来从各机器日志发现备份失败,因为很多 Docker 容器会创建 root 拥有的文件,而你不小心就会建一个以默认用户运行的 cronjob。
更糟的是,几乎所有 web 应用都用某种数据库。数据库有时会把数据存在内存里,再批量刷到磁盘以提高性能。这意味着不走运时,从备份恢复会因数据损坏而失败。于是我们让备份同时 dump 数据库,并给它 Docker 卷上的完整文件系统权限。这应该能成!
然后你读到某款硬盘故障率奇高的事故,开始想是不是该把备份存在两台使用不同介质类型的机器上。这样特定硬件的故障就不太可能把备份全毁。说到物理安全,还要有一份异地备份,放在云上或亲戚家的机器上。这样电涌、洪水或火灾把它们全毁的可能性就极低。3-2-1 备份因此得名:3份副本,2种介质,1份异地。
假设你为异地备份选了云厂商,具体说是 Amazon S3 这样的对象存储。你很快发现现有方案不行:一,文件上传到 S3 会丢元数据;二,往 S3 传大量小文件的价格高得吓人(文件大小也遵循胖尾分布)。这两点让你最好把许多文件塞进一个 tarball,这样既保留文件元数据又保持低成本。但问题是怎么做?把所有东西塞进一个巨大的 tarball?显然不行,那样带硬链接的增量备份就没意义了。最好把一切切成干净的50MB块,但要做得可验证安全,祝你好运。
到这一步之前,自己造备份听起来像一个下午就能搞定的事,但这就是我会放弃的地方。为这一切付出的心智负担完全不值得。不如直接用久经考验的工具,比如 Borg 或 Restic,它们处理所有这些以及更多(加密、块级去重、校验和)。要万分感谢了不起的开源社区构建、维护并实际测试这些工具,同时尊重为此所需的大量试错——正是这些让所有复杂度对我们抽象掉了。
显然,如果你不实际测试恢复,这一切都白搭。所以这又是一篇数字卫生文章,会加进你的待办清单。只要每6个月跑一次恢复,你就能享受你的:
加密、块级去重、GFS 轮换、时间点归档、云端、3-2-1 备份方案
评论
讨论整体推崇“恢复才是备份的目的”,但在实现路径上分成两派:一派坚持测试恢复、异地备份和自动化监控,另一派认为普通用户按价值分级、用简单同步加历史版本就够,不必追求企业级完备。技术选型上也有专用仓库工具与 tar/rsync 老路线的分歧。
备份的真正价值在于可测试的恢复
- 多位从业者认为备份只是手段,恢复和演练才是业务核心;不测试恢复的备份没有意义,灾难恢复还要考虑系统本身而不仅是数据文件。(较多人) > 我们不是在做备份,而是在做恢复。(@AdieuToLogic)
- 有人的客户遭遇火灾和疫情封锁,靠异地备份、虚拟化和 VPN 迅速接管,说明恢复能力决定备份价值。(少数人)
普通家庭和普通用户不必上企业级加密去重方案
- 家用场景只需异地同步副本加历史版本,防止误操作;术语堆砌的复杂方案往往不是必要。(较多人) > 普通家庭不需要加密、分块、企业级那一套,一个异地同步副本加额外备份流程就够了。(@justsomehnguy)
- 按数据价值分级:只对照片视频认真做 3-2-1,其余两份并信任大厂,先问是否真的值得。(较多人)
先有一份副本,别等完美方案
- 有备份总比没有好;洒液体后靠外置 SSD 克隆恢复,强调别拖延。(较多人) > 不要等完美备份方案,先让数据存在于不止一个地方。(@dsego)
- 老牌标准工具长期稳定,rsync+cron 多年不用修,笔记本丢三次也能次日恢复。(较多人)
备份操作本身也可能造成数据丢失
- 有用户四次丢数据,其中一次是备份时脚本删源又删旧备份,因此对可重写介质警惕。(少数人) > 备份本身也是高风险活动。(@publlus_enigma)
同步副本不是备份,但有人就想要同步副本
- 少数人认为共享凭证的异地同步副本比传统备份更符合需求。(少数人) > 我不想要备份,我想要用共享凭证在地理上分离的同步副本。(@pizzafeelsright)
“简单复制文件”在真实世界从不简单
- 有人用 SharePoint 到 S3 的例子说明跨服务复制需要认证、断点续传、重试、加密、递归、防死循环等;AI 会走捷径。(少数人) > 告诉 AI“把文件从 A 复制到 B”不会满足基本需求,因为 AI 会走捷径。(@jongjong)
家用环境手动加提醒比全自动更可维护
- 有人手动运行 restic,用终端横幅提醒;生产系统才需要自动化监控。(少数人) > 生产系统当然要自动化和监控,但我个人机器上挺喜欢这个设置。(@smallerfish)
不控制数据规模,数据规模就会控制你的备份方案
- 有用户指出数据量膨胀会让备份选择走向灾难性后果。(少数人) > 如果不管住数据规模,数据规模就会控制你的备份选择,最后导致灾难。(@crossroadsguy)
有价值的补充
- Restic/Kopia 支持管道输入、完整性检查、去重和 FUSE 挂载;有人用“掷骰子随机恢复”脚本验证备份可用性。(@PunchyHamster)
- tar+zstd+gpg 配合 GNU tar 的 .snar 增量索引,可只上传增量到 Glacier 这类只写存储,避免复杂仓库格式。(@snizovtsev)
- ReaR 能在 Oracle Linux 上做裸机恢复,数据库配合 standby 和 rsync 处理临时文件;btrfs 快照复制因支持复杂而未用在关键区域。(@chasil)
- Docker 容器常生成 root 属主文件,备份失败可能来自以默认用户运行的 cron,甚至带来提权风险。(@innocent_name)
- 7zip 近期改动 FILEATTRIBUTEARCHIVE 位,暴露出 DOS 时代 BACKUP/RESTORE 的遗留假设:只考虑单次备份。(@bakinator)
- rsnapshot 约七千行 Perl,COPYING 文件已二十年,至今仍在维护,最近一次改动在六个月前。(@ryuuseijin)
- 有人把“加密、分块去重、GFS 轮转、时间点归档、云、3-2-1”整串术语当密码,调侃备份方案的术语堆砌。(@bloomingeek)