Hadoop從2.1.0版開始提供了HDFS SnapShot的功能。一個snapshot(快照)是一個全部文件系統、或者某個目錄在某一時刻的鏡像。快照在下面場景下是非常有用:
防止用戶的錯誤操作:管理員可以通過以滾動的方式周期性設置一個只讀的快照,這樣就可以在文件系統上有若干份只讀快照。如果用戶意外地刪除了一個文件,就可以使用包含該文件的最新只讀快照來進行回復。
備份:管理員可以根據需求來備份整個文件系統,一個目錄或者單一一個文件。管理員設置一個只讀快照,並使用這個快照作為整個全量備份的開始點。增量備份可以通過比較兩個快照的差異來產生。
試驗/測試: 一個用戶當想要在數據集上測試一個應用程序。一般情況下,如果不做該數據集的全量拷貝,測試應用程序會覆蓋/損壞原來的生產數據集,這是非常危險的。管理員可以為用戶設置一個生產數據集的快照(Read write)用於用戶測試使用。在快照上的改變不會影響原有數據集。
災難恢復:只讀快照可以被用於創建一個一致的時間點鏡像用於拷貝到遠程站點作災備冗余。
通過下面命令對某一個路徑(根目錄/,某一目錄或者文件)開啟快照功能,那么該目錄就成為了一個snapshottable的目錄。snapshottable下存儲的snapshots 最多為65535個,保存在該目錄的.snapshot下。
1
2
|
hdfs dfsadmin -allowSnapshot /user/spark
Allowing snaphot on /user/spark succeeded
|
下面創建一個snapshot,命令格式為hdfs dfs -createSnapsshot [snapshot names]
1
2
|
hdfs dfs -createSnapshot /user/spark s0
Created snapshot /user/spark/.snapshot/s0
|
該快照會被立即創建出來,創建動作僅僅是在目錄對應的Inode上加個快照的標簽,因為此時快照目錄里不包含任何實際數據。不同的快照間采用硬鏈接的方式,引用相同的數據塊,所以也不會涉及到數據塊的拷貝操作。而對文件的刪除和追加,快照中的塊將會的指向所作的修改的塊,所以也不會對讀寫性能有影響,但是會占用namenode一定的額外內存來存放快照中被修改的文件和目錄的元信息。參考:大數據實踐:通過Snapshot對HDFS文件系統進行備份
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#創建f1,f2,f3三個文件
hdfs dfs -touchz /user/spark/tmp/f{1,2,3}
#新建快照s1
hdfs dfs -createSnapshot /user/spark s1
Created snapshot /user/spark/.snapshot/s1
#此時當前文件系統和s1中都包含f1,f2,f3三個文件
hdfs dfs -ls -R /user/spark
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f1
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f2
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f3
#刪除f3
hdfs dfs -rm /user/spark/tmp/f3
14/12/20 10:46:09 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://hdp01:8020/user/spark/tmp/f3' to trash at: hdfs://hdp01:8020/user/hdfs/.Trash/Current
#查看快照內容,可以發現當前文件系統已經沒有f3,而快照s1還有f3文件存在。這樣,通過拷貝s1下的f3文件就可以進行恢復。
hdfs dfs -ls -R /user/spark/.snapshot
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:28 /user/spark/.snapshot/s0
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s0/tmp
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f1
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f2
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f3
hdfs dfs -ls -R /user/spark/
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:46 /user/spark/tmp
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f1
-rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f2
#RO的快照不能被修改,目前還沒有找到RW的實現方法=。=
hdfs dfs -touchz /user/spark/.snapshot/s1/f4
touchz: Modification on a read-only snapshot is disallowed
|
此外,另外幾個常用的命令:
(1). 修改snapshot名稱: hdfs dfs -renameSnapshot
例如:將s0修改為s_init
1
2
3
4
5
|
hdfs dfs -renameSnapshot /user/spark s0 s_init
hdfs dfs -ls /user/spark/.snapshot
Found 2 items
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1
drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:28 /user/spark/.snapshot/s_init
|
(2). 通過hdfs lsSnapshottableDir 來列出snapshottable的目錄
1
2
|
hdfs lsSnapshottableDir
drwxr-xr-x 0 hdfs supergroup 0 2014-12-20 10:45 2 65536 /user/spark
|
(3). 比較兩個快照之間的差異:hdfs snapshotDiff
1
2
3
4
5
6
|
hdfs snapshotDiff /user/spark s_init s1
Difference between snapshot s_init and snapshot s1 under directory /user/spark:
M ./tmp
+ ./tmp/f1
+ ./tmp/f2
+ ./tmp/f3
|
(4). 刪除快照:hdfs dfs -deleteSnaphost
1
|
hdfs dfs -deleteSnapshot /user/spark s_init
|
(5). 關閉 Snapsshots: hdfs dfsadmin -disallowSnapshot
1
|
hdfs dfsadmin -disallowSnapshot /user/spark
|
通過Snapshot可以按照定時任務,按固定時間間隔(例如每天)的方式創建文件快照,並刪除過期的文件快照,減少業務誤操作造成的數據損失。快照的操作遠低於外部備份開銷,可作為我們備份HDFS系統最常用的方式。