snapshot其實就是一組metadata信息的集合,它可以讓管理員將表恢復到以前的一個狀態。snapshot並不是一份拷貝,它只是一個文件名的列表,並不拷貝數據。一個全的snapshot恢復以為著你可以回滾到原來的表schema和創建snapshot之前的數據。 應用場景: 1獲取:該操作嘗試從 ...
snapshot其實就是一組metadata信息的集合,它可以讓管理員將表恢復到以前的一個狀態。snapshot並不是一份拷貝,它只是一個文件名的列表,並不拷貝數據。一個全的snapshot恢復以為著你可以回滾到原來的表schema和創建snapshot之前的數據。
應用場景:
1獲取:該操作嘗試從指定的表中獲取一個snapshot。該操作在regions作balancing,split或者merge等遷移工作的時候可能會失敗。
2拷貝:該操作用指定snapshot的schema和數據來創建一個新表。該操作會不會對 原表或者該snapshot造成任何影響。
3恢復: 該操作將一個表的schema和data回滾到創建該snapshot時的狀態。
4刪除:該操作將一個snapshot從系統中移除,釋放磁碟空間,不會對其他拷貝或者snapshot造成任何影響。
5導出:該操作拷貝這個snapshot的data和metadata到另一個集群。該操作僅影響HDFS,並不會和hbase的Master或者Region Server通信(這些操作可能會導致集群掛掉)。
首先我們要理解,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
MemStore Flush
寫操作(Put、Delete等)在WAL(Write-Ahead Log)提交成功後,馬上會寫入對應Region Server的記憶體緩衝區(MemStore)中。在MemStore里這些操作是按key排好序的。當MemStore寫滿時,就會將這些數據寫入到HDFS中成為一個HFile。
Compaction
HFile內部的數據是按key排好序的,但HFile之間的數據並不能保證key的順序,也就是說,對於新生成的HFile,其裡面的key值並不都比老的HFile的大。因此每次檢索時,都需要在所有HFile中檢索一次,再將結果合併。雖然HBase針對這個設計了各種加速機制(如Bloom Filter),但HFile文件數目一多還是會比較吃力,因此就需要對HFile做合併操作(Compaction)。Compaction分為minor和major兩種級別,本質上都是從幾個HFile生成合併後的HFile(類似於合併幾個有序數組),然後,老的HFile被刪除,起用合併後的HFile。
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,該表需要先下線
5.HBase Shell: Snapshot 操作
想使用snapshot功能,請確認你的hbase-site.xml中的hbase.snapshot.enabled 配置項為true
<property>
<name>hbase.snapshot.enabled</name>
<value>true</value>
</property>
5.1表上創建snapshot
hbase(main):003:0> snapshot 'abc','spabc'
(abc為表名字,spabc為快照名字)
5.2查看快照
hbase(main):004:0> list_snapshots
5.3恢復快照
hbase(main):012:0> deleteall 'abc','admin'
(刪除rowkey為admin 的整行)
hbase(main):013:0> scan 'abc'
hbase(main):016:0> disable 'abc'
hbase(main):017:0> restore_snapshot 'spabc'
(spabc為快照名字)
hbase(main):018:0> enable 'abc'
hbase(main):019:0> scan 'abc'
刪除的數據又回來了
5.4刪除快照
hbase(main):001:0> delete_snapshot 'spabc'