1.简介

  Snapshots即快照的意思,作用于表上。在对于表做快照的时候不会造成文件的拷贝,如不会对HFile文件进行拷贝而是以链接的方式链接到元表的HFile上。可以说它是一种元数据的集合,可以快速的恢复到表至快照指定的状态从而迅速的数据修复(会丢失快照之后的数据)如用户误删除表等操作中恢复。也可以将数据拷贝到不同的集群进行数据的备份。

  

hbase oss 介质 hbase snapshot 原理_数据

 

hbase oss 介质 hbase snapshot 原理_hadoop_02


2.准备

  在测试环境上准备源表:

  

hbase oss 介质 hbase snapshot 原理_hbase oss 介质_03

hbase(main):005:0> scan 'mytable'
ROW                   COLUMN+CELL                                               
 row1                 column=f1:a, timestamp=1470208281649, value=1             
 row2                 column=f1:a, timestamp=1470208287371, value=2             
 row3                 column=f1:a, timestamp=1470208295512, value=3             
 row4                 column=f1:a, timestamp=1470208301149, value=4             
 row5                 column=f1:a, timestamp=1470208305778, value=5             
 row6                 column=f1:a, timestamp=1470209308099, value=6             
6 row(s) in 0.1100 seconds

 

3.操作:

a.创建快照:

hbase(main):006:0> snapshot 'mytable','mysnapshot'
0 row(s) in 0.3840 seconds

 

   创建完毕后再web页面我们可以看到快照的信息,显示了多少hfile包含于这个快照,这些hfile是否被归档(当发生分裂,compaction或者drop表操作的时候有可能会在源表hdfs目录中删除这

   些引用的hfile,但是为了维护快照的信息这些被删除的hfile会被归档到指定目录,这里看到100%shared with the source table 代表这些hfile还没有没删除。)

 

hbase oss 介质 hbase snapshot 原理_hbase oss 介质_04

  其会在如下hdfs路径下创建快照的引用信息:

  

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/.hbase-snapshot/mysnapshot
Found 2 items
-rw-r--r--   1 hadoop supergroup         32 2016-08-03 03:43 /hbase/.hbase-snapshot/mysnapshot/.snapshotinfo// 这里记录了当前快照的元信息
-rw-r--r--   1 hadoop supergroup        464 2016-08-03 03:43 /hbase/.hbase-snapshot/mysnapshot/data.manifest// 这里记录了源表的元信息,region分裂信息,以及引用目标hfile信息
注意:现在大部分网络上的分享信息都是说创建一个空文件来链接到源表的hfile文件上,在https://issues.apache.org/jira/browse/HBASE-7987中优化这样的处理,避免了大量的空的链接文件对于hdfs的冲击。

 

   这里我们展示一下具体的data.manifest文件信息

16/08/03 04:21:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

?

defaultmytable
IS_METAfalse?
f1

ATA_BLOCK_ENCODINGNONE

BLOOMFILTERROW
REPLICATION_SCOPE0

COMPRESSIONNONE
VERSIONS1
TTL
2147483647

MIN_VERSIONS0
EEP_DELETED_CELLSFALSE
    BLOCKSIZE65536
    IN_MEMORYfalse

BLOCKCACHEtrueX?????*// 这一部分保存了源表的元信息
defaultmytablerow3"(08+
f1%
 420c04ce57eb4634bf2efefb56aa0b15X?????*
defaultmytable"row3(08+
f1%
 29a0b0870ce740dba0be8ba24c3fa34e// 这一部分保存了region的切分信息和当前快照所以来的源表的hfile信息【通常建立快照的时候都需要flush表】

  

  b.restore 快照:

  如下我们将mytable这个源表删除:  

 

hbase(main):002:0> put 'mytable','row7','f1:a',7 // 插入一条数据以此来检测当restore后数据是否恢复的原来的状态
0 row(s) in 0.0940 seconds

hbase(main):003:0> flush 'mytable'
0 row(s) in 0.5350 seconds

hbase(main):004:0> disable 'mytable'
0 row(s) in 2.4120 seconds

