1818IP-服务器技术教程,云服务器评测推荐,服务器系统排错处理,环境搭建,攻击防护等

当前位置:首页 - 运维 - 正文

君子好学,自强不息!

HBase数据迁移方案介绍

2022-11-14 | 运维 | gtxyzz | 586°c
A+ A-

一、前言

HBase数据迁移是很常见的操作,目前业界主要的迁移方式主要分为以下几类:

图1.HBase数据迁移方案

从上面图中可看出,目前的方案主要有四类,Hadoop层有一类,HBase层有三类。下面分别介绍一下。

二、Hadoop层数据迁移

2.1 方案介绍

Hadoop层的数据迁移主要用到DistCp(Distributed Copy), 官方描述是:DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具。它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成。它把文件和目录的列表作为map任务的输入,每个任务会完成源列表中部分文件的拷贝。

我们知道MR程序适合用来处理大批量数据, 其拷贝本质过程是启动一个MR作业,不过DisctCp只有map,没有reducer。在拷贝时,由于要保证文件块的有序性,转换的最小粒度是一个文件,而不像其它MR作业一样可以把文件拆分成多个块启动多个map并行处理。如果同时要拷贝多个文件,DisctCp会将文件分配给多个map,每个文件单独一个map任务。我们可以在执行同步时指定-m参数来设定要跑的map数量,默认设置是20。如果是集群间的数据同步,还需要考虑带宽问题,所以在跑任务时还需要设定 bandwitdh 参数,以防止一次同步过多的文件造成带宽过高影响其它业务。同时,由于我们HBase集群一般是不会开MR调度的,所以这里还需要用到单独的MR集群来作主备数据同步,即在跑任务时还需要指定mapreduce相关参数。

简单的distcp参数形式如下:

hadoopdistcphdfs://src-hadoop-address:9000/table_namehdfs://dst-hadoop-address:9000/table_name

如果是独立的MR集群来执行distcp,因为数据量很大,一般是按region目录粒度来传输,同时传输到目标集群时,我们先把文件传到临时目录,最后再目的集群上load表,我们用到的形式如下:

hadoopdistcp\
-Dmapreduce.job.name=distcphbase\
-Dyarn.resourcemanager.webapp.address=mr-master-ip:8088\
-Dyarn.resourcemanager.resource-tracker.address=mr-master-dns:8093\
-Dyarn.resourcemanager.scheduler.address=mr-master-dns:8091\
-Dyarn.resourcemanager.address=mr-master-dns:8090\
-Dmapreduce.jobhistory.done-dir=/history/done/\
-Dmapreduce.jobhistory.intermediate-done-dir=/history/log/\
-Dfs.defaultFS=hdfs://hbase-fs/\
-Dfs.default.name=hdfs://hbase-fs/\
-bandwidth20\
-m20\
hdfs://src-hadoop-address:9000/region-hdfs-path\
hdfs://dst-hadoop-address:9000/tmp/region-hdfs-path

在这个过程中,需要注意源端集群到目的端集群策略是通的,同时hadoop/hbase版本也要注意是否一致,如果版本不一致,最终load表时会报错。

2.2 方案实施

迁移方法如下:

第一步,如果是迁移实时写的表,最好是停止集群对表的写入,迁移历史表的话就不用了,此处举例表名为test;

第二步, flush表, 打开HBase Shell客户端,执行如下命令:

hbase>flush'test'

第三步,拷贝表文件到目的路径,检查源集群到目标集群策略、版本等,确认没问题后,执行如上带MR参数的命令

第四步, 检查目标集群表是否存在,如果不存在需要创建与原集群相同的表结构

第五步,在目标集群上,Load表到线上,在官方Load是执行如下命令:

hbaseorg.jruby.Mainadd_table.rb/hbase/data/default/test

对于我们来说,因我们先把文件同步到了临时目录,并不在原表目录,所以我们采用的另一种形式的load,即以region的维度来Load数据到线上表,怎么做呢,这里用到的是org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles这个类,即以bulkload的形式来load数据。上面同步时我们将文件同步到了目的集群的/tmp/region-hdfs-path目录,那么我们在Load时,可以用如下命令来Load region文件:

hbaseorg.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles-Dhbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily=1024hdfs://dst-hadoop-address:9000/tmp/region-hdfs-path/region-nametable_name

这里还用到一个参数hbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily, 这个表示在bulkload过程中,每个region列族的HFile数的上限,这里我们是限定了1024,也可以指定更少,根据实际需求来定。

第六步,检查表数据是否OK,看bulkload过程是否有报错

