转载自 | HBase技术社区
微信号 | hbasegroup
最近知识星球有人问浪尖,自己的hbase集群元数据丢失了,但是数据还在,是否能够修复,其实这种情况下利用数据的hfile去修复元数据很常见,也有很多时候我们是生成hfile加载进hbase。
那么他又问了,假设数据也丢失了,或者数据存在大量坏块,是否能进行修复。首先要先修复坏块,一本有副本,假设不是所有数据副本一起损坏,通过清除坏块,修复副本,然后再逆向修复hbase的元数据也是可行的。但是如果清除坏块之后数据丢了,那也可以修复hbase元数据,只是丢了数据而已。
HBase中的元数据表中记录了Region的路由信息,如果元数据被损坏,将会影响正常的HBase读写业务,而元数据被损坏的问题时有发生,这篇文章介绍了如何进行元数据逆向修复的原理与操作。
在实际的HBase运维中,会碰到各色各样的问题,如RegionServer异常退出,重启进程很慢,Region长时间处于RIT状态等等,为了帮助大部分读者提供HBase的运维能力,后续会针对"HBase运维专题"写一系列文章,欢迎大家关注社区公众号最新动态。
本文整体思路如下:
本文内容基于HBase 1.x版本。
HBase在HDFS上使用一个独立的目录作为HBase文件目录的根目录,通常为"/hbase",该目录结构布局如下:
/hbase/archive
进行snapshot或者升级的时候使用到的归档目录。Compaction删除HFile的时候,也会把旧的HFile归档到这里。
/hbase/corrupt
splitlog的corrupt目录,以及corrupt hfile的目录。
/hbase/data/default/[TableName]/.tabledesc/.tableinfo.0000000001
表的基本属性信息元文件tableinfo。
/hbase/data/default/[TableName]/[RegionName]/info/[HFileName]
对应表下的hfile数据文件。
/hbase/data/default/[TableName]/[RegionName]/recovered.edits/340.seqid
当splitlog发生时,一个RS的wal会按照region级别split WALs写到对应目录下的的recovered.edits目录上,使得此region再次被open的时候,回放这些recovered.edits日志。
/hbase/data/default/[TableName]/[RegionName]/.regioninfo
regioninfo文件。
/hbase/data/default/[TableName]/[RegionName]/.tmp
compaction等的临时tmp目录。
/hbase/data/default/[TableName]/[RegionName]/.splits
Region split操作的临时目录,如果上次region的split没有完成被中断了,这个region再open的时候会自动清理这个目录,一般不需要人工干预。
/hbase/data/default/[TableName]/[RegionName]/.merges
merges时的临时目录,和split一样,如果没有正常完成的时候被中断了,那么它会在下次被open的时候自动被清理,一般不需要人工干预。
/hbase/data/hbase/acl
acl开启HBase权限控制时的权限记录系统表。
/hbase/data/hbase/meta
元数据表,记录region相关信息。
/hbase/hbase.id
集群启动初始化的时候,创建的集群唯一id。可以重新fix生成。
/hbase/hbase.version
HBase软件版本文件,代码静态版本。
/hbase/MasterProcWALs
master执行过程程序的状态保存,用于中断恢复执行使用。
/hbase/oldWALs
oldWALs历史wal,即wal记录的数据已经确认持久化了,那么这些wal就会被移到这里。splitlog完成的那些旧日志,也会被放到这里。
/hbase/.tmp
tmp临时辅助目录,比如写一个hbase.id文件,在这里写成功后,rename到 /hbase/hbase.id
/hbase/.trashtables/data
当truncate table或者delete table的时候,这些数据会临时存放在这里,默认1小时内被清理
/hbase/WALs/[RegionServerName]/[WALFileName]
记录着一台RegionServer上的WAL日志文件。可以看到它是regionserver名字是有时间的,即下一次启动时RS的wal目录就会使用新的目录结构存放wal,这个旧的RS wal目录就会被splitlog过程拆分回放。
HBase在HDFS上存放的数据文件,包括:
HFile
数据文件,目前最高版本也是默认常用版本为3。HFile文件结构细节可以参考官网http://hbase.apache.org/book.html#_hfile_format_2。我们这里逆向生成元数据主要使用到了HFile Fileinfo中的的{firstkey、lastkey}信息。
hfilelink
在hbase snapshot时用到, migration upgrade 也会使用到。很少碰到这类文件的运维问题,这里不作过多介绍。
reference
用来指定half hfile,一个region有reference文件时,这个region不能执行split操作。split/merge会创建这类文件。进行compaction后生成新的hfile后,会把对应的reference文件删除。
HFile的reference文件名格式一般为hfile.parentEncodeRegion。
如:/hbase/data/default/table/region-one/family/hfilename。
其region-two有reference hfile文件名格式为:
/hbase/data/default/table/region-two/family/hfile.region-one
通常无效引用就是region-one的hfile不存在了,那么这个引用就会失效,具体的修复方法一般是把reference无效的引用移除。
.regioninfo
包含Region的{endkey, offline标志, regionid, regionName, split标志, startkey, tablename}等信息。
tableinfo
包含{TableName, Table属性信息, Table级别Config信息, ColumnFamily信息}。
其中ColumnFamily信息包含{FamliyName, Family属性, Family级别config信息}等。
常见的表属性包括:
{REGION_MEMSTORE_REPLICATION,PRIORITY,IS_ROOT_KEY,...}。
列族属性包括:
{BLOCKSIZE,TTL,REPLICATION_SCOPE,COMPRESSION, BLOCK_ENCODING,...}。
HBase元数据表格式定义
HBase元数据的完整名称为"hbase:meta",其中,"hbase"为元数据表所在的NameSpace名称。每一个Region的信息在元数据表中都以独立的行存在,这一行数据的格式定义如下:
RowKey:[RegionName]
Qualifier:info:regioninfo
RegionInfo的EncodeValue值
Qualifier:info:seqnumDuringOpen
序列号
Qualifier:info:server
Region所在的RegionServer名称
Qualifier:info:serverstartcode
Regionserver启动时的Timestamp
上述介绍的数据文件中,HBase的元数据主要由meta表、tableinfo、regioninfo构成。这里的逆向生成元数据主要是指:根据HFile数据文件,反向生成regioninfo/tableinfo/meta表的过程。
1. 逆向生成tableinfo文件
Case 1:通过从Master进程内存中的tabledescritor cache 完整恢复tableinfo文件,此时恢复的tableinfo是完整的,和之前的完全一样。
Case 2:当cache中没有加载过此表的tableinfo时,修复过程只能从表的目录结构list所有familyNames来恢复tableinfo,这个时候只能得到的是列族的名字,恢复tableinfo文件内容中,除了表名、列族名一致,其它属性均采用默认值。这个时候如果运维人员知道有什么属性是自定义进去的,那么就需要要手动再次添加进去。
2. 逆向生成regioninfo文件
HFile中的fileinfo读取{firstkey,lastkey},排序后得到Region下所有HFile的最大rowkey和最小rowkey,并根据tableinfo中的表名完整恢复Regioninfo文件。
这里只能恢复{表名,startkey,endkey}, 其它属性如:{offline标志, regionName, split标志, hashcode}等均使用代码重新生成或使用配置默认值。
3. 逆向填充meta表行
regioninfo文件序列化,填入meta表 info:regioninfo 列,并同时写入默认的server,等它被再次open的时候,重新分配region到实际的regionserver上,并更新这里的数据行。
逆向工程除了上面的数据文件、数据内容修复外,还涉及到数据的完整性等其它方面修复。一个表是由无穷小的rowkey到无穷大的rowkey范围组成,还可能会发生的问题如:Region空洞、Region重叠现象,如:
如果有Region空洞的时候,就会使用他们的空洞边界作为startkey/endkey,再修复创建一个Region目录及目录下的regioninfo文件。如果是Region重叠,则会把重叠的Region进行合并,取所有Region的最大最小rowkey作为merge后新Region的最大最小rowkey。
元数据的缺失或者完整性有问题,会影响系统运行,甚至导致集群不可用。最常见的问题如meta表上线失败,Region上线open失败等。这里介绍两个工具:
工具1: HBase hbck,在线修复工具,可完整性修复HBase元数据信息
工具2:OfflineMetaRepair, 可离线重建 hbase:meta元数据表
前提条件:HDFS fsck 确保HBase根目录下文件没有损坏丢失,如果有,应该先考虑修复/处理corrupt的block。
步骤1:hbase hbck 检查输出所以ERROR信息,每个ERROR都会说明错误信息。
步骤2:hbase hbck -fixTableOrphones 先修复tableinfo缺失问题,根据内存cache或者hdfs table 目录结构,重新生成tableinfo文件。
步骤3:hbase hbck -fixHdfsOrphones 修复regioninfo缺失问题,根据region目录下的hfile重新生成regioninfo文件。
步骤4:hbase hbck -fixHdfsOverlaps 修复region重叠问题,merge重叠的region为一个region目录,并从新生成一个regioninfo。
步骤5:hbase hbck -fixHdfsHoles 修复region缺失,利用缺失的rowkey范围边界,生成新的region目录以及regioninfo填补这个空洞。
步骤6:hbase hbck -fixMeta 修复meta表信息,利用regioninfo信息,重新生成对应meta row填写到meta表中,并为其填写默认的分配regionserver。
步骤7:hbase hbck -fixAssignment 把这些offline的region触发上线,当region开始重新open上线的时候,会被重新分配到真实的RegionServer上 , 并更新meta表上对应的行信息。
离线修复
前提条件:HDFS fsck确保hbase根目录下文件没有损坏丢失,如果有,应该先考虑修复/处理corrupt的block。
步骤: 执行如下命令即可:
hbase org.apache.hadoop.hbase.util.hbck.OfflineMetaRepair -fix
HBase官网或工具命令提示信息中,都有关于这两个工具的详细使用说明,这里不再展开更多内容。一些题外话,有些开源组件设计的时候,向HBase元数据文件写入一些特有的信息,但是并没有修改到HBase工具的修复工具,或者它自己没有维护修复工具,如果这类文件损坏、丢失了,那么相应的组件就会运行不正常。使用这类组件的用户,应该不仅记录好你的表的基本结构,还要记录表的属性配置等,当发生修复运维行为的时候,需要再次核对确认。
本文介绍了运维HBase基础原理中的数据完整性以及逆向元数据修复原理,并介绍了两个逆向修复元数据的工具和实用执行步骤。后续会推出系列文章,介绍更多HBase运维基础、运作原理等,希望能给大家的运维和如何使用HBase方面带来一些帮助。