1. 故障发生的底层逻辑:HBase 数据路径与薄弱环节
1.1 从写入路径看数据恢复为什么依赖 WAL
接手过 HBase 集群运维的人都有这种体会:平时觉得它皮实,真正出故障时又恨它难伺候。要搞懂数据恢复,首先得看数据是怎么写进去的。客户端写入一条数据,RegionServer 不会直接改磁盘上的文件,而是先追加到 WAL(Write-Ahead Log,预写日志),再写进内存里的 MemStore。等 MemStore 攒到一定大小,比如默认的 128MB,才会触发 flush,把数据落成 HFile 文件存到 HDFS 上。
这套机制的核心用意是保证“先记日志、再改内存”,进程一旦崩溃,内存数据丢了没关系,回头靠 WAL 重放就能把数据找回来。这也是 HBase 数据恢复的地基:多数故障恢复,本质都是在跟 WAL 和 HDFS 上的文件打交道。明白了这一点,后面所有方案就有了主线。
1.2 故障类型分级:进程级、节点级、数据损坏级
实际运维中我习惯先把故障分个级,因为不同级别对应的恢复手段差别很大。
第一类是进程级故障。RegionServer 或 HMaster 进程退出了,可能是 JVM OOM、机器重启、网络抖动。这类故障不涉及数据文件损坏,恢复的核心是把进程拉起来,让 HBase 的协调机制重新分配 Region,并回放 WAL。大多数半夜告警都属于这一类,处理得当半小时内能恢复。
第二类是节点级故障。一台物理机或虚拟机彻底挂掉,短时间起不来。RegionServer 上未 flush 的 WAL 都在本地磁盘,节点起不来的话,日志暂时拿不到。HBase 会把这些 Region 分配到其他节点,但数据恢复必须等原节点恢复或者手动从 HDFS 中找回相关文件。
第三类是数据损坏级故障。HFile 文件块损坏、HDFS 副本丢失、hbase:meta 元数据表错乱,这类最麻烦。它不是重启能解决的,需要用到 hbck、HBCK2、HDFS fsck 这些工具去修,风险也最大。
1.3 故障影响面:从单 Region 卡死到整表不可用
很多人以为 RegionServer 挂了只影响它上面的那部分数据,实际影响往往比想象中大。HBase 按 RowKey 范围把表拆成多个 Region,分散在不同 RegionServer 上。一台 RegionServer 宕机,它上面所有 Region 都会先进入 RIT(Region In Transition)状态,也就是过渡态。如果 WAL split 顺利完成,Region 会很快被其他节点接管;要是 split 卡住,这些 Region 会一直处于下线或 OPENING 状态,读请求直接超时。
更严重的是 hbase:meta 表出问题。这张表保存着所有 Region 的分布信息,客户端每次读写都要先找它定位。meta 表一旦损坏或数据丢失,整个集群所有的表查询都会失败,这基本是 HBase 运维里最紧急的故障。所以后面聊恢复方案,元数据修复一定是重头戏。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 恢复前必须做好的环境准备:安装配置与端口清单
2.1 一套干净的恢复/演练环境怎么搭
很多团队的恢复事故现场是这样的:集群出问题后,运维手忙脚乱地找工具,发现 HBCK2 没装,版本还对不上;或者准备在另一套集群上恢复数据,结果那套环境的 HBase 版本、HDFS 版本和原集群不一致。这些都是可以提前避免的。
我强烈建议维护一套“专用的恢复演练环境”。版本尽量和生产一致,至少大版本一致。HBase 2.x 和 1.x 的元数据工具差别很大,不要混用。环境不需要大集群,三台机器就够了:一台 HMaster、两台 RegionServer,复用现有的 HDFS。如果条件紧张,甚至可以用单机伪分布式模式做工具验证。
安装时还有一个容易踩的坑:HBase 启动后会去连 ZooKeeper,ZooKeeper 里如果残留了旧集群的元数据,会干扰恢复。所以在恢复环境里要么用独立的 ZooKeeper 端口,要么启动前把 ZK 上对应的 znodes 清干净。曾经有人在演练环境里直接报“RegionServer 无法上线”,折腾半天发现是 ZK 里的 ENABLED 状态不对。
2.2 HBase 端口清单速查
恢复工作最怕数据方案都想好了,结果端口不通,节点之间通信不了,所有工具都报连接异常。这里给一张我常用的端口速查表,按 HBase 2.x 默认值来列,1.x 用户对应把 160xx 换成 600xx 即可。
| 组件角色 | 默认端口 | 用途说明 | 典型问题 |
|---|---|---|---|
| HMaster RPC | 16000 | 负责 DDL、Region 分配等控制操作 | 客户端连接时被防火墙挡掉 |
| HMaster Web UI | 16010 | Master 监控页面 | 浏览器访问不了,检查端口是否监听 |
| RegionServer RPC | 16020 | 数据读写主通道 | 节点间通信受阻,Region 无法分配 |
| RegionServer Web UI | 16030 | 单节点监控页面 | 排障时看请求延迟不方便 |
| ZooKeeper | 2181 | 协调服务,存 meta 定位信息 | ZK 不可用,整个集群会停摆 |
| HDFS NameNode RPC | 8020 或 9000 | HDFS 元数据操作 | RegionServer 找不到 HDFS 时报文件系统错误 |
| HDFS NameNode Web UI | 9870 或 50070 | HDFS 监控页面 | 排查 HFile 块状态时常用 |
部署在 Ubuntu 这类系统上时,很多人会忘了还有 ufw 防火墙。我处理过一次 RegionServer 一直连不上 HMaster 的故障,排查到最后是 16020 端口没放行。单机操作一条 sudo ufw allow 16020/tcp 就能解决,但在集群环境里要把 Master、RegionServer、ZK、HDFS 的端口都加入白名单,别抱着“内网无防火墙”的侥幸心理。
2.3 配置参数里影响恢复速度的几个关键项
hbase-site.xml 里有几个参数跟恢复速度直接相关,出故障前就该调好。
一个是 hbase.regionserver.hlog.cleanup.interval,默认 10 分钟。它控制 WAL 文件的清理频率,调小一点能让故障时待回放的日志更少,但也别太激进,否则会影响正常性能。
另一个是 hbase.master.assignment.timeout 和 hbase.regionserver.region.split.timeout。这两个超时时间决定了 Region 分配和 WAL split 时多久会被判定为超时。默认配置在大集群里偏保守,故障时可能等很久才触发重试。监控发现 split 长时间卡住,可以适当调大超时,给恢复流程留出足够时间。
Master 的 HA 配置也很关键。hbase.master.port 和 hbase.master.info.port 在多 Master 节点下要注意端口一致,不然备 Master 切换时客户端连不上。很多人以为 HMaster 挂了会自动切换,实际上如果没配好 ZooKeeper 里的 active master 节点信息,切换过程会出各种幺蛾子。恢复环境搭建完成后,建议先做一次“手动杀 Master”演练,确认备用 Master 能顺利接管。
3. 分级数据恢复方案:按故障场景选择对应手段
3.1 RegionServer 宕机:WAL Split 与日志回放
RegionServer 宕机后的恢复流程,HBase 内部其实是自动的,但理解它才能判断哪里会卡壳。宕机后 HMaster 会检测到 RegionServer 失联,然后把这个节点上所有 Region 标记为需要恢复。最关键的一步是把该节点本地磁盘上的 WAL 文件“拆开”,按 Region 分组,再分别回放给接管这些 Region 的新 RegionServer。这个过程叫 WAL split,是恢复速度的瓶颈所在。
如果 RegionServer 是进程崩溃但机器还在,WAL 文件还能读到,split 一般能顺利完成。我们实践中最担心的是机器彻底挂了,WAL 文件拿不到。这时候如果 HDFS 上已经有这个节点 flush 出来的 HFile,数据不会全丢,但内存里未落盘的那部分会永久丢失,只能靠客户端重放或业务方补偿。
这种场景下我的经验是:先确认机器能不能快速拉起,能的话优先把原节点恢复,让 HBase 自己能读到本地 WAL。不能的话,立刻检查 HDFS 上的 HFile 文件完整性,做好“部分数据丢失”的心理准备,同时启动灾备流程,看是否有备份集群、快照或 Replication 数据可以补。
3.2 HMaster 失效:ZooKeeper 协调下的自动切换
HMaster 负责全局的 Region 分配、负载均衡和 DDL 操作,它挂了以后集群不会立刻停止读写,但 Region 无法再自动恢复,新的建表、删表操作也做不了。如果配置了 HA,ZooKeeper 里会维护 active master 的临时节点,备 Master 能接管锁,成为新的 active。
这个过程中最容易出的问题是“双主脑裂”。两个 Master 因为网络分区都认为自己是 active,同时去操作 meta 表,就会把元数据搞乱。HBase 本身通过 ZooKeeper 的分布式锁防止这个问题,但如果你手动干预或者 ZK 状态异常,依然可能遇到。
我的建议是:HMaster 恢复时不要急着去手动 assign Region,先看 ZK 里 active master 是谁,用 hbase zkcli 查一下节点状态。曾经有人把备 Master 直接拉起来,结果它发现 ZK 里已经有 active,自动退出了,大家误以为是启动不成功,反复重启,把问题搞复杂。恢复 HMaster 的关键是耐心等 ZK 会话超时,确实没有 active 再启动新 Master。
3.3 HDFS 块损坏:HFile 修复与副本恢复
HBase 的底层文件都存在 HDFS 上,HFile 默认是 3 副本。如果多副本同时损坏,或者节点宕机导致副本数不足,HDFS 会报块丢失,HBase 读这些文件时会抛异常。这种情况下,恢复思路要先回到 HDFS 层。
第一步用 hdfs fsck /hbase -files -blocks -locations 扫描出损坏块。损坏块通常分为“MISSING”和“CORRUPT”两种。MISSING 是副本数不够,CORRUPT 是文件数据校验失败。前者如果还有一个副本存活,可以等 HDFS 自动复制补齐;后者就比较麻烦,得看 HFile 文件是否还能部分读取。
HBase 2.x 提供了一个检查 HFile 的工具,在 hbase 安装目录下执行:
bash复制hbase hfile -check /hbase/data/default/your_table/uuid/columnfamily/xxxxx
它能逐块校验 HFile 内容,判断是文件头损坏还是数据区损坏。如果文件头还能读,有时可以抢救出一部分数据;如果损坏严重,就得靠快照、备份或 Replication 数据来恢复。这也是为什么我一直强调,HBase 本身再“高可用”,备份还是不能省。
4. 元数据损坏修复实战:hbck / HBCK2 操作手册
4.1 先用工具体检:HBase 2.x 的 HBCK2
元数据损坏是所有故障里最让人头大的。HBase 2.x 已经移除了老的 hbase hbck 修复能力,改用一个独立工具叫 HBCK2。它负责检查 hbase:meta 表、Region 在 HDFS 上的实际状态、RegionServer 上的在线状态这三者是否一致。
HBCK2 的入口有两种,一种是在 HBase 安装目录下直接跑脚本:
bash复制hbase hbck2 -help
另一种是在 HBase Shell 里用 hbck 子命令,效果一样。
体检第一步,先报告 meta 表里缺失的 Region:
bash复制hbase hbck2 reportMissingRegionsInMeta
这个命令会列出 HDFS 上有文件、但 meta 表里没有记录的 Region。接下来再检查 Region 是否处于“应该在线但实际没上线”的状态。HBCK2 会自动输出不一致列表,格式类似:Table=ns:tbl, Region=668a1f4d..., State=CLOSED。
这里有个实操心得:HBCK2 的输出版本差异比较大,有时候信息看着吓人,但很多只是状态未刷新。先别急着做修复,把输出保存下来,对照 HBase Web UI 或 hbase shell 里的 scan 'hbase:meta' 结果,确认到底哪种不一致。
4.2 元数据不一致的典型修复流程
我处理过的元数据问题里,最常见的一类就是“HDFS 上有 Region 文件,但 meta 表里没有记录”,对应 HBCK2 的 addFsRegionsMissingInMeta 命令。执行方式:
bash复制hbase hbck2 addFsRegionsMissingInMeta ns:table
这个命令会把 HDFS 上存在的 Region 信息重新补写进 meta 表。执行完后再用 assigns 命令手动把 Region 分配上线:
bash复制hbase hbck2 assigns -o 668a1f4d...
-o 参数表示覆盖当前状态,适合 Region 卡在 RIT 里出不来的时候。
另一类常见问题是表状态不对。比如表在 meta 里显示 DISABLED,但实际文件都在,业务方此时无法读写。可以用 setTableState 强制纠正:
bash复制hbase hbck2 setTableState 'ns:table' ENABLED
注意执行顺序有讲究:先补 meta,再分配 Region,最后改表状态。我曾经为了省事先改了表状态,结果 assign 的时候触发了一堆校验,反而让 Region 一直无法上线。按顺序一步步来,每一步都验证完再走下一步,看着慢,实际最稳。
HBase 1.x 的老用户还在用 hbase hbck -fix,那是老版本的一键修复参数,功能强大但容易误伤。如果是 2.x 环境,千万别把老 hbck 直接拿来修,HBase 官方明确不支持,强行使用会弄坏 meta 表。
4.3 手工操作时的顺序禁忌
修复元数据时有一个原则:先备份 meta 表再操作。很多人一上来就执行 hbck2 addFsRegionsMissingInMeta,结果发现补写错了,想回滚都没有原始数据。正确做法是先用 HBase 的 snapshot 功能给 hbase:meta 做一次快照:
bash复制hbase shell
snapshot 'hbase:meta', 'meta_backup_before_fix'
虽然 snapshot 对系统表的支持在部分版本有限制,但能建就建,建不了就直接用 export 的方式把 meta 表数据目录复制一份到 HDFS 的其他路径:
bash复制hdfs dfs -cp /hbase/data/hbase/meta /tmp/meta_backup_$(date +%s)
另外,手工修复时尽量停掉 RegionServer 的自动均衡,避免集群一边在分配 Region,一边又因为负载均衡把 Region 挪走,两边打架。
5. 常见问题与排查技巧实录
5.1 Region 一直 RIT 卡住怎么处理
Region 卡在 RIT 是 HBase 恢复中最常见的现象。界面上一堆 Region 处于 OPENING、CLOSING 或 PENDING_CLOSE,进程状态迟迟不变,首先别慌着重启 RegionServer。先看日志里有没有 stuck assignment 的记录,判断卡点是 ZooKeeper 会话异常还是 HDFS 文件访问超时。
如果确认是分配流程卡住,通常用 HBCK2 的 assigns 命令强制触发重新分配即可。但有一种情况是 Region 已经在 meta 里被标记为 OPEN,实际却没有 RegionServer 在服务它,这时候用 assigns -o 覆盖。覆盖前要确认原 RegionServer 确实已经退出,否则会出现双节点同时写同一个 Region 的数据错乱。
5.2 WAL split 卡死,日志刷了一整屏
WAL split 卡死很折磨人。日志里反复出现 Failed to split wal 或 WAL split retry,怎么等都没进展。分析下来,大多数情况是 HDFS 文件系统出了问题,比如 DataNode 容量满、NameNode 进入安全模式、HFile 块损坏导致日志读取失败。
我处理过的一个真实案例是:HDFS 写满,WAL 文件无法被新的 RegionServer 读取,split 一直失败。最后挪走了部分不重要的数据,释放空间后 split 立刻完成。所以遇到 split 卡住,先查 HDFS 状态,特别是剩余空间和文件系统是否健康,再去怀疑 HBase 本身。
如果 HDFS 正常,split 还卡着,可以在 Master 日志里找到 WAL split 的具体路径,然后手动检查这个 WAL 文件在 HDFS 上是否完整。有时候文件本身损坏,HBase 会不断重试。这种情况下可以用 hbase hbck2 scheduleRecoveries 跳过某些损坏日志,接受部分数据可能无法恢复的现实。
5.3 别把单机数据恢复工具的思路套到 HBase 上
搜索“数据恢复”时会看到一堆工具,比如 U 盘数据恢复、移动存储设备数据恢复、单机硬盘恢复软件。这些工具针对的是本地文件系统的误删、格式化、分区丢失,和 HBase 这种分布式数据库完全是两码事。HBase 数据分散在多个节点的 HDFS 上,没有统一的“磁盘镜像”概念,恢复靠的是快照、WAL、HFile 副本和元数据工具,而不是数据恢复软件。
也有人在 Ubuntu 服务器上误操作删除了 HBase 数据目录,问能不能用文件恢复软件找回来。说实话,文件删除后如果进程还在持续写盘,覆盖概率很高,找回的可能性很小。所以与其指望事后恢复,不如在运维规范上做足功夫:HDFS 的 trash 目录开着,定期做快照,数据文件不要手动删除,这些才是治本的办法。
6. 恢复验证与日常抗灾加固
6.1 数据恢复完成后的验证清单
恢复操作做完,不等于收工。我见过太多人把 Region 拉上线后就直接给业务方发“已恢复”,结果业务一查数据不对,二次事故。恢复后的验证动作,一样都不能少。
首先跑一遍 HBCK2 的完整性检查,确认没有新的不一致项。然后针对出问题的表,用 HBase Shell 做一次全表 scan 抽样,看数据行数和时间戳是否正常。有条件的话,对比业务侧在故障前的记录条数,至少核对一个大致数量级。
还要验证写入是否正常。恢复一个表后,插入几条测试数据,再读出来,确认这条链路是通的。最后检查 HDFS 的文件副本数,确保数据文件至少有一个以上副本存在,避免后续再次损坏时完全无法恢复。
6.2 日常备份、快照与定期演练的落地经验
这次文章聊的是“故障后恢复”,但真正吃过亏的人都明白,恢复方案的成败,八成取决于日常准备。HBase 官方提供了快照功能,执行 snapshot 'table', 'backup_name' 可以给整张表做在线快照,对业务影响很小。我建议核心表每天快照一次,快照保留 7 到 15 天,只留增量的话恢复窗口会太长。
跨集群备份可以配合 Replication 机制,把数据实时同步到灾备集群。如果条件不允许,定期用 distcp 把 HDFS 上的 /hbase 目录复制到备份集群,也是一个稳妥的办法。注意 distcp 不能保证 HBase 表在不同集群间的元数据完全一致,恢复时可能需要配合 HBCK2 做元数据重建。
最后,每隔一段时间做一次故障演练。杀一台 RegionServer,模拟元数据损坏,计时看能不能在规定时间内恢复。没有演练过的恢复方案,真出事时基本要现场踩坑。把这套流程沉淀成文件,放在团队共享目录里,出了故障照着执行,比自己临场回忆稳健得多。
我在实际运维中最大的感触是,HBase 的恢复不像是“修一个文件”那么直接,它更像是一套流程:判断故障类型、检查底层文件系统、修复元数据、验证数据完整性。每个环节都踩过坑,但只要把方案提前做扎实,故障来临的时候是可以做到心里有底的。
