前置问题与边界

RegionServer 崩溃以后,HBase 要恢复的是由该 RegionServer 服务的 Region,而不是让 HDFS 自动懂得数据库事务。HDFS 负责保存 WAL 和 HFile;HBase 通过 procedure、assignment、WAL split 或 replay,把未 flush 的 edit 重新送到负责 Region 的服务进程。

本篇回答一个核心问题:ServerCrashProcedure、WAL split/replay 和 Region reassignment 如何把服务恢复到可读写状态。行级一致性边界见第 10 篇;复制链路见第 12 篇;Snapshot 和 Backup 见第 13 篇。

崩溃恢复路径图

flowchart TD
    A[RegionServer crash] --> B[Master detects dead server]
    B --> C[ServerCrashProcedure]
    C --> D[Mark affected regions unavailable]
    C --> E[Split or distribute WAL edits]
    E --> F[recovered.edits per region]
    F --> G[Assign region to live RegionServer]
    G --> H[Open region and replay edits]
    H --> I[Region accepts traffic]

故障恢复里有三类状态不能混在一起。Region 的服务归属由 HBase 的 assignment 流程推进;WAL 文件位于 HDFS 上,但 edit 如何按 Region 拆分和重放由 HBase 负责;hbase:meta 记录 Region 位置信息和状态,ZooKeeper 只承担协调与注册一类职责。

关键对象和状态

对象 位置 作用
ServerCrashProcedure HMaster procedure 框架 编排死亡 RegionServer 的恢复步骤
WAL HDFS 保存 RegionServer 写入 edit
WAL split Master/worker 协作流程 把死亡 server 的 WAL edit 按 Region 分派
recovered.edits Region 目录附近 Region 打开时用于 replay 的 edit 文件
AssignmentManager HMaster 推进 Region 关闭、打开和迁移状态
hbase:meta HBase 系统表 保存 Region 位置信息和状态

现代 HBase 2.x 的恢复流程由 procedure 框架驱动。文章不应把它写成“Master 直接手工移动目录”或“HDFS 自动恢复数据库状态”。HDFS 只提供持久文件和租约恢复能力;数据库语义来自 HBase 的 WAL 和 Region 打开流程。

WAL 为什么是恢复中心

写入成功但尚未 flush 成 HFile 的数据,只存在于 MemStore 和 WAL 里。RegionServer 进程消失以后,MemStore 随进程丢失;WAL 仍在 HDFS 上。恢复流程要读取死亡 RegionServer 留下的 WAL,把属于不同 Region 的 edit 拆出来,并在 Region 被新 RegionServer 打开时重放。

WAL 记录的是 edit 序列。恢复时要维护 sequence id,避免已经 flush 的 edit 被重复应用,也避免未 flush 的 edit 被跳过。这个边界解释了为什么 WAL、MemStore flush 和 Region 打开状态必须一起看。

模式提炼:把易失状态写成可分区重放日志。公式是 volatile_state + durable_log -> replay(partition) -> serving_state。LSM 数据库、消息队列 consumer checkpoint、流处理状态后端都用类似方法。日志本身不等于服务恢复,必须有分区归属和重放进度。

ServerCrashProcedure 的职责

ServerCrashProcedure 接到死亡 RegionServer 事件后,会围绕该 server 的 Region 和 WAL 做一组步骤:标记 affected Regions、处理 WAL、推进 Region reassignment,并在必要时更新元数据状态。不同版本内部步骤可能调整,但职责边界保持一致:把故障节点上的 Region 交给存活节点,并让未 flush edit 被 replay。

这不是客户端透明重试就能完成的事。客户端只会看到请求失败、重试、重新定位或超时。真正决定数据是否可恢复的,是服务端写入时的 durability、WAL 是否可读、split/replay 是否成功,以及 Region 是否能重新打开。

recovered.edits 的角色

WAL split 后,属于某个 Region 的 edit 会变成该 Region 打开流程可以读取的恢复文件,常见目录名包含 recovered.edits。Region 被新 RegionServer 打开时,HBase 会把这些 edit 应用到内存状态,再继续提供服务。

不要把 recovered.edits 写成普通 HFile。它不是最终 StoreFile,也不是 compaction 的输入;它是 Region 打开时用于重放的恢复资料。重放成功后,后续 flush 会把内存状态写成 HFile。

最小实验

UNVERIFIED_RUNTIME:当前环境未安装 HBase 2.6.6、Hadoop 3.4.3、JDK 17 和 HBase 源码 checkout,以下步骤只作为复现实验,不附带输出。

在 HBase 源码 checkout 中,优先用官方测试验证 WAL replay、WAL split 和 crash procedure。三条命令分别覆盖 edit 重放、死亡 server 日志拆分、procedure 编排三个观察面:

1
mvn -pl hbase-server -Dtest=TestWALReplay test
1
mvn -pl hbase-server -Dtest=TestWALSplit test
1
mvn -pl hbase-server -Dtest=TestServerCrashProcedure test

在独立测试集群里观察服务恢复,应先创建实验表:

1
hbase shell
1
create_namespace 'lab'
1
create 'lab:t11_recover', 'cf'
1
put 'lab:t11_recover', 'r1', 'cf:q', 'v1'

故障注入必须在可丢弃环境执行。不要在共享或生产集群上直接 kill RegionServer。实验记录只应保留 procedure 状态、Region reassignment、WAL replay 和最终读回结果,不记录无法复核的“恢复耗时”数字。

失败恢复

失败点 现象 排查方向
WAL 不可读 Region 打开失败或 replay 卡住 HDFS 文件、租约、权限、WAL 损坏
WAL split 积压 ServerCrashProcedure 长时间未完成 Master procedure、split worker、HDFS I/O
Region reassignment 失败 客户端持续 NotServingRegion 或定位失败 AssignmentManager、hbase:meta 状态
客户端超时 请求重试或重新定位 客户端缓存、重试配置、Region 状态

恢复流程里最危险的写法是把组件拟人化为“自动找回”。更精确的描述是:HBase 使用持久 WAL、Region 状态机和 procedure 框架,把失败节点留下的 Region 服务权迁到存活节点,并在 Region 打开时重放 edit。

工程迁移

场景 可迁移模式 HBase 对应物
分片服务节点死亡 分片重新归属 Region reassignment
内存状态丢失 日志重放 WAL replay
日志按分片恢复 分区日志拆分 WAL split 和 recovered.edits
故障恢复编排 持久状态机 ServerCrashProcedure

听到“节点挂了但内存里还有未落盘状态”时,先看可重放日志、分片归属和重放进度。只看底层文件系统副本是不够的。

常见误解

  • “HDFS 会恢复 HBase 写入”不准确;HDFS 保存文件,HBase 执行 WAL replay。
  • “Master 在正常读写路径上”不准确;Master 主要处理控制面和故障恢复编排,客户端正常读写直连 RegionServer。
  • “WAL replay 会把所有历史 edit 再执行一遍”不准确;sequence id、flush 状态和恢复文件共同限制重放范围。
  • “Region 重新打开后复制也自动完成”不准确;replication 有自己的 WAL source、peer 和 queue 语义。

练习

  • 画出一个 RegionServer 同时服务三个 Region 时的 WAL split 结果。
  • 给出 SKIP_WAL 写入在 RegionServer 崩溃后的数据风险说明。
  • 设计一份恢复观察清单,只包含 procedure、WAL、Region 状态和最终读回验证。

系列导航

参考资料