hbase数据备份

作者: _火山_ | 来源:发表于2018-09-07 15:41 被阅读0次

    火山日常啰嗦
    今天就讲讲hbase数据备份相关的问题。

    讲备份,首先就要知道备份的种类,然后再弄清楚每种备份的操作方法。

    数据备份分类:
    hbase数据备份分为离线备份和在线备份两大类。

    离线备份是直接备份hdfs(hadoop分布式文件系统)上的数据,它只能备份到某个具体的时间节点之前的所有数据,因为进行离线备份时,数据库要处于不工作状态,即关闭了数据库,在进行离线备份期间不接受任何读写操作,所以在进行离线备份期间直到重新启用数据库之前,数据库的一致性状态是不会改变的,当离线备份完成后,重新启动了数据库,数据库可对外提供服务了,能够对它进行读写操作了,数据库的状态才会发生改变;
    那如何禁用数据库呢?
    执行shutdown normal,关闭了数据库,那么就可以一次性备份该数据库的所有表;
    但是有时候,需求是并不需要备份所有表,仅需要备份某数据库中的一张或者几张表,这种情况下,我们不必关闭整个数据库,要备份哪些表,我们就禁用(disable tablename)哪些表就行了,禁用了这些表,使得这些表不能对外提供服务了(但其他的表还是可以照常提供服务的),才可以开始离线备份;
    但是由于离线备份对于在线业务的不友好(不友好体现在,备份时需要关闭数据库或者禁用表,不能对外提供读写服务,在线业务对数据库的依赖性强,你关闭了或者禁用了,业务执行所需要的数据就取不到了或者写不进去了),所以在0.94之后的版本就弃用了离线备份方案。

    在线备份就是在进行数据备份的时候不需要关闭数据库,备份时还可以提供对外服务。
    常用在线数据备份包括以下几种:
    copytable、export/import(先导出到目标集群,再导入到目标集群的表中)、replication、snapshot(快照)

    接下来我们详细说说这几种在线备份方案的操作:

    copytable方案
    copytable,顾名思义就是拷贝表或复制表,它可以拷贝表的部分或者全部内容;它可以在同一个集群内进行表的拷贝,也可以在不同集群间进行表的拷贝(比如将某个集群中的表拷贝到另一个集群上)。
    进行copytable操作的前提是:必须要在目标集群上事先创建好拷贝的数据要存储的表,比如要拷贝表test1到表test2上,那么在目标集群上就必须先创建test2表,不然会报错。
    copytable的用法:
    通过bin/ hbase org.apache.hadoop.hbase.mapreduce.CopyTable --help查看用法


    clipboard.png

    bin/hbase org.apache.hadoop.hbase.mapreduce.CopyTable [--starttime=X] [--endtime=Y] [--new.name=newtablename] [--peer.adr=ADR] tablename
    对copytable用法的理解:拷贝tablename这张表上的从starttime开始到endtime结束的这部分数据到目标集群[--peer.adr=ADR]上的目标表[--new.name=newtablename]上;
    从帮助文档中可以看到,copytable不仅支持时间区间的拷贝,还支持rowkey区间的拷贝,还可以更改复制数据存储的目标表的列簇名(也就是说目标表与所要复制的表的列簇名可以不相同,这个在创建时目标表时就可以确定的了,然后在进行真正的拷贝时通过--families指明新的列簇名,当然,如果目标表与复制表的元数据信息一模一样,那就不需要使用--families参数指明啦)
    参数解释:
    --starttime=X :执行时间范围的开始时间
    --endtime=Y :执行时间范围的结束时间
    ps:若--starttime=X和--endtime=Y同时使用,那就是拷贝指定时间范围内的数据;如果仅用了
    --starttime=X,那就是拷贝从starttime开始之后的所有数据;如果仅用了--endtime=Y,就是拷贝从该表的第一条数据开始到endtime的所有数据;
    --startrow和--stoprow用于通过rowkey指定拷贝的区间,它的理解和使用跟--starttime和--endtime一样;
    (注意:这涉及到区间的问题都有开闭之分,这里的区间都是左闭右开的,即拷贝的数据包括开始的,但不包括结束的)
    --new.name :指定目标表的名字
    tablename:所要拷贝的表的名字
    --peer.adr : 目标集群的地址(默认是指本集群,如果是本集群的拷贝,那就不用指定集群地址的,否则报错,如果是跨集群那指定的就应该是另一个集群的地址)
    集群地址的格式:hbase.zookeeer.quorum:hbase.zookeeper.client.port:zookeeper.znode.parent
    即zookeeper的地址:端口号:节点存储目录
    使用例子:volcano01.cc.com,volcano02.cc.com,volcano03.cc.com:2181:hbase

    案例演示:
    同一个集群的某表的部分数据拷贝(本集群的拷贝不用指定集群地址--peer.adr,否则报错,跨集群的拷贝才要指定集群地址):
    按照rowkey确定范围(所拷贝的数据包括开始的那条,不包括结束的那条,即区间是左闭右开的)


    clipboard.png
    clipboard1.png
    clipboard2.png

    按照时间戳确定范围(区间也是左闭右开的)


    clipboard.png
    clipboard1.png
    clipboard2.png
    同一个集群的某表的全部数据拷贝
    clipboard.png
    clipboard1.png
    clipboard2.png

    复制表与目标表的列簇个数及列簇名不同,必需使用--families参数进行指明新表的列簇
    --families参数的使用格式是:--families=oldcfname:newcfname
    如果有多个列簇名不同,则格式应该是:--families=oldcfname1,oldcfname2,...:newcfname1,newcfname2,...


    clipboard.png
    clipboard1.png
    clipboard2.png
    如果复制表与目标表的列簇名相同,不必使用--families参数

    跨集群的拷贝就必须使用--peer.adr参数指定目标集群的地址了,假如有个集群地址为:
    zk1,zk2,zk3:2181:hbase(我用的hbase1.2.5版本的集群地址的格式是这样写的,可能是版本的问题吧,以前的旧版本的格式是zk1,zk2,zk3:2181/hbase,一个是冒号,一个是斜杠)
    那么进行跨集群拷贝的案例就应该使用如下命令:
    hbase org.apache.hadoop.hbase.mapreduce.CopyTable --startrow=20180611 --stoprow=20180621 --new.name=new_t2 --peer.adr=zk1,zk2,zk3:2181:hbase t1

    ps:copytable方案中同一集群de拷贝,集群中不能存在同名的表,所以在同一集群的拷贝中,都需要使用--new.name参数来指定新表的名称,但是不同集群是可以存在同名的表的,当在不同集群进行拷贝,对于同名的表可以不使用--new.name参数,不使用该参数默认表同名,否则不同名,那么就要使用参数--new.name。

    export/import方案
    这个数据备份方案就很浅显易懂啦,我们要进行数据备份嘛,那我们可以先把要进行备份的数据拿出来,放到某个地方,然后再将放在这个地方的数据导入到表中进行持久化;
    而export/import方案将数据导出时是临时存储在hdfs上,然后再通过import导入到hbase表中
    exoprt的使用方法:
    使用hbase org.apache.hadoop.hbase.mapreduce.Export --help查看帮助文档

    clipboard.png
    通过查看帮助文档,可以看到最简单的导出就是:
    bin/hbase org.apache.hadoop.hbase.mapreduce.Export tablename hdfs路径(其他的参数都是可选的,加上[]方括号的都是指可选的)
    即将某张表的数据导出到hdfs上指定路径处;
    通过查看帮助文档,还可以发现,可以使用-D 来指定使用的参数来进行优化,比如使用
    -D mapreduce.output.fileoutputformat.compress=true来指定输出时进行压缩;
    也可以通过-D同时指定多个优化参数,如: -D mapreduce.output.fileoutputformat.compress=true -D mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec
    (即指定输出时进行压缩并指定压缩方式)
    通过查看帮助文档还可以发现,可以指定cell的版本个数(即要备份cell的多少个版本的数据),还可以指定开始时间计结束时间(有了这个时间区间,我们可以做增量备份)

    案例演示:
    将本集群的某张表的数据导出到hdfs的user/root/hbase_test1目录下(在本集群的导出,hdfs路径不能写绝对路径,否则报错,只有跨集群的导出才写绝对路径)
    本集群的导出的hdfs路径不能写绝对路径,不能写成:hdfs:volcano01.cc.com:8020/user/root/hbase_test1
    在本集群的正确的写法是:/user/root/hbase_test1
    同时,请注意:导出目录必须事先不存在在hdfs上,即对于导出而言不能事先创建导出数据的存储目录,当执行导出操作时会自动创建;


    clipboard.png
    clipboard1.png
    clipboard2.png

    import将hdfs上的数据导入表中(ps:在使用import导入数据到表中之前,表必须事先创建,这正与export操作的相反,export操作要求导出目录不能事先存在)
    使用hbase org.apache.hadoop.hbase.mapreduce.Import --help查看帮助文档


    clipboard.png
    通过帮助文档可知,文件导出方式为:
    hbase org.apache.hadoop.hbase.mapreduce.Import tablename hdfs路径
    默认情况下通过这一步import就可以直接将hdfs上的数据导入到hbase表中,它不像importcsv方式先生成Hfile文件,然后再通过-Dimport.bulk.output=hdfs结果输出路径

    案例演示:


    clipboard1.png clipboard2.png clipboard3.png

    snapshot(快照)方案
    要使用snapshot方案,首先要在hbase-site.xml中进行snapshot的配置,在hbase-site.xml中添加如下配置项进行配置snapshot,这个配置是开启snapshot,即开启快照功能:
    <property>
    <name>hbase.snapshot.enabled</name>
    <value>true</value>
    </property>

    snapshot的使用方法:
    ps:snapshot的操作都是在hbase命令行操作的

    为表创建快照
    snapshot '表名','快照名' (要两个参数的,参数之间以逗号隔开)

    clipboard.png
    查看快照列表
    通过命令list_snapshots
    clipboard.png
    将快照恢复到一张新表上(ps:新表不能事先存在,否则报错)
    通过命令clone_snapshot '快照名','新表名'
    clipboard.png
    删除快照
    通过命令delete_snapshot '快照名'
    clipboard.png
    通过快照为该快照的源表进行数据恢复(ps:用快照为源表进行数据恢复之前,首先要禁用源表)
    通过命令:
    禁用表:disable '表名'
    使用快照为源表恢复数据 :restore_snapshot '快照名' (不用带表名参数,使用这个命令默认就是恢复数据到创建这个快照的表的)
    t1表的数据
    clipboard.png
    使用snapshot进行恢复,恢复前先禁用
    clipboard1.png
    恢复后,由于之前禁用了表,所以在操作表之前应该启用表
    clipboard2.png
    查看恢复后的数据,可以看到多了一条rowkey为1的记录
    clipboard3.png
    通过ExportSnapshot将快照导出到其他集群(我尝试了将快照导到本集群,但是每次运行都失败,报错:Java heap space,所以 我认为ExportSnapshot是无法将本集群中的快照 导到本集群中的,因为,这很显然的道理嘛,本集群中已经有这个快照了,你还将这个快照再导一遍到本集群,这不是多此一举吗,所以ExportSnapshot是跨集群导出快照文件的,即将本集群的文件导出到其他集群)
    ps:在linux命令行操作
    通过hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -help查看帮助文档
    clipboard4.png
    从帮助文档中可以看到org.apache.hadoop.hbase.snapshot.ExportSnapshot 有很多参数选项,下面解释一下这些选项的意思:
    -help|-h 查看帮助文档
    -snapshot name 要导出的快照的名字
    -copy-to name 所导到的目标集群地址hdfs://xxx:port/dir(默认是hbase-site.xml文件中配置的hbase.rootdir配置项的值)
    -copy-from name 从哪个集群导出指定的snapshot文件
    -overwrite 覆盖目标集群中的snapshot文件
    -chuser username 修改文件的所有者,将文件所有者修改为指定的这个
    -chgroup group 修改文件所属的组,将文件所属的组修改为指定的这个
    -chmod mode 修改文件的权限,如chmod 700
    -mappers number 指定map task的个数
    -bandwidth 指定传送快照文件时的带宽大小,即限制传送速度

    示例:
    //将本集群的快照文件mysnapshot导出到集群 hdfs://volcano01.cc.com:8020/hbase
    bin/hbase org.apache.hadoop.hbase.snapshot.tool.ExportSnapshot -snapshot mysnapshot -copy-to hdfs://volcano01.cc.com:8020/hbase

    //将某个集群(不是本集群)的快照mysnapshot导到另一个集群上
    bin/hbase org.apache.hadoop.hbase.snapshot.tool.ExportSnapshot -snapshot mysnapshot -copy-from hdfs://volcano02.cc.com:8020/hbase -copy-to hdfs://volcano01.cc.com:8020/hbase

    将快照文件导到目标集群上之后,就可以用clone_snapshot '快照文件名' '新表名'克隆出一张新表
    或者用restore_snapshot '快照文件名' 将数据恢复到新集群的表中。

    相比较于export/import,ExportSnapshot更加的简便快速。
    对于export/import,export要先将数据导到hdfs上,然后再通过import将数据导入到hbase中;
    ExportSnapshot就是直接将hbase表的镜像导出然后就可以通过clone_snapshot或者restore_snapshot进行表的克隆或恢复。

    相关文章

      网友评论

        本文标题:hbase数据备份

        本文链接:https://www.haomeiwen.com/subject/ypxcgftx.html