Snapshot即是快照,代表某个时刻数据库中表的状态,就像是照片一样,记录了该时刻所有的数据。
HBase可以对某个时刻的表建立snapshot,过后可以恢复到该snapshot的状态,也可以用snapshot建立一个新的表等等。
本文重点在于解释,为什么HBase Snapshot的建立与恢复操作不涉及数据的大量复制,且能在常数时间内完成。
建立snapshot、查看snapshot:
hbase> snapshot 'tableName', 'snapshotName' hbase> list_snapshots SNAPSHOT TABLE + CREATION TIME snapshotName tableName (Sun Mar 13 13:54:32 +0800 2016)
将snapshot复制到一个新表:
hbase> clone_snapshot 'snapshotName', 'newTableName'
删除snapshot
hbase> delete_snapshot 'snapshotName'
用snapshot恢复表:
hbase> restore_snapshot 'snapshotName'
与其它集群的导出或导入:
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \ -snapshot MySnapshot -copy-to hdfs://srv2:8082/hbase \ -chuser MyUser -chgroup MyGroup -chmod 700 -mappers 16 hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \ -snapshot MySnapshot -copy-from hdfs://srv2:8082/hbase \ -copy-to hdfs://srv1:50070/hbase \
利用Snapshot只需要常数时间的特性,还可以用来改表名:
hbase> disable 'tableName' hbase> snapshot 'tableName', 'tableSnapshot' hbase> clone_snapshot 'tableSnapshot', 'newTableName' hbase> delete_snapshot 'tableSnapshot' hbase> drop 'tableName'
直接摘抄自https://blog.cloudera.com/blog/2013/03/introduction-to-apache-hbase-snapshots/,感觉写得很好(主要是我懒得翻译了:P)
Snapshot之所以能在常数时间内完成,是因为它只是一组元数据(MetaData)的集合。Snapshot的操作都不需要复制任何业务数据。
首先我们要理解,HBase的底层存储文件HFile是什么,以及是怎么被生成的、怎么被删除的(或者叫生命周期)。其次就不难理解Snapshot为什么不需要复制业务数据了。
1. HFile是什么
HBase是一个Key-Value数据库,其基本数据操作(如Put、Delete等)最后都化归为Key-Value对,存储在HDFS的一个个文件(HFile)中:
注意上图绿色的Key字段中,最后有个1 Byte的Key Type域,即是用来区分Put和Delete的。
另外更需注意的一点是,HBase的Delete操作并不是立即定位到目标数据将其删除或者做个删除标记,因为HDFS不支持这种随机写。Delete操作也跟Put一样存储,只是Key Type域不一样,以及Value域为空而已。HBase在读取时,会将拥有Delete操作的数据过滤掉。而具体何时删除目标数据,则是在对HFile做Compaction时。
2. HFile的两种生成方式
HFile有两种生成方式,分别是MemStore Flush和Compaction
3. HFile何时会被删除
上面提到过的,在完成Compaction后,老的HFile就会被删除,起用合并后的HFile。
4. Snapshot操作的实现
细心的你是否发现了一个事实,HFile是不会被追加或者修改的!HFile一旦生成,就不会再被改变,只有被拿去合并后,生成了新的HFile,完成自己的使命时才会被删除。
那如果不删除呢?
比如说,我今天建了个表开始跑业务,这个表总共生成了10个HFile,每二天又生成一些HFile,并因此触发了合并操作,现在启用的HFile里有一些是老的没被合并的,有一些是新的由合并产生的。如果昨天那10个HFile还在,那我只要让这个表启用原来的这10个HFile,不就回滚到昨天的状态了嘛。依靠的是什么?就是这10个HFile自从诞生之后就不会被改动,连追加都不会。他们像琥珀一样,记录了这个表昨天的所有数据。
因此,建立Snapshot其实就是把当前所有启用的HFile文件名记录下来,并提醒系统在Compaction时不要删除它们。恢复Snapshot就是重新启用当时的那些HFile。当然这两句话说得不严谨,还有一些细节要处理,比如建Snapshot时要把内存里的东西也存下来先。具体是这样的:
建立Snapshot
1,Master与RegionServer同步,让他们同时进行MemStore flush
2,记录MetaData,即当前表有哪些region,每个region使用的HFile是哪些
3,“标记”HFile以防被删除
*建立Snapshot的过程不需要让表下线。
恢复Snapshot
根据Snapshot对应的MetaData恢复各个region,该表需要先下线
本文解析了为什么HBase的Snapshot操作只需要常数时间,不需要复制业务数据。其实说白了就一点,因为HFile生成之后只会被删除,不会被修改,连追加的修改都不会!