「我们有备份」和「我们能恢复」之间,隔着一次真实的演练。微型博客的数据是用户几年的创作、关系与互动,一旦丢失就是不可逆的信任崩塌;而勒索软件、误操作、机房故障、云厂商事故都在提醒:数据保护不是「买个备份服务」就完事的。容灾工程要回答两个数字:出事多久能恢复(RTO)、能丢多少数据(RPO),再用备份、多活、演练把这套承诺变成可验证的能力。本文讲透这套体系。
前置:数据模型与 Schema 演进 、图片与对象存储 、多租户隔离设计 、可观测性与 SRE 。
目录
- 1. 容灾目标:RTO 与 RPO
- 2. 备份策略:全量、增量与 3-2-1
- 3. 备份的安全:加密、不可变与隔离
- 4. 数据库备份:PITR 与持久化取舍
- 5. 对象存储与媒体资产保护
- 6. 多活与故障切换架构
- 7. 数据一致性校验
- 8. 恢复演练:从有备份到能恢复
- 9. 降级与兜底策略
- 10. 速查表与一句话记忆
- 延伸阅读
1. 容灾目标:RTO 与 RPO
容灾的一切设计都从这两个数字出发,它们是「业务能接受的最坏情况」。
RTO(Recovery Time Objective)恢复时间目标:
□ 从故障发生到服务恢复可用的最长时间
□ 决定:需要多快切换、要预热多少实例、要不要多活
□ 微型博客参考:核心读接口 15 分钟,写入 30 分钟
RPO(Recovery Point Objective)恢复点目标:
□ 能容忍丢失多少时间窗口的数据
□ 决定:备份频率、复制方式(同步/异步)、日志归档间隔
□ 微型博客参考:帖子与关系 RPO ≈ 0(同步复制),
统计与热度 RPO 可放宽到 1 小时
两者是成本曲线:
RTO/RPO 越接近 0,成本越呈指数上升
□ 冷备(天级恢复)→ 便宜
□ 温备(小时级)→ 中
□ 热备/多活(分钟级)→ 贵
按业务分级定目标,而不是「全站一个数字」:
| 数据类型 | RPO | RTO | 手段 |
|---|---|---|---|
| 帖子/关系/私信 | ≈ 0 | 15 min | 同步复制 + 自动切换 |
| 计数/点赞 | 1 min | 30 min | 异步复制 + 对账修复 |
| 统计/热度 | 1 h | 数小时 | 可重算,备份频率低 |
| 媒体文件 | ≈ 0 | 分钟级 | 对象存储跨区复制 |
| 日志/审计 | 15 min | 数小时 | 归档到冷存储 |
2. 备份策略:全量、增量与 3-2-1
备份的三种形态与一条经典原则。
全量备份(Full):
□ 完整复制所有数据;恢复最快、占用最大
□ 频率:每天 / 每周一次(按数据量定)
增量备份(Incremental):
□ 只备份自上次备份以来的变化;占用最小、恢复最慢
□ 恢复需要「全量 + 所有增量」链式重放
差异备份(Differential):
□ 备份自上次全量以来的变化;折中方案
□ 恢复需要「全量 + 最近一次差异」
3-2-1 原则:
3 份副本(1 份生产 + 2 份备份)
2 种介质(如本地磁盘 + 对象存储)
1 份异地(地理隔离,抗区域性灾难)
扩展 3-2-1-1-0:
+1 份离线/不可变(抗勒索)
+0 个错误(备份必须验证,不能有未验证的备份)
| 组合方案 | 恢复速度 | 存储成本 | 适用 |
|---|---|---|---|
| 每日全量 | 快 | 高 | 小数据量 |
| 每周全量 + 每日增量 | 慢(重放链长) | 低 | 大数据量 |
| 每周全量 + 每日差异 | 中 | 中 | 通用 |
| 全量 + WAL 持续归档 | 快(PITR) | 中 | 数据库首选 |
备份的验证比备份本身更重要:一个从未被恢复过的备份,等于没有备份。每次备份完成后要做校验(校验和、可挂载性),并定期做完整恢复演练。
3. 备份的安全:加密、不可变与隔离
备份是攻击者的高价值目标——拿到备份就等于拿到全部数据,删掉备份就能让勒索得逞。
备份安全三件套:
□ 加密(Encryption):
· 传输加密(TLS)+ 静态加密(KMS 托管密钥)
· 密钥与数据分离存储,密钥丢失 = 数据不可恢复
□ 不可变(Immutability):
· 对象存储开启 Object Lock / WORM(一次写入多次读取)
· 保留期内任何人(包括管理员)都不能删除或篡改
□ 隔离(Isolation):
· 备份账号与生产账号分离,权限最小化
· 备份网络与生产网络隔离(生产被攻陷不影响备份)
· 离线/磁带等「空气间隙」副本
权限隔离示例:
生产服务账号:只能写业务数据,无备份桶权限
备份写入账号:只能写备份桶,不能删除
恢复账号:只在恢复流程中临时提权,用完即收回
审计:所有备份桶的删除操作必须触发告警
勒索软件的典型攻击链是先窃取凭据、再加密生产数据、最后删除备份。防御的关键是「备份凭据与生产凭据分离」+「不可变保留」——即使生产账号被完全控制,攻击者也删不掉备份。
4. 数据库备份:PITR 与持久化取舍
数据库是容灾的重心,PostgreSQL 与 Redis 各有成熟的保护手段。
PostgreSQL 时间点恢复(PITR, Point-In-Time Recovery):
□ 基础备份(pg_basebackup)+ WAL 归档(continuous archiving)
□ 恢复:还原基础备份 → 重放 WAL 到指定时间点
□ 能力:可恢复到「误删前 1 秒」的任意时刻
□ 部署:流复制到从库 + WAL 归档到对象存储
关键参数:
wal_level = replica # 记录足够 WAL 用于归档
archive_mode = on
archive_command = 'wal-g wal-push %p' # 归档到对象存储
archive_timeout = 60 # 强制切换 WAL 段,控制 RPO
# 全量基础备份 + 归档到对象存储(wal-g 示例)
wal-g backup-push /var/lib/postgresql/data
wal-g backup-list
# 恢复到指定时间点(先停库、还原、重放)
wal-g backup-fetch /var/lib/postgresql/data LATEST
# recovery.signal + restore_command 指向 wal-g wal-fetch
Redis 的持久化是「性能与可靠性」的取舍:
| 方式 | 机制 | 优点 | 缺点 | 建议 |
|---|---|---|---|---|
| RDB | 定时快照 | 文件小、恢复快 | 可能丢窗口内数据 | 缓存可接受 |
| AOF | 追加命令日志 | 丢得少(everysec) | 文件大、恢复慢 | 关键数据用 |
| RDB + AOF | 双开 | 兼顾 | 成本高 | 混合持久化 |
| 主从 + 哨兵 | 复制 | 高可用 | 需脑裂防护 | 生产标配 |
关键认知:Redis 通常不应作为「唯一数据源」。点赞计数、时间线缓存这类数据要能「从主库重建」,备份 Redis 是为了「快速恢复」而非「唯一保障」。
5. 对象存储与媒体资产保护
图片、视频、头像这类媒体资产,往往是数据量最大的部分。
对象存储保护手段:
□ 版本控制(Versioning):覆盖/删除保留历史版本,防误删
□ 跨区域复制(CRR):异步复制到异地桶,抗区域故障
□ 生命周期(Lifecycle):转低频/归档存储,降成本
□ 对象锁(Object Lock):合规保留,防篡改
□ 校验和:上传时记录,读取时校验完整性
媒体资产的特殊性:
□ 大文件、不可变(上传后不改)→ 天然适合版本控制
□ 转码产物可重算 → RPO 可放宽,源文件必须保护好
□ CDN 缓存是「加速层」,不是「数据层」,丢了可回源
// 跨区域复制 + 版本控制:抗区域性故障
{
"Role": "arn:aws:iam::123:role/replication",
"Rules": [{
"Status": "Enabled",
"Prefix": "media/",
"Destination": {
"Bucket": "arn:aws:s3:::miniblog-media-dr",
"StorageClass": "STANDARD_IA"
},
"DeleteMarkerReplication": { "Status": "Disabled" }
}]
}
源文件(原图/原视频)必须优先保护,因为转码产物、缩略图都可以从源文件重算。把「可重算的派生数据」和「不可重建的源数据」分开定 RPO,是省钱的关键。
6. 多活与故障切换架构
从「备份恢复」到「不停机切换」,是多活架构要解决的问题。
容灾等级(由低到高):
□ 冷备(Backup & Restore):出事了才拉起环境,RTO 小时级
□ 温备(Pilot Light):最小环境常驻,出事扩起来,RTO 分钟~小时
□ 热备(Warm Standby):完整环境 + 异步复制,RTO 分钟级
□ 多活(Active-Active):两地都对外服务,RTO ≈ 秒级
多活的难点(不是「起两套」那么简单):
□ 数据同步:跨区延迟 → 强一致与低延迟不可兼得
□ 写入冲突:两地同时写同一用户 → 需要冲突解决策略
□ 流量调度:DNS / Anycast / 全局负载均衡的健康检查
□ 会话与状态:登录态、购物车等状态要能跨区共享
故障切换(Failover)的关键设计:
□ 自动还是手动:核心库切换建议「自动检测 + 人工确认」
· 全自动切换有脑裂风险(网络分区时两边都以为对方挂了)
□ 切换判据:健康检查连续失败 N 次 + 仲裁节点确认
□ 数据安全:切换前确认从库已追平(避免丢数据)
□ 回切预案:主恢复后如何切回(避免「单边运行」变常态)
□ 演练:定期做真实切换演练,验证 RTO 承诺
对微型博客而言,务实的路线是:核心数据用热备 + 自动切换,非核心用冷备。全量多活的复杂度与成本对小团队往往不划算,先把「可恢复」做扎实,再考虑「不停机」。
7. 数据一致性校验
恢复后最怕的不是「数据没了」,而是「数据悄悄错了」——不一致的静默损坏。
一致性风险:
□ 复制延迟导致从库数据滞后
□ 部分恢复(只恢复了一张表)造成引用断裂
□ 计数与实际记录数不符(点赞数 vs 点赞记录)
□ 软删除墓碑与关联数据不同步
校验手段:
□ 行数校验:关键表的行数在源与恢复环境比对
□ 校验和校验:分块计算 checksum 比对(如 pg_checksums)
□ 业务对账:计数表 vs 明细表定期对账
□ 引用完整性:孤儿记录扫描(无主评论、悬空关注)
-- 计数对账:发现「点赞数」与实际记录数的偏差
SELECT p.id, p.like_count, COUNT(l.user_id) AS actual
FROM posts p
LEFT JOIN likes l ON l.post_id = p.id
GROUP BY p.id, p.like_count
HAVING p.like_count <> COUNT(l.user_id);
-- 孤儿记录扫描:指向已删除帖子的评论
SELECT c.id FROM comments c
LEFT JOIN posts p ON p.id = c.post_id
WHERE p.id IS NULL;
对账应是常态化的后台任务,而不是「出事才跑」。每天跑一次对账、把偏差量作为指标监控,就能在数据腐烂到不可收拾前发现苗头。
8. 恢复演练:从有备份到能恢复
演练是容灾能力的唯一证明。「备份成功」不等于「恢复成功」。
恢复演练的层次:
□ L1 备份可读:确认备份文件能下载、能解压、校验和一致
□ L2 单表恢复:从备份中恢复一张表并验证行数与抽样内容
□ L3 全库恢复:完整还原到隔离环境,跑通关键查询
□ L4 时间点恢复:验证 PITR 能恢复到「误操作前 1 秒」
□ L5 切换演练:真实把流量切到备用环境,验证 RTO
演练剧本要素(同混沌工程):
□ 稳态假设:演练前记录基线指标
□ 注入:模拟真实故障(删库、区域不可用)
□ 观测:恢复耗时是否满足 RTO、数据是否满足 RPO
□ 复盘:记录卡点(凭据过期、脚本失效、文档过时)
| 演练项 | 常见失败 | 对策 |
|---|---|---|
| 凭据 | 备份账号密码过期 | 凭据纳入轮换与监控 |
| 脚本 | 恢复脚本从未跑过 | 脚本版本化 + 定期演练 |
| 文档 | 步骤缺失或过时 | 演练即文档更新的时机 |
| 容量 | 恢复环境磁盘不足 | 预留容量或弹性扩容 |
| 时长 | 恢复远超 RTO | 优化流程或调整目标 |
演练频率建议:L1/L2 每月,L3/L4 每季度,L5 每半年。每次演练都要计时并记录实际 RTO/RPO,与目标对比——数字不说谎。
9. 降级与兜底策略
容灾不只有「恢复」,还有「在恢复完成前如何体面地活着」。
降级策略(故障期间的兜底):
□ 只读模式:数据库故障时,写入拒绝、读取走缓存/从库
□ 功能降级:关掉非核心功能(推荐、搜索),保核心(时间线)
□ 静态兜底:首页降级为静态缓存页 + 提示
□ 排队缓冲:写入进队列,恢复后异步补写
□ 限流保护:故障期间收紧限流,避免雪崩
用户沟通:
□ 明确的状态页(Status Page)与提示文案
□ 避免「白屏」——降级也要给用户可用的东西
□ 恢复后对「降级期间受影响的操作」给出补偿或说明
降级的顺序是「保核心、舍边缘」:先砍掉个性化推荐、搜索这类可降级功能,把资源留给「刷时间线、发帖、登录」这些核心路径。降级开关要能在故障时秒级生效(这正是特性开关的价值)。
10. 速查表与一句话记忆
| 问题 | 一句话答案 |
|---|---|
| 目标怎么定 | 按数据分级定 RTO/RPO,核心接近 0 |
| 备份怎么放 | 3-2-1-1-0:三份、两介质、一异地、一不可变、零错误 |
| 备份怎么防删 | 加密 + 不可变(Object Lock)+ 账号隔离 |
| 数据库怎么保 | 基础备份 + WAL 归档 = PITR,可恢复到任意时刻 |
| Redis 能当唯一源吗 | 不能,关键数据要能从主库重建 |
| 媒体怎么保 | 版本控制 + 跨区复制,优先保源文件 |
| 多活难在哪 | 数据同步、写冲突、流量调度、会话状态 |
| 切换怎么安全 | 自动检测 + 人工确认,避免脑裂,留回切预案 |
| 数据会悄悄错吗 | 会,靠行数/校验和/对账常态化发现 |
| 怎么证明能恢复 | 分级演练 L1~L5,计时对比 RTO/RPO |
一句话记忆:容灾 = 按数据分级定 RTO/RPO + 3-2-1-1-0 备份(含不可变与隔离)+ 数据库 PITR(基础备份 + WAL 归档)+ Redis 不作唯一源 + 媒体跨区复制优先保源文件 + 热备自动切换(防脑裂留回切)+ 对账校验常态化 + L1~L5 分级演练计时验证 + 保核心舍边缘的降级兜底——用「演练过」代替「以为有备份」,把恢复能力变成可证明的承诺。
延伸阅读
- 数据模型与 Schema 演进
- 图片与对象存储
- 多租户隔离设计
- 可观测性与 SRE 实践
- 数据库备份与恢复策略 — 全量/增量与 PITR 落地
- Kubernetes 备份与容灾 — 集群级数据与配置保护
- DevOps 备份与容灾 — 备份自动化与演练流程
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。