在同步过程中,我们为加块同步速度,还会开个多线程来并发同步文件,这个可根据实际数据量和文件数来决定是否需要使用并发同步。

三、HBase层数据迁移

3.1 copyTable方式

copyTable也是属于HBase数据迁移的工具之一,以表级别进行数据迁移。copyTable的本质也是利用MapReduce进行同步的,与DistCp不同的时,它是利用MR去scan 原表的数据,然后把scan出来的数据写入到目标集群的表。这种方式也有很多局限,如一个表数据量达到T级,同时又在读写的情况下,全量scan表无疑会对集群性能造成影响。

来看下copyTable的一些使用参数:

Usage:CopyTable[generaloptions][--starttime=X][--endtime=Y][--new.name=NEW][--peer.adr=ADR]<tablename>
Options:
rs.classhbase.regionserver.classofthepeercluster
specifyifdifferentfromcurrentcluster
rs.implhbase.regionserver.implofthepeercluster
startrowthestartrow
stoprowthestoprow
starttimebeginningofthetimerange(unixtimeinmillis)
withoutendtimemeansfromstarttimetoforever
endtimeendofthetimerange.Ignoredifnostarttimespecified.
versionsnumberofcellversionstocopy
new.namenewtable'sname
peer.adrAddressofthepeerclustergivenintheformat
hbase.zookeeer.quorum:hbase.zookeeper.client.port:zookeeper.znode.parent
familiescomma-separatedlistoffamiliestocopy
Tocopyfromcf1tocf2,givesourceCfName:destCfName.
Tokeepthesamename,justgive"cfName"
all.cellsalsocopydeletemarkersanddeletedcells
Args:
tablenameNameofthetabletocopy
Examples:
Tocopy'TestTable'toaclusterthatusesreplicationfora1hourwindow:
$bin/hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable--starttime=1265875194289--endtime=1265878794289--peer.adr=server1,server2,server3:2181:/hbase--families=myOldCf:myNewCf,cf2,cf3TestTable
Forperformanceconsiderthefollowinggeneraloptions:
-Dhbase.client.scanner.caching=100
-Dmapred.map.tasks.speculative.execution=false

从上面参数,可以看出,copyTable支持设定需要复制的表的时间范围,cell的版本,也可以指定列簇,设定从集群的地址,起始/结束行键等。参数还是很灵活的。

copyTable支持如下几个场景:

1、表深度拷贝:相当于一个快照,不过这个快照是包含原表实际数据的,0.94.x版本之前是不支持snapshot快照命令的,所以用copyTable相当于可以实现对原表的拷贝, 使用方式如下:

create'table_snapshot',{NAME=>"i"}
hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable--new.name=tableCopytable_snapshot

2、集群间拷贝:在集群之间以表维度同步一个表数据,使用方式如下:

create'table_test',{NAME=>"i"}#目的集群上先创建一个与原表结构相同的表
hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable--peer.adr=zk-addr1,zk-addr2,zk-addr3:2181:/hbasetable_test

3、增量备份:增量备份表数据,参数中支持timeRange,指定要备份的时间范围,使用方式如下:

hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable...--starttime=start_timestamp--endtime=end_timestamp

4、部分表备份:只备份其中某几个列族数据,比如一个表有很多列族,但我只想备份其中几个列族数据,CopyTable提供了families参数,同时还提供了copy列族到新列族形式,使用方式如下:

hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable...--families=srcCf1,srcCf2#copycf1,cf2两个列族,不改变列族名字
hbaseorg.apache.hadoop.hbase.mapreduce.CopyTable...--families=srcCf1:dstCf1,srcCf2:dstCf2#copysrcCf1到目标dstCf1新列族

总的来说,CopyTable支持的范围还是很多的,但因其涉及的是直接HBase层数据的拷贝,所以效率上会很低,同样需要在使用过程中限定扫描原表的速度和传输的带宽,这个工具实际上使用比较少,因为很难控制。

3.2 Export/Import方式

此方式与CopyTable类似,主要是将HBase表数据转换成Sequence File并dump到HDFS,也涉及Scan表数据,与CopyTable相比,还多支持不同版本数据的拷贝,同时它拷贝时不是将HBase数据直接Put到目标集群表,而是先转换成文件,把文件同步到目标集群后再通过Import到线上表。主要有两个阶段:

Export阶段: 将原集群表数据Scan并转换成Sequence File到Hdfs上,因Export也是依赖于MR的,如果用到独立的MR集群的话,只要保证在MR集群上关于HBase的配置和原集群一样且能和原集群策略打通(master&regionserver策略),就可直接用Export命令,如果没有独立MR集群,则只能在HBase集群上开MR,若需要同步多个版本数据,可以指定versions参数,否则默认同步最新版本的数据,还可以指定数据起始结束时间,使用如下:

