【HBase】增量数据迁移

hbase数据迁移,不乏有许多好的文章

 

比如:

HBase 数据迁移方案介绍:https://blog.csdn.net/mnasd/article/details/97616460(转载者:mnasd)

HBase集群数据迁移方案:https://blog.csdn.net/scgaliguodong123_/article/details/46761529(作者:李国东)

其实方法很多是好事,但对于不太了解hbase的使用者来说也是一种折磨

关键点在于,如何在我的老hbase集群(后面称A集群)数据还在持续写入的时候,迁移集群到新的hbase(后称B集群),不中断服务,也不丢失数据

所以接下来我使用了两种同步方式,replication+snapshot

一、Replication同步(在线同步)

先创建在线同步,让新的数据能在两个集群中都存在

1、确保A集群能访问B集群的所有机器

包括:主机名和ip的映射(vi /etc/hosts)

端口开放(telnet ip 端口),主要的端口就是,zk的2181,hregionserver的16020,hmaster的1600

2、A集群修改配置hbase-site.xml,滚动重启A集群的hbase服务

  <property>
    <name>hbase.replication</name>
    <value>true</value>
  </property>

3、 添加一条复制peer

add_peer '1', CLUSTER_KEY => "B集群zk1,B集群zk1,B集群zk1:2181:/hbase"

这里的/hbase,是因为B集群下面的参数

  <property>
    <name>zookeeper.znode.parent</name>
    <value>/hbase</value>
  </property>

查看所有peer:list_peers

删除某个peer:remove_peer '1'

注:set_peer_tableCFs '1','表名' 这条命令还可以规定那个peer同步哪些表,甚至哪些列簇,具体使用大家可用百度,我这里没那么复杂就不搞了,设置之后,可以通过list_peers查看到

4、enable_table_replication 'tablename'

   

这一步我遇到过如上三问题:

第一个是host映射没做好(每台机器都要配置!)

第二个是add_peer的时候B集群的zookeeper.znode.parent填错了

第三个是B集群已经有这张表了,导致失败(去把B集群这张表删了)

禁止复制这张表:disable_table_replication 'tablename'

5、插入数据验证

接下来往A集群的那张表中插入数据,然后到B集群:scan 'tablename',如果能看到数据证明成功了

注:如果只是看到表被创建了,但是没有数据写入,那很有可能是A集部署hregionserver的机器,访问B集群的服务失败,请重新检查:1、确保A集群能访问b集群的所有机器

二、存量数据同步(snapshot)

1、生成快照

snapshot 'tablename', '快照名称'

删除快照:delete_snapshot '快照名称'
查看快照:list_snapshots 

2、通过快照获得数据

# 将该快照的数据生成到hdfs上的/hbase-snapshot中:
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot 快照名称 -copy-from hdfs://header:8020/hbase -copy-to hdfs://header:8020/hbase-snapshot/

3、将刚刚生成的数据块上传到B集群中

由于我只是做测试,数据量不大

所以直接把A集群上hdfs的数据拉到了本地磁盘

然后scp发送到了B集群

最后B集群再把这个数据块上传到了hdfs,命令如下(理论上也可以distcp直接跨集群copy)

A集群执行:hdfs dfs -copyToLocal /hbase-snapshot ~

A集群执行:scp -r hbase-snapshot/ root@B集群ip:~

B集群执行:hdfs dfs -put hbase-snapshot /

注:执行数据同步的时候,我试过把文件拉到Windows,然后通过ftp工具上传到另一台机器,我发现linxu的以"."开头的隐藏文件,居然丢失了,导致后面恢复数据的时候失败,大家注意下这个!

4、将数据块加载到B集群的表中

我们一开始采用了:

B集群执行:hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot 快照名称 -copy-from hdfs://B集群header:8020/hbase-snapshot -copy-to hdfs://B集群header:8020/hbase/

-copy-to的地址是/hbase,是因为hbase.rootdir是/hbase

然后restore_snapshot '快照名称'

但是我们发现这样会覆盖replication同步过来的数据,有丢失数据的风险,所以我们采用如下的方式

我们写了脚本将hbase的hfile块同步到B集群中

可以观察下你同步过来的snapshot文件,archive/data这个目录下,是具体的namespace,然后是表名,然后就是实际的hfile块

(1)、获得快照中对应表的hfile列表

hadoop fs -ls /hbase-snapshot/archive/data/namespace名称/表名 | grep 表名  | awk '{print $8}' >表名.hfile.list

(2)、写个脚本

将本地生成的list和hdfs的快照目录的list对比,如果匹配上了,就通过LoadIncrementalHFiles将每个文件块都同步到hbase

hfile_list_local_file=$1
snapshot_hdfs_filepath=$2
ns_name=$3
tbl_name=$4


hfile_num_1=`cat $hfile_list_local_file | wc -l`
hfile_num_2=`hadoop fs -ls $snapshot_hdfs_filepath | grep  $tbl_name | grep $ns_name | wc -l`


if [ $hfile_num_1 -eq $hfile_num_2 ];
then
  echo "hfiles num is $hfile_num_1"
else
  echo "hfiles not match, exit 1..."
  exit 1
fi


while read line; do
# reading each line
echo $line
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles $line $ns_name:$tbl_name
done < $hfile_list_local_file

(3)、运行脚本

sh load_incremental_hfiles.sh 表名.hfile.list /hbase-snapshot/archive/data/namespace名称/表名/ namespace名称 表名

三、题外话

我稍微看了下LoadIncrementalHFiles的代码

代码中先是在LoadIncrementalHFiles里做了一堆校验,然后把请求发送给了服务端,然后服务端开始处理bulkLoadHFile请求

服务端:

下图的方法中做了重命名(应该也是改了路径,把快照目录中的文件块mv到了正式目录)


然后把刚刚mv过来的文件加入到storefilemanager里面,管理起来了,只有hbase就能查到数据了

(加入的时候还用了写锁和释放写锁,看来文件关联上的时候,会造成B集群数据短暂的写入不了)


 

所以他的原理就是mv文件块正式目录,然后把文件块的信息,关联到storeEngine上,这样就算有重复的数据,hbase也只会查到timestamp最新的数据,保证了数据不丢失,而且同步数据的时候基本不影响老集群上的服务!

感谢以下两位博主的文章:

http://www.itkeyword.com/doc/2372176198145978x416/region-bulkload-store

https://blog.csdn.net/gyxinguan/article/details/100002099

好了,本文其实是大师给的方案,我只是学习和测试,努力努力,像大师看齐

这篇文章比较早就写了,没有发布,今天稍微整理下发不出来,前几天台风“烟花”还是比较严重的,搞的我今天才到杭州~下班,最近感觉好多东西要学啊,加油加油加油!!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值