深入 HBase 13 - Snapshot、Backup 与恢复
前置问题与边界
HBase Snapshot 接近一次元数据操作,因为它主要记录某个时刻表的 Region、StoreFile 引用和相关描述,而不是把整张表的数据复制一遍。HFile 是不可变文件,这让 snapshot 可以通过引用既有 HFile 建立一致视图;后续 compaction、删除和清理要尊重这些引用。
本篇回答一个核心问题:Snapshot 为什么快,Backup 和跨集群恢复还需要什么。第 11 篇处理 WAL 恢复,第 12 篇处理 replication;本篇处理表级时间点视图、克隆、恢复和备份边界。
Snapshot 路径图
flowchart TD
A[Table] --> B[Regions]
B --> C[StoreFiles HFile]
A --> D[Snapshot request]
D --> E[Flush by default]
E --> F[Snapshot manifest]
F --> G[References to HFiles]
G --> H[Clone or restore]
G --> I[Export or backup workflow]
Snapshot 能快,是因为 HBase 存储文件不可变。对已有 HFile 建引用,比重写全量数据便宜得多。这个优势也带来边界:被 snapshot 引用的 HFile 不能随意删除;跨集群搬迁还需要复制文件、校验权限和处理目标集群元数据。
关键对象和状态
| 对象 | 作用 | 风险 |
|---|---|---|
| Snapshot manifest | 记录表、Region、StoreFile 引用 | manifest 损坏会影响恢复 |
| HFile reference | 指向不可变 StoreFile | 被引用文件需要保留 |
| Flush | 把 MemStore 写成 HFile | 默认 snapshot 会尽量减少 WAL 依赖 |
SKIP_FLUSH |
快速 snapshot 选项 | 可能让最新内存写入不进入 snapshot |
| Clone | 从 snapshot 建新表 | 新表初始复用 HFile 引用 |
| Restore | 把原表恢复到 snapshot | restore 前必须 disable 表,会影响现有数据和必要 schema |
Snapshot 和 Backup 不同。Snapshot 是表级时间点视图;Backup 是把数据和元数据保存到恢复目标可用的位置,并能按恢复目标执行恢复流程。跨集群恢复通常还要处理文件传输、权限、表结构、ACL、replication 配置和目标集群兼容性。AccessController 启用时,snapshot 操作需要 global admin 权限;snapshot 不捕获 ACL 本身,权限恢复要单独设计。
Flush 与 SKIP_FLUSH
默认 snapshot 会触发或等待 flush,使 MemStore 中的数据进入 HFile,从而让 snapshot 主要依赖不可变 StoreFile。SKIP_FLUSH 可以减少 snapshot 对在线写入的扰动,但它也会改变快照覆盖边界:未 flush 的内存数据不一定进入该 snapshot。
这条边界不能写成“snapshot 一定包含所有刚写入数据”。更准确的说法是:默认 snapshot 试图通过 flush 建立稳定文件视图;使用 SKIP_FLUSH 时,速度和扰动降低,覆盖的新近写入边界也更窄。
模式提炼:利用不可变文件做引用式备份。公式是 manifest(version) + immutable_files -> point_in_time_view。对象存储版本、LSM SSTable checkpoint、湖仓 table snapshot 都属于同类模式。文件不可变是前提,引用清理是代价。
Clone 与 Restore
clone_snapshot 用 snapshot 创建一张新表,常用于验证、回放、离线分析或迁移前检查。初始状态下,新表可以复用 snapshot 引用的 HFile;后续写入会产生新文件。
restore_snapshot 会把表恢复到 snapshot 指向的状态。restore 前必须 disable 目标表;恢复的是 snapshot 覆盖的数据和必要 schema,操作会影响现表内容。生产环境通常要配合停写、备份当前状态、权限校验和回滚预案。局部修复优先 clone snapshot 到临时表,再按业务 key 回拷所需行或列,避免为了几行误删覆盖整张表。
ACL 边界要单独写进恢复方案。snapshot 不捕获 ACL;restore 到现有表时,现表 ACL 会保留;clone snapshot 创建的新表默认不会继承原表 ACL。安全集群里,clone 后需要重新授予目标表权限,再让应用访问。
Backup 与跨集群恢复
HBase Backup 能把表数据和必要元数据复制到备份位置,并支持恢复到目标集群。Snapshot 可以作为备份链路的一部分,但 snapshot 本身不是完整的跨集群灾备流程。文件还要被导出,目标集群还要有兼容的 HBase/Hadoop 环境和权限配置。
ACL、namespace、replication peer、quota、coprocessor 配置等边界要单独核查。只恢复表数据,不等于恢复完整服务语义。加密、Kerberos 和 HDFS 权限也可能让“文件已经复制”与“目标集群可读写”之间出现差距。对已经参与 replication 的表执行 restore 后,副本集群可能和源表状态失配;恢复方案应暂停相关复制、重新 bootstrap 或重建 peer 端基线,再恢复复制。
最小实验
UNVERIFIED_RUNTIME:以下命令适用于可丢弃 HBase 2.6.6 环境,当前任务未运行。实验先创建表并生成 snapshot,再演示 restore 前必须 disable 原表,最后 clone 出临时表用于局部修复比对:
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
1 | |
继续写原表:
1 | |
再次读取克隆表:
1 | |
这个实验只验证 snapshot view 和后续原表写入的隔离,不记录耗时。SKIP_FLUSH 可在独立实验里观察覆盖边界:
1 | |
失败恢复
| 场景 | Snapshot 能做什么 | 仍需补齐什么 |
|---|---|---|
| 误删几行 | clone snapshot 后按业务 key 回拷 | snapshot 之后的合法写入处理 |
| 误 drop 表 | 从 snapshot clone 或 restore | snapshot 是否仍存在,restore 前表状态是否可控 |
| 集群迁移 | 结合 ExportSnapshot 或 Backup 搬运数据 | 目标权限、版本、ACL、namespace |
| 灾难恢复 | 作为时间点恢复材料 | RPO、RTO、切流和应用验证 |
| replication 表恢复 | 恢复源端时间点 | 停止复制并重新 bootstrap peer 端基线 |
Snapshot 不替代 WAL 恢复。RegionServer 崩溃后的未 flush edit 仍按第 11 篇的 WAL replay 处理;snapshot 解决的是表级时间点视图和恢复材料。
工程迁移
| 需求 | 建议路径 | 检查点 |
|---|---|---|
| 发布前保护 | 对关键表做 snapshot | 确认可 clone、可读 |
| 数据修复 | clone snapshot 到临时表比对并回拷 | 不直接覆盖原表 |
| 跨集群迁移 | snapshot 加 ExportSnapshot 或 Backup | 校验文件、权限、目标表、ACL |
| 降低误操作风险 | 定期 snapshot 和保留策略 | 清理策略不能删仍需恢复的视图 |
| 复制链路修复 | restore 后重新 bootstrap replication | 避免 peer 与源表时间点失配 |
模式速查:听到“保留某个时间点”,优先找不可变文件和 manifest;听到“异地能恢复”,还要补文件传输、权限、版本和服务配置。
常见误解
- “Snapshot 会复制整张表”不准确;它主要记录元数据和 HFile 引用。
- “Snapshot 一定包含所有刚写入数据”不准确;默认 flush 和
SKIP_FLUSH的边界必须区分。 - “Clone 等于深拷贝”不准确;初始阶段可能复用 HFile 引用。
- “Snapshot 会保存 ACL”不准确;ACL 不属于 snapshot 内容,clone 后需要重新授权。
- “Restore 可以直接在线覆盖表”不准确;restore 前必须 disable 表,并确认 replication 和应用写入已经受控。
- “Backup 只要拷贝 HDFS 目录”不准确;恢复还依赖 HBase 元数据和目标环境。
练习
- 设计一个误删恢复流程,要求先 clone snapshot 再比对回写。
- 列出从生产集群导出 snapshot 到测试集群时的权限和版本检查。
- 解释为什么被 snapshot 引用的 HFile 不能被普通清理流程直接删除。
系列导航
- 00 导读:row key 决定数据位置
- 01 数据模型:Cell、Column Family 与版本
- 02 集群架构:HMaster、RegionServer、ZooKeeper 与 hbase:meta
- 03 Schema 与 row key 设计
- 04 写入路径:WAL、MVCC、MemStore 与 flush
- 05 读取路径:BlockCache、Bloom Filter 与 HFile block
- 06 HFile 内部结构
- 07 Compaction、TTL、版本与 Delete
- 08 Region 生命周期:split、merge 与 assignment
- 09 Client 路由与重试
- 10 行级原子性与一致性边界
- 11 RegionServer 崩溃与 WAL 恢复
- 12 跨集群 Replication
- 13 Snapshot、Backup 与恢复(本篇)
- 14 Get、Scan、Filter 与分页
- 15 BufferedMutator 与 Bulk Load
- 16 Coprocessor、Endpoint 与 Phoenix 边界
- 17 Kerberos、RPC 保护与 ACL
- 18 Metrics、hbtop、Compaction 与性能调优
- 19 HBase 3.0 与设计边界
参考资料
- Apache HBase Reference Guide:https://hbase.apache.org/docs/
- Apache HBase Backup and Snapshots:https://hbase.apache.org/docs/operational-management/backup-and-snapshots/
- Apache HBase Backup and Restore:https://hbase.apache.org/docs/backup-restore/
- Apache HBase User API:https://hbase.apache.org/2.6/apidocs/
- Apache HBase Developer API:https://hbase.apache.org/2.6/devapidocs/
- Apache HBase 源码:https://github.com/apache/hbase