#output_hdfs_path可以直接是目标集群的hdfs路径,也可以是原集群的HDFS路径,如果需要指定版本号,起始结束时间
hbaseorg.apache.hadoop.hbase.mapreduce.Export<tableName><ouput_hdfs_path><versions><starttime><endtime>

Import阶段: 将原集群Export出的SequenceFile导到目标集群对应表,使用如下:

#如果原数据是存在原集群HDFS,此处input_hdfs_path可以是原集群的HDFS路径,如果原数据存在目标集群HDFS,则为目标集群的HDFS路径
hbaseorg.apache.hadoop.hbase.mapreduce.Import<tableName><input_hdfs_path>

3.3 Snapshot方式

3.3.1 snapshot介绍

此方式与上面几中方式有所区别,也是目前用得比较多的方案,snapshot字面意思即快照, 传统关系型数据库也有快照的概念,HBase中关于快照的概念定义如下:

快照就是一份元信息的合集,允许管理员恢复到表的先前状态,快照不是表的复制而是一个文件名称列表,因而不会复制数据

因不拷贝实际的数据,所以整个过程是比较快的,相当于对表当前元数据状态作一个克隆,snapshot的流程主要有三个步骤:

图2.数据迁移图

加锁: 加锁对象是regionserver的memstore,目的是禁止在创建snapshot过程中对数据进行insert,update,delete操作

刷盘:刷盘是针对当前还在memstore中的数据刷到HDFS上,保证快照数据相对完整,此步也不是强制的,如果不刷会,快照中数据有不一致风险

创建指针: snapshot过程不拷贝数据,但会创建对HDFS文件的指针,snapshot中存储的就是这些指标元数据

3.3.2 snapshot内部原理

snapshot实际内部是怎么做的呢,上面说到,snapshot只是对元数据信息克隆,不拷贝实际数据文件,我们以表test为例,这个表有三个region, 每个region分别有两个HFile,创建snapshot过程如下:

图3.snapshot创建内部原理

创建的snapshot放在目录/hbase/.hbase-snapshot/下, 元数据信息放在/hbase/.hbase-snapshot/data.manifest中, 如上图所示,snapshot中也分别包含对原表region HFile的引用,元数据信息具体包括哪哪些呢:

1.snapshot元数据信息
2.表的元数据信息&schema,即原表的.tableinfo文件
3.对原表Hfile的引用信息

由于我们表的数据在实时变化,涉及region的Hfile合并删除等操作,对于snapshot而言,这部分数据HBase会怎么处理呢,实际上,当发现spit/compact等操作时,HBase会将原表发生变化的HFile拷贝到/hbase/.archive目录,如上图中如果Region3的F31&F32发生变化,则F31和F32会被同步到.archive目录,这样发生修改的文件数据不至于失效,如下图所示:

图4.snapshot文件迁移

快照中还有一个命令就是clone_snapshot, 这个命令也很用,我们可以用它来重命名表,恢复表数据等。具体用法如下:

hbase>clone_snapshot'snapshot_src_table','new_table_name'

这个命令也是不涉及实际数据文件的拷贝,所以执行起来很快,那拷贝的是什么呢,与上面提到的引用文件不同,它所生成的是linkfile,这个文件不包含任何内容,和上面引用文件一样的是,在发生compact等操作时,会将原文件copy到/hbase/.archive目录。

比如我们有一个表test, 有一个region原表信息如下:

