摘要: 使用过开源 HBase 的人都知道, 运维 HBase 是多么复杂的事情, 集群大的时候, 读写压力大, 配置稍微不合理一点, 就可能会出现集群状态不一致的情况, 糟糕一点的直接导致入库, 查询某个业务表不可用, 甚至集群运行不了.
概述
使用过开源 HBase 的人都知道, 运维 HBase 是多么复杂的事情, 集群大的时候, 读写压力大, 配置稍微不合理一点, 就可能会出现集群状态不一致的情况, 糟糕一点的直接导致入库, 查询某个业务表不可用, 甚至集群运行不了. 在早期 0.9x 版本的时候, HBase 的修复工具还有一下 bug, 使得即使你懂得如何修复的情况下, 依然需要多次重复运行命令, 绕过那些不合理的修复逻辑, 甚至有时候需要自己写代码预先修复某个步骤.
背景
上周五, 某公司使用的某 DataHup 大数据产品自建一个 HBase 集群挂了! 整个集群有 30+T 业务数据, 是公司的数据中心, 集群直接启动不了. 他们也是经历了熬战一天一夜的情况下, 依旧没有解决恢复, 还曾有过重装集群重导数据念头. 最后, 通过钉钉 HBase 技术交流群找到群主 -- 阿里云 HBase 的封神. 随后其立即下达命令, 临时成立 HBase 抢救小分队, 尽力最大的努力, 使用最低风险的方式, 抢救最完整的集群.
蹭蹭蹭, 几个抢救队员集齐, 开始救火.
救火开始
虽然紧急, 但是抢救工作不能乱, 我们把救火过程主要分为几步:
1. 定位现象问题所在
首先与用户沟通现场环境情况, 以及客户在出问题之前做过哪些重大操作, 特别是一些特殊操作, 平时没做过的. 据用户描述已经远程观察了解到, 用户使用开源的某 DataHup 自建了一个 HBase 集群, 存储公司的大量的业务, 是公司的数据中心. 集群有 7 个 RegionServer,2 个 Master,32 核 256G 的机器配置, 业务数据量有 30+T.HBase 的 master 已经都挂了, 两个 RegionServer 也挂了, 用户使用过 "重启大法", 依旧无法正常运行.
寥寥几句没有更多信息, 我们只能上集群开日志, 打 jstack, 观察 HBase 运行流程为什么中断或者挂掉.
首先我们先检查 HDFS 文件系统, fsck 发现没有什么异常. 其次开始检查 HBase, 把 Debug 日志打开, 全部关闭 HBase 集群, 为了便于观察现象, 只启动一个 Master 和一个 RegionServer. 启动后, 发现 Master 因为 fullscan meta 表 (master 启动的一个流程)timeout Abort 终止了. 观察 meta region 分配到的 RegionServer 也挂了, 查看日志并没有异常, 貌似是这个开源的 DataHup 当 RegionServer scan 数据操作超时 会被 manager kill 掉的样子. 打 jstack 发现, Master 确实在等待 fullscan meta 完成, 而接管 meta region 的 RegionServer 确实一直在忙着 scan meta 数据, 确实有忙不过来超时了. 按理说, 扫描 meta 表应该很快的才对.
检查发现 HDFS 的 HBase meta 表有 1T 多数据!!! 进一步查看现象 HFile 的内容, 发现了大量的 Delete famly 的 cell 存在, 而且很多是重复的, 序列号 (没有截图, 想象一下). 问题现象定位了, 用户使用这个系列的 DataHup 的 HBase 生态时, 有组件存在 bug 往 hbase meta 表写了大量的这些冗余的 delete 数据, 导致 hbase 启动时 full scan meta 卡着, 最终导致整个集群无法正常启动运行服务.
2. 提出解决方案, 评估风险
我们很快生成了两个相对较优的方案. 第一个是使用离线 compaction, 把 hbase meta 表进行一次 major compaction 把多余的 delete family 删除, 然后再重启即可. 第二个方案是, 直接移除 meta 表的无用 hfile, 逆向生成 meta 表数据进行修复 meta 表即可.
第一个方案做离线 compaction 对集群来说没有什么风险, 缺点是离线 compaction 并不快, 因为 meta 表 region 只有一个, 执行离线 meta 表 compaction 时只有一个 task, 非常的缓慢耗时.
第二个方案是逆向修复 meta 表信息. 看似风险很大, 其实实际操作起来, 很多风险可以降低. 我们可以备份好核心的元数据, 只有就可以在恢复失败的时候, 还原到原来修复手术的前状态. 这样一来, 这个修复过程也就风险极大降低了.
3. 开始实施
秉着更安全风险更低的情况下, 我们还是先选择了方案一, 给 meta 表做离线 major compaction 的方案. 但最终因为 MapReduce 和本地模式的 compaction 都太慢了, 开始会 oom, 调整后, 最终因 meta 的 hfile checksum 校验失败中断了. meta 表的 hfile 都存在问题, 那么这个 compaction 过程就不能正常进行了.
我们开始选择方案二, 和用户沟通风险后, 开始制定操作步骤, 把这个方案的实施带来的风险尽可能降到最低. 规避这个方案存在的风险, 前提是懂得这个方案会有什么风险. 下面我们来分析一下, 如图:
可以看到, 开源 HBase 的 meta 表, 是可以逆向生成回来的, 但是有可能不同的 DataHup 生产商可能会有一些额外的信息 hack 进 meta 表里, 对于这部分信息, 在开源的逆向生成过程中是不包含的, 存在这个关系数据丢失. 但是这些核心的业务数据都存在, 只是 hack 的第三方关联信息不存在了. 有人可能会问, 会有哪些数据可能 hack 到这里呢? 曾看到过某厂商会在 meta 表了多加一些额外的字段用来保存 virtual hostname 信息, 还有一些将二级索引相关的信息会保存在 tableinfo 文件那里. HBase 的开发商越多, 什么姿势都可能存在, 这个就是可能的风险点.
接下来我们开始实施, 这个问题比较典型, 用户的 meta 表里, 有 1T 多的 hfile 数据, 检查 hfile 发现几乎 99% 的 hfile 是 delete famly 相关的内容, 我们就移除这些 delete famly 的 hfile 到备份目录, 只留下一个正常数据的 hfile, 而这个 hfile 也仅仅有 30M 左右的数据. 重启 HBase 后, 正常运行. HBase 一致性检查发现很幸运, 没有坏文件, 也没有丢失的 tableinfo,regioninfo,hfile 相关的 block 等. 如果发现有文件丢失, corrupt hfile 等等问题, 逆向生成元数据的修复过程就可能会带来风险, 但 HBase 集群核心业务数据依然可以完整挽救.
4. 用户再自己验证一下是否正常
通知用户验证集群运行, 业务运行情况.
来源: http://geek.csdn.net/news/detail/258913