hbase(main):005:0> drop 'mytable'
0 row(s) in 1.2890 seconds

  

  此时源表被删除,源表的hdfs文件夹也被删除了:

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/data/default/mytable
16/08/03 04:51:03 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
ls: `/hbase/data/default/mytable': No such file or directory

  这个时候快照manifest中引用的源表hfile会被归档到,只要原来的文件有被删除的情况,那么快照所引用的hfile文件都会归档到archive的对应表目录中。

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/archive/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1
16/08/03 04:57:21 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 1 items
-rw-r--r--   1 hadoop supergroup       1107 2016-08-03 04:50 /hbase/archive/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1/420c04ce57eb4634bf2efefb56aa0b15
[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/archive/data/default/mytable/d2d35f61fae1de22492b0c6d9d305cfe/f1
16/08/03 04:57:36 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 1 items
-rw-r--r--   1 hadoop supergroup       1045 2016-08-03 04:50 /hbase/archive/data/default/mytable/d2d35f61fae1de22492b0c6d9d305cfe/f1/29a0b0870ce740dba0be8ba24c3fa34e
[hadoop@xufeng-3 ~]$

 

  执行restore,我们可以看到表数据被恢复,且数据

hbase(main):005:0> drop 'mytable'
0 row(s) in 1.2890 seconds

hbase(main):006:0> restore_snapshot 'mysnapshot'
0 row(s) in 0.8470 seconds

hbase(main):007:0> list
TABLE                                                                                                                                                                                
mytable                                                                                                                                                                              
1 row(s) in 0.0190 seconds

=> ["mytable"]
hbase(main):008:0> scan 'mytable'
ROW                                            COLUMN+CELL                                                                                                                           
 row1                                          column=f1:a, timestamp=1470208281649, value=1                                                                                         
 row2                                          column=f1:a, timestamp=1470208287371, value=2                                                                                         
 row3                                          column=f1:a, timestamp=1470208295512, value=3                                                                                         
 row4                                          column=f1:a, timestamp=1470208301149, value=4                                                                                         
 row5                                          column=f1:a, timestamp=1470208305778, value=5                                                                                         
 row6                                          column=f1:a, timestamp=1470209308099, value=6                                                                                         
6 row(s) in 0.0430 seconds

hbase(main):009:0>

 

  我们接着在被恢复表的hdfs目录结构,可以看到这两个hfile的size为0,说明他是对achive中归档hfile的引用。

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1
Found 1 items
-rw-r--r--   1 hadoop supergroup          0 2016-08-03 05:14 /hbase/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1/mytable=49b61de11f43344b8bebfed0db0605b4-420c04ce57eb4634bf2efefb56aa0b15
[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/data/default/mytable/d2d35f61fae1de22492b0c6d9d305cfe/f1
Found 1 items
-rw-r--r--   1 hadoop supergroup          0 2016-08-03 05:14 /hbase/data/default/mytable/d2d35f61fae1de22492b0c6d9d305cfe/f1/mytable=d2d35f61fae1de22492b0c6d9d305cfe-29a0b0870ce740dba0be8ba24c3fa34e

 

  当我们再次插入数据并flush的时,可以看到新被flush的hfile是实际的hfile,大小不为0,在achive中归档的hfile文件直到所对应的快照被删除且当没有没有表引用它才会被定期删除。

hbase(main):009:0> put 'mytable','row7','f1:a',7
0 row(s) in 0.0180 seconds

hbase(main):010:0> 
Display all 487 possibilities? (y or n) 
hbase(main):010:0> flush 'mytable'
0 row(s) in 0.3520 seconds
-rw-r--r--   1 hadoop supergroup       1014 2016-08-03 05:23 /hbase/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1/7b6d4c0556c84224a8f8f1da10b5fee4
-rw-r--r--   1 hadoop supergroup          0 2016-08-03 05:14 /hbase/data/default/mytable/49b61de11f43344b8bebfed0db0605b4/f1/mytable=49b61de11f43344b8bebfed0db0605b4-420c04ce57eb4634bf2efefb56aa0b15

 

  c.从快照中克隆一张表

hbase(main):012:0> clone_snapshot 'mysnapshot','myclonetable'
0 row(s) in 2.5610 seconds

hbase(main):013:0> scan 'myclonetable'
ROW                                            COLUMN+CELL                                                                                                                           
 row1                                          column=f1:a, timestamp=1470208281649, value=1                                                                                         
 row2                                          column=f1:a, timestamp=1470208287371, value=2                                                                                         
 row3                                          column=f1:a, timestamp=1470208295512, value=3                                                                                         
 row4                                          column=f1:a, timestamp=1470208301149, value=4                                                                                         
 row5                                          column=f1:a, timestamp=1470208305778, value=5                                                                                         
 row6                                          column=f1:a, timestamp=1470209308099, value=6                                                                                         
6 row(s) in 0.2060 seconds

  再来看一下其表hdfs目录:可以看到其hfile也是对于快照归档文件的引用,大小为0,同时其具有不同的表名,不同的region名称。

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/data/default/myclonetable/660358521754384ce0d5e2e1a00b7f3e/f1
Found 1 items
-rw-r--r--   1 hadoop supergroup          0 2016-08-03 05:27 /hbase/data/default/myclonetable/660358521754384ce0d5e2e1a00b7f3e/f1/mytable=d2d35f61fae1de22492b0c6d9d305cfe-29a0b0870ce740dba0be8ba24c3fa34e
[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/data/default/myclonetable/93f80e96f83e193caf35752a84cf6492/f1
Found 1 items
-rw-r--r--   1 hadoop supergroup          0 2016-08-03 05:27 /hbase/data/default/myclonetable/93f80e96f83e193caf35752a84cf6492/f1/mytable=49b61de11f43344b8bebfed0db0605b4-420c04ce57eb4634bf2efefb56aa0b15
注意:clone与restore快照的区别通过上述实践可知:restore恢复快照对应的源表的状态,其表名,region都一致。而clone是执行表名重新创建了新表,除了表名连region名称也不同,完全是一张新表。
他们共同点是都引用了archive中快照归档的hflie文件。

   

d.删除快照

hbase(main):015:0> delete_snapshot 'mysnapshot'
0 row(s) in 0.1580 seconds

 

 删除只有快照目录被删除但是archive目录由于被其他表引用着并不会被删除:

[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/.hbase-snapshot/mysnapshot
ls: `/hbase/.hbase-snapshot/mysnapshot': No such file or directory
[hadoop@xufeng-3 ~]$ hadoop fs -ls /hbase/archive/data/default/mytable
Found 2 items
drwxr-xr-x   - hadoop supergroup          0 2016-08-03 04:55 /hbase/archive/data/default/mytable/49b61de11f43344b8bebfed0db0605b4
drwxr-xr-x   - hadoop supergroup          0 2016-08-03 04:55 /hbase/archive/data/default/mytable/d2d35f61fae1de22492b0c6d9d305cfe
[hadoop@xufeng-3 ~]$

 

4.原理简述

  综上对于快照的实践我们可以大概总结一下快照的一般原理。

  a.创建快照:

    如前所述,在快照的data.manifest文件中写明了快照指向那些hflie

  

hbase oss 介质 hbase snapshot 原理_hive_05

  b. 源表hfile文件变动(发生split、compact等),元hfile文件会被拷贝到archive归档目录中去

    

hbase oss 介质 hbase snapshot 原理_hbase oss 介质_06

  c.restore

    当对某个表进行restore时,此表在快照时间点之后创建的HFile会被删除并被归档(有可能HF5之上也有快照引用),然后会通过一个空文件link到之前被归档的HF4文件上从而恢复了表数据。

   

hbase oss 介质 hbase snapshot 原理_hbase oss 介质_07

  d.clone

    克隆的表是一个独立的新表有自己的hdfs路径,初始化的时候内部也都是空文件指向了源表的hfile或者被归档的hfile。

    

hbase oss 介质 hbase snapshot 原理_hadoop_08

5.应用场景及缺陷:

  略。