hbaseuser:~>hadoopfs-ls/hbase/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/*
Found1items
-rw-r--r--1hbaseusersupergroup372017-12-0111:44/hbase/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/.regioninfo
Found1items
-rw-r--r--1hbaseusersupergroup9832017-12-0112:13/hbase/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/i/55c5de40f58f4d07aed767c5d250191

在创建一个snapshot之后:snapshot ‘test’, ‘snapshot_test’,在/hbase/.hbase-snapshot目录信息如下:

hbaseuser~>hadoopfs-ls/hbase/.hbase-snapshot/snapshot_test
Found4items
-rw-r--r--1hbaseusersupergroup322017-12-0112:13/hbase/.hbase-snapshot/snapshot_test/.snapshotinfo
drwxr-xr-x-hbaseusersupergroup02017-12-0112:13/hbase/.hbase-snapshot/snapshot_test/.tabledesc
drwxr-xr-x-hbaseusersupergroup02017-12-0112:13/hbase/.hbase-snapshot/snapshot_test/.tmp
drwxr-xr-x-hbaseusersupergroup02017-12-0112:13/hbase/.hbase-snapshot/snapshot_test/d8340c61f5d77345b7fa55e0dfa9b492

在clone_snapshot之后:clone_snapshot ‘snapshot_test’,’new_test’,在/hbase/archive/data/default目录,有对原表的link目录,目录名只是在原HFile的文件名基础上加了个links-前缀,这样我们可以通过这个来定位到原表的HFile,如下所示:

hbaseuser:~>hadoopfs-ls/hbase/archive/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/i
Found1items
drwxr-xr-x-hbaseusersupergroup02017-12-0112:34/hbase/archive/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/i/.links-55c5de40f58f4d07

此时,再执行合并操作:major_compact ‘new_test’,会发现/hbase/archive/data/default/目录已经变成了实际表的数据文件,上面图中/hbase/archive/data/default/test/d8340c61f5d77345b7fa55e0dfa9b492/i/.links-55c5de40f58f4d07这个已经不在了,取而代之的是如下所示文件:

hbaseuser:~>hadoopfs-ls/hbase/archive/data/default/new_test/7e8636a768cd0c6141a3bb45b4098910/i
Found1items
-rw-r--r--1hbaseusersupergroup02017-12-0112:48/hbase/archive/data/default/new_test/7e8636a768cd0c6141a3bb45b4098910/i/test=d8340c61f5d77345b7fa55e0dfa9b492-55c5de40f58f4d07aed767c5d250191c

在实际的/hbase/data/default/new_test目录也是实际的原表的数据文件,这样完成了表数据的迁移。

3.3.3 snapshot数据迁移

snapshot的应用场景和上面CopyTable描述差不多,我们这里主要考虑的是数据迁移部分。数据迁移主要有以下几个步骤:

A.创建快照:在原集群上,用snapshot命令创建快照,命令如下:

hbase>snapshot'src_table','snapshot_src_table'
#查看创建的快照,可用list_snapshots命令
hbase>list_snapshots
#如果快照创建有问题,可以先删除,用delete_snapshot命令
hbase>delete_snapshot'snapshot_src_table'

创建完快照后在/hbase根目录会产生一个目录:

/hbase/.hbase-snapshot/snapshot_src_table
#子目录下有如下几个文件
/hbase/.hbase-snapshot/snapshot_src_table/.snapshotinfo
/hbase/.hbase-snapshot/snapshot_src_table/data.manifest

B.数据迁移: 在上面创建好快照后,使用ExportSnapshot命令进行数据迁移,ExportSnapshot也是HDFS层的操作,本质还是利用MR进行迁移,这个过程主要涉及IO操作并消耗网络带宽,在迁移时要指定下map数和带宽,不然容易造成机房其它业务问题,如果是单独的MR集群,可以在MR集群上使用如下命令:

hbaseorg.apache.hadoop.hbase.snapshot.ExportSnapshot\
-snapshotsnapshot_src_table\
-copy-fromhdfs://src-hbase-root-dir/hbase\
-copy-tohdfs://dst-hbase-root-dir/hbase\
-mappers20\
-bandwidth20

上面这些流程网上很多资料都有提到,对于我们业务来说,还有一种场景是要同步的表是正在实时写的,虽然用上面的也可以解决,但考虑到我们表数据规模很大,几十个T级别,同时又有实时业务在查的情况下,直接在原表上就算只是拷贝HFile,也会影响原集群机器性能,由于我们机器性能IO/内存方面本身就比较差,很容易导致机器异常,所以我们采用的其它一种方案,流程图如下:

图5.新的snapshot迁移方案

为什么要采用这种方案呢,主要考虑的是直接对原表snapshot进行Export会影响集群性能,所以采用折中的方案,即先把老表clone成一个新表,再对新表进行迁移,这样可以避免直接对原表操作。

四、总结

上文把HBase数据迁移过程中常用的一些方法作了一个大概介绍,总结起来就四点:

DistCp: 文件层的数据同步,也是我们常用的

CopyTable: 这个涉及对原表数据Scan,然后直接Put到目标表,效率较低

Export/Import: 类似CopyTable, Scan出数据放到文件,再把文件传输到目标集群作Import

Snapshot: 比较常用 , 应用灵活,采用快照技术,效率比较高

具体应用时,要结合自身表的特性,考虑数据规模、数据读写方式、实时数据&离线数据等方面,再选择使用哪种。

本文来源:1818IP

本文地址:https://www.1818ip.com/post/9278.html

免责声明:本文由用户上传,如有侵权请联系删除!

发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。