云湖湖导读:
HBase是一个结构化数据的分布式存储系统,在Hadoop之上提供了类似于Bigtable的能力。笔者做为资深HBase研发人员,面对不同的业务场景有不同的实用技巧,今天我们将基于HBase集群恢复与迁移展开分享:
1、HBase 2.X版本的元数据修复及一种数据迁移方式
2、一种全量+增量数据的迁移方法
01
HBase 2.X版本的元数据修复及一种数据迁移方式
1.1
背景
在HBase 1.x中,经常会遇到元数据不一致的情况,这个时候使用HBCK的命令,可以快速修复元数据,让集群恢复正常。
另外HBase数据迁移时,大家经常使用到一种迁移方式是:拷贝HBase的数据目录/hbase/data/default到新的集群,然后在新集群执行HBCK的命令让元数据重建,这种拷贝数据目录然后恢复元数据的方式是一种快速直接的手段。
HBase升级到2.X版本之后,hbase hbck中的一些修复命令已经不再支持,包括,所以在HBase遇到集群故障,无法通过HBCK快速把元数据修复,通过HBase数据目录迁移的方式也就使用不了。
在HBase 2.X的客户端执行hbase hbck时,常用的fixMeta命令已经不再支持。
1.2
hck-1无法使用
HBase 2.X版本加强了可靠性,因为使用了 procedure,由于之前的hbck(hbck-1)是会直接去向region server或者hdfs发送请求进行修复,而在HBase 2.0版本上集群内部操作全部都被挪到了procedure v2(下文都称为procedure)上进行处理。
因为所有的命令都是经过master来协调处理,所以在修复时也需要通过master进行修复。否则反而可能导致更严重的不一致问题。所以hbck-1在HBase 2.x版本是不适用的。
1.3
HBase2.X版本中元数据的恢复方法
修改配置hbase.assignment.skip.empty.regions=false;
如果是普通的hbase:meta系统表中的元数据不正确,在修改完此参数重启HBase后就已经能恢复。
当第一步骤完成后还不能修复,就要使用下面的命令了。
例如启动后发现,hbase shell能list出数据,但是表无法put或者scan,这时候hbase:meta表里的t1表记录其实是不正确的;
hbaseorg.apache.hadoop.hbase.util.hbck.OfflineMetaRepair -fix
这个命令需要停止HBase然后执行。
当表的数据目录存在(/hbase/data/default/
执行完成后,启动HBase。
启动完成后,查看hbase:meta表的用户表记录,可以看到t1表的元数据都生成了。
1.4
新集群清理及数据迁移
看完上面的元数据恢复,应该就知道接下来的这种HBase数据迁移方式的原理:通过拷贝数据目录,让HBase元数据与业务数据目录重新建立关系,达到业务正常读写。
下面例子只考虑用户使用default命名空间
拷贝旧集群的HBase数据目录到新集群,将旧集群的/hbase/data/default目录拷贝到了hdfs上的/mydata/目录;
如果新集群数据不需要清理,则跳过此步骤。
停止HBase;
清除HBase在数据存储目录,hdfs dfs -rm -r /hbase;
清除HBase在zk的节点,使用ZK客户端工具zkCli.sh –server :2181 进入后执行deleteall /hbase;
启动HBase,让目录结构自动生成;
保持HBase集群停止状态,拷贝旧机器数据目录到新集群HBase的数据目录中;
hdfs dfs -cp /mydata/default/* /hbase/data/default/
执行hbase修复命令hbase org.apache.hadoop.hbase.util.hbck.OfflineMetaRepair –fix;
设置hbase.assignment.skip.empty.regions=false并启动HBase;
运行完上述步骤,在新的集群就能对迁移过来的HBase进行业务访问了。
02
一种全量+增量数据的迁移方法
2.1
背景
在HBase使用过程中,使用的HBase集群经常会因为某些原因需要数据迁移。大多数情况下,可以跟用户协商用离线的方式进行迁移,迁移离线数据的方式就比较容易了,将整个hbase的data存储目录进行搬迁就行,但是当集群数据量比较多的时候,文件拷贝的时间很长,对客户的业务影响时间也比较长,往往在客户给的时间窗口无法完成,本文给出一种迁移思路,可以利用HBase自身的功能,对集群进行迁移,减少集群业务中断时间。
2.2
简介
大家都知道HBase有snapshot快照的功能,利用快照可以记录某个时间点表的数据将其保存快照,在需要的时候可以将表数据恢复到打快照时间时的样子。我们利用hbase的snapshot可以导出某个时间点的全量数据。
因为用户的业务还在不停的写入表中,除了迁移快照时间点之前的全量数据,我们还需要将快照时间点后源源不断的增量数据也迁移走,这里如果能采用双写的方式,将数据写入两个集群就好了,但是用户的业务不会这样做,如果这样做还得保证双写的事务一致性。于是可以利用HBase的replication功能,replication功能本身就是保留了源集群的WAL日志记录,去回放写入到目的集群,这样一来用户业务端->原始集群->目的集群便是个串形的数据流,且由HBase来保证数据的正确性。
所以这个迁移的方法就是利用snapshot迁移全量数据,利用replication迁移增量数据。
2.3
迁移步骤
上图给出了迁移的整个时间线流程,主要有这么5个时间点。
T0:配置好老集群A集群到新集群B的Replication关系,Replication的数据由A集群同步到集群B,将表设置成同步,从此刻开始新写入A集群表的数据会保留在WAL日志中;
T1:生成该时间点的全量数据,通过创建快照,以及导出快照数据的方式将该时间点的数据导出到新集群B;
T2:新集群B将T1时刻的快照数据导入,此时新集群B中会由快照创建出表,此时老集群A集群上设置的Replication的关系会自动开始将T0时刻保留的WAL日志回放至新集群B的表中,开始增量数据同步。
T3:由于从T0-T3之间的操作会花费一段时间,此时会积累很多WAL日志文件,需要一定的时间来同步至新集群,这里需要去监控一下数据同步情况,等老集群WAL被逐渐消费完,此时可以将老集群的写业务停止一下并准备将读写业务全部切到新集群B。
T4:T3-T4之间应该是个很短的时间,整个迁移也只有这个时间点会有一定中断,此时是让用户将业务完全切到新集群B,至此迁移完成。
2.4
操作涉及的命令
1.设置集群A和集群B的peer关系
在源集群hbase shell中, 设定peer
add_peer 'peer_name','ClusterB:2181:/hbase'
2.在集群A的表中设置replication属性
假设目标表名为Student,先获取Family=f
进入hbase shell中,
alter 'Student',{NAME => 'f',REPLICATION_SCOPE => '1'}
3.给集群A的表创建快照
在hbase shell中
snapshot 'Student','Student_table_snapshot'
4.在A集群中导出快照
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot Student_table_snapshot -copy-to /snapshot-backup/Student
5.将快照数据放置到集群B的对应的目录下
上面命令会导出2个目录,一个是快照元数据,一个是原始数据
将元数据放到/hbase/.hbase-snapshot中,将原始数据放到/hbase/archive目录中
由于hbase的archive目录会有个定时清理,这里可以提前将集群B的master的hbase.master.cleaner.interval值设置大点,避免拷贝过程中发生碰巧发生了数据清理。
如果集群B中没有对应的目录,可以提前创建
hdfs dfs -mkdir -p /hbase/.hbase-snapshot
hdfs dfs -mkdir -p /hbase/archive/data/default/
移动导出的snapshot文件到snapshot目录
hdfs dfs -mv /snapshot-backup/Student/.hbase-snapshot/Student_table_snapshot /hbase/.hbase-snapshot/
hdfs dfs -mv /snapshot-backup/Student/archive/data/default/Student /hbase/archive/data/default/
6.在新集群B中恢复表的快照
进入hbase shell
restore_snapshot 'Student_table_snapshot'
恢复完成后,记得将集群B的hmaster中hbase.master.cleaner.interval的值调整回来。
-END-