hdfs快照是檔案系統在某個時刻的隻讀副本。快照可以是檔案系統的一個子樹,也可以是整個檔案系統。快照的一些通用用途包含資料備份,出錯保護和容災恢複。
hdfs快照的實作是高效的:
快照建立瞬時性:除去inode的查詢時間,算法消耗o(1)複雜度。
隻有在對快照修改時才會消耗額外記憶體:記憶體使用o(m),m是被修改的檔案或者目錄數。
datanode的block不被複制:快照檔案記錄block清單和檔案大小。不做資料的拷貝複制。
快照不會對正常hdfs操作産生不利影響:所有的修改都按照時間倒序排序,是以目前資料總能被直接通路到。快照資料是根據與目前資料進行變更部分的內插補點計算得來的。
如果目錄設定為可以快照的,那麼就可以對該目錄進行快照操作。一個可以快照的目錄可以允許同時存在65536個快照。而對可快照目錄數的限制則不存在。管理者可以設定任意目錄為可快照的。如果一個可快照目錄已經存在快照,那麼該目錄不能被删除,也不能被重命名,除非将其中所有的快照都先删除。
嵌套的可快照目錄目前還不允許。換句話說,如果一個祖先目錄或者子孫目錄已經是可快照的目錄,那麼該目錄不可以再設定為可快照的目錄。
對于一個可快照的目錄,路徑元件“.snapshot”用來通路其快照。假設/foo是一個可快照的目錄,/foo/bar是/foo下的一個檔案或者目錄,/foo有一個快照s0.那麼路徑
對應到/foo/bar的快照拷貝。通用api和cli可以在“.snapshot”路徑下生效。以下是一些例子。
列出一個可快照目錄下的所有快照:
hdfs dfs -ls /foo/.snapshot
列出快照s0的所有檔案:
hdfs dfs -ls /foo/.snapshot/s0
從快照s0拷貝一個檔案:
hdfs dfs -cp -ptopax /foo/.snapshot/s0/bar /tmp
注意一下這個例子使用了保留選項來保留timestamps,ownership,permission,acl和xattrs。
下面的操作需要超級使用者權限。
允許建立一個目錄的快照。如果該操作成功,那麼目錄變為可快照的。
指令:
hdfs dfsadmin -allowsnapshot
參數:
可以參考對應的java api,<code>hdfsadmin</code>類下面的<code>void allowsnapshot(path path)</code>方法。
禁止建立一個目錄的奎照。在禁止快照前,該目錄下已有的快照需要被删除。
hdfs dfsadmin -disallowsnapshot
可以參考對應的java api,<code>hdfsadmin</code>類下面的<code>void disallowsnapshot(path path)</code>方法。
這一部分描述使用者操作。注意hdfs超級使用者可以進行任何操作。
為一個可快照的目錄建立一個快照。該操作需要可快照目錄的owner權限。
hdfs dfs -createsnapshot []
可以參考對應的java api,<code>filesystem</code>類下面的<code>path createsnapshot(path path)</code>方法和<code>path createsnapshot(path path, string snapshotname)</code>方法。這些方法會傳回快照的路徑。
從一個可快照的目錄删除一個快照。該操作需要可快照目錄的owner權限。
hdfs dfs -deletesnapshot
可以參考對應的java api,<code>filesystem</code>類下面的<code>void deletesnapshot(path path, string snapshotname)</code>方法。
重命名一個快照。該操作需要可快照目錄的owner權限。
hdfs dfs -renamesnapshot
可以參考對應的java api,<code>filesystem</code>類下面的<code>void renamesnapshot(path path, string oldname, string newname)</code>方法。
擷取目前使用者有權限建立快照的所有可快照目錄的清單。
hdfs lssnapshottabledir
參數:無
可以參考對應的java api,<code>distributedfilesystem</code>類下面的<code>snapshottabledirectorystatus[] getsnapshottabledirectorylisting()</code>方法。
擷取兩個快照之間的差異。這個操作需要兩個快照所有檔案和目錄的讀通路權限。
hdfs snapshotdiff
結果:
一個rename的項表明一個檔案或目錄被重命名過,但是仍在同一個可快照目錄下。一個檔案或目錄如果被重命名到可快照目錄外面,那麼被認為删除。一個檔案或目錄如果從可快照目錄外重命名到可快照目錄内,那麼會被認為是建立。
快照差别報告不保證操作順序。舉例來說,如果我們重命名一個目錄“/foo”為“/foo2”,然後添加一個新檔案為“/foo2/bar”,那麼差别報告會是:
這種順序不保證展現在,在重命名目錄下的檔案或目錄變動會被認為是在目錄重命名前完成的(比如上面的例子)。可以參考對應的java api,<code>distributedfilesystem</code>類下面的<code>snapshotdiffreport getsnapshotdiffreport(path path, string fromsnapshot, string tosnapshot)</code>方法。