2. 核心概念:快照、日志、版本号、一致性点、RPO 与 RTO
好,咱们正式开始聊干货。这一章我打算把增量 Checkpoint 和全量恢复里最基础的那几个概念掰开揉碎讲清楚。你可能会觉得这些词儿都听过,但说实话,我在面试 P8 级别的候选人时,能把它们之间的逻辑链条说利索的人,真不多。
说白了,这六个概念就是一套组合拳。你搞懂了它们,后面讲实现原理时,我只需要说「这里用版本号对齐一致性点」,你脑子里立刻就能浮现出画面。
2.1 快照(Snapshot)
快照是什么?就是某个时刻的数据「照片」。你把整个数据集在 T0 时刻的状态完整复制一份,存下来,这就是一个快照。
关键特征:
- 完整副本:不是增量,是全量。哪怕你只有 1TB 数据,快照就是 1TB。
- 时间点确定:快照一定对应一个明确的时间戳或版本号。
- 只读不可变:生成之后不允许修改,只能读取或删除。
我在项目中遇到过一种情况:团队用 ZFS 的快照做日常备份,结果有人误以为快照是增量存储,觉得 100 个快照只占一份空间。嗯,后来磁盘爆了,大家才明白——快照的写时复制(Copy-on-Write)只节省变化部分的空间,但每个快照的元数据和指针结构本身是有开销的。
我的习惯:快照频率不要拍脑袋定。我一般先跑一周的监控,看数据变化率。日变化量小于 5% 的系统,我才会考虑每小时快照;变化剧烈的 OLTP 系统,快照间隔建议拉长到 4-6 小时,中间用日志补。
2.2 日志(Log)
日志记录的是「变化」,不是「状态」。你想想看,快照是照片,日志就是录像。照片告诉你某个瞬间长什么样,录像告诉你从 A 到 B 是怎么变的。
在分布式存储里,日志通常有两种形态:
| 类型 | 记录内容 | 典型用途 |
|---|---|---|
| Write-Ahead Log (WAL) | 数据修改操作(写前日志) | 崩溃恢复、事务回滚 |
| Change Log | 数据块的增量变化(字节级差异) | 增量 Checkpoint、主从同步 |
我个人习惯把日志看作「时间轴上的补丁」。快照是基座,日志是补丁序列。恢复时,先加载快照,再按顺序回放日志,就能得到最新状态。
避坑指南:我曾经在一个 Kafka 集群上踩过日志保留策略的坑。默认保留 7 天的日志,但快照每 24 小时才生成一次。结果第 6 天节点挂了,日志回放时发现第 5 天的日志已经被清理了——快照和日志之间出现了空洞。从那以后,我定了一条铁律:日志保留时长必须 ≥ 快照间隔 × 2。
2.3 版本号(Version Number)
版本号是分布式系统里最容易被低估的概念。很多人觉得它就是个自增 ID,其实不然。
版本号的核心作用有两个:
- 标识数据的新旧:哪个版本更新,一目了然。
- 判断冲突:两个副本的版本号不一致,说明存在分歧。
在增量 Checkpoint 的场景里,版本号通常附着在每个数据块上。比如一个 4KB 的块,它的元数据里会有一个 version: 1024。当这个块被修改时,版本号递增到 1025。Checkpoint 只扫描版本号大于上次 Checkpoint 的块,这就是「增量」的来源。
版本号的设计原则:
- 单调递增:不能回退,不能跳跃(除非有明确的 Gap 处理逻辑)。
- 全局唯一:在分布式环境下,建议用
(node_id, local_counter)组合,或者直接上 Lamport 时钟。 - 持久化:版本号必须落盘,不能只存在内存里。否则节点重启后,版本号归零,增量 Checkpoint 就退化成全量了。
2.4 一致性点(Consistency Point)
一致性点,也叫「检查点」或「同步点」。它指的是系统中所有数据在逻辑上达成一致的那个时刻。
举个例子:你有一个分布式数据库,3 个副本。T1 时刻,副本 A 写入了数据 X,但副本 B 和 C 还没收到。这时候系统是不一致的。等到 T2 时刻,所有副本都确认了 X,T2 就是一个一致性点。
在增量 Checkpoint 里,一致性点的作用特别重要:
- Checkpoint 必须在一致性点触发,否则保存的数据可能是不完整的。
- 恢复时,只能恢复到最近的一致性点,不能恢复到任意时刻。
我的经验:一致性点的选取不是越频繁越好。太频繁会导致系统频繁进入同步状态,影响写入性能。我一般建议:对于强一致性系统,一致性点间隔控制在 1-5 秒;对于最终一致性系统,可以放宽到 30 秒到 1 分钟。
2.5 RPO 与 RTO
这两个指标是衡量恢复能力的黄金标准。我每次做架构设计,第一件事就是跟业务方确认 RPO 和 RTO 的容忍度。
| 指标 | 全称 | 定义 | 通俗理解 |
|---|---|---|---|
| RPO | Recovery Point Objective | 能容忍的最大数据丢失量 | 「丢多少数据我能接受?」 |
| RTO | Recovery Time Objective | 能容忍的最大恢复时间 | 「多久必须恢复过来?」 |
这两个指标直接决定了你的 Checkpoint 策略:
- RPO 越小 → Checkpoint 间隔越短,或者日志保留越多。
- RTO 越小 → 全量快照越频繁,或者恢复流程越自动化。
我曾经踩过的坑:有个金融客户要求 RPO=0(零数据丢失),RTO=5 分钟。我一开始的方案是每秒做一次增量 Checkpoint,结果系统负载直接飙到 80%。后来改成「每 5 分钟全量快照 + 实时 WAL 日志」,恢复时先加载快照再回放日志,RPO 做到了秒级,RTO 控制在 3 分钟以内。记住:RPO=0 不等于必须高频 Checkpoint,日志回放才是关键。
2.6 概念关系图
下面这张图把六个概念串起来了。你盯着看 30 秒,应该能理解它们之间的协作关系。
2.7 小结
这一章的概念比较多,但你别急着背。我建议你记住一条主线:快照提供基座,日志记录变化,版本号追踪差异,一致性点对齐状态,RPO 和 RTO 定义目标。
后面讲增量 Checkpoint 算法时,你会发现每一步都在跟这六个概念打交道。比如「基于版本号的增量扫描」就是在快照和日志之间找差异;「一致性点对齐」决定了 Checkpoint 的触发时机;而 RPO/RTO 直接约束了你的 Checkpoint 频率和恢复策略。
一句话总结:没有快照,恢复没有起点;没有日志,恢复没有连续性;没有版本号,增量无从谈起;没有一致性点,恢复结果不可信;没有 RPO/RTO,你根本不知道自己的方案合不合格。