HDFS 快照是檔案系統的唯讀時間點副本。快照可以建立在檔案系統的子樹或整個檔案系統上。快照的一些常見用途包括資料備份、防止使用者錯誤和災難復原。
HDFS 快照的實作很有效率
快照建立是即時的:成本為 O(1),不包括 inode 查詢時間。
只有當修改相對於快照時才會使用額外記憶體:記憶體使用量為 O(M),其中 M 是已修改檔案/目錄的數量。
資料節點中的區塊不會被複製:快照檔案會記錄區塊清單和檔案大小。不會有資料複製。
快照不會對一般的 HDFS 操作造成負面影響:修改會以反向時間順序記錄,以便可以直接存取目前的資料。快照資料是透過從目前的資料中減去修改來計算的。
只要目錄已設為「可建立快照」,即可對任何目錄建立快照。可建立快照的目錄可以容納 65,536 個同時快照。可建立快照目錄的數量沒有限制。管理員可以設定任何目錄為可建立快照。如果可建立快照目錄中有快照,則在刪除所有快照之前,不能刪除或重新命名目錄。
目前不允許巢狀可建立快照目錄。換句話說,如果目錄的祖先/後代目錄之一為可建立快照目錄,則無法將目錄設定為可建立快照。
對於可建立快照目錄,路徑元件「.snapshot」用於存取其快照。假設 /foo 是可建立快照目錄,/foo/bar 是 /foo 中的檔案/目錄,而 /foo 有快照 s0。然後,路徑 /foo/.snapshot/s0/bar 參考 /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
請注意,此範例使用保留選項來保留時間戳記、擁有權、權限、ACL 和 XAttr。
HDFS 快照功能引進了一個新的保留路徑名稱,用於與快照互動:.snapshot。從不支援快照的舊版 HDFS 升級時,首先需要重新命名或刪除名為 .snapshot 的現有路徑,以避免與保留路徑衝突。請參閱 HDFS 使用者指南 中的升級區段,以取得更多資訊。
本節中描述的操作需要超級使用者權限。
允許建立目錄的快照。如果操作成功完成,目錄將變為可建立快照。
指令
hdfs dfsadmin -allowSnapshot <path>
引數
路徑 | 可建立快照目錄的路徑。 |
請參閱 HdfsAdmin 中對應的 Java API void allowSnapshot(Path path)
。
禁止建立目錄的快照。在禁止快照之前,必須刪除目錄的所有快照。
指令
hdfs dfsadmin -disallowSnapshot <path>
引數
路徑 | 可建立快照目錄的路徑。 |
另請參閱 HdfsAdmin
中對應的 Java API void disallowSnapshot(Path path)
。
本節說明使用者操作。請注意,HDFS 超級使用者可以在不滿足個別操作中權限要求的情況下執行所有操作。
建立可快照目錄的快照。此操作需要可快照目錄的所有者權限。
指令
hdfs dfs -createSnapshot <path> [<snapshotName>]
引數
路徑 | 可建立快照目錄的路徑。 |
snapshotName | 快照名稱,為選用參數。當省略時,會使用格式為 "'s'yyyyMMdd-HHmmss.SSS" 的時間戳記產生預設名稱,例如 "s20130412-151029.033" 。 |
另請參閱 FileSystem 中對應的 Java API Path createSnapshot(Path path)
和 Path createSnapshot(Path path, String snapshotName)
。快照路徑會在這些方法中傳回。
從可快照目錄中刪除快照。此操作需要可快照目錄的所有者權限。
指令
hdfs dfs -deleteSnapshot <path> <snapshotName>
引數
路徑 | 可建立快照目錄的路徑。 |
snapshotName | 快照名稱。 |
另請參閱 FileSystem 中對應的 Java API void deleteSnapshot(Path path, String snapshotName)
。
重新命名快照。此操作需要可快照目錄的所有者權限。
指令
hdfs dfs -renameSnapshot <path> <oldName> <newName>
引數
路徑 | 可建立快照目錄的路徑。 |
oldName | 舊快照名稱。 |
newName | 新快照名稱。 |
另請參閱 FileSystem 中對應的 Java API void renameSnapshot(Path path, String oldName, String newName)
。
取得目前使用者有權限建立快照的所有可快照目錄。
指令
hdfs lsSnapshottableDir
參數:無
另請參閱 DistributedFileSystem
中對應的 Java API SnapshottableDirectoryStatus[] getSnapshottableDirectoryListing()
。
取得兩個快照之間的差異。此操作需要兩個快照中所有檔案/目錄的讀取存取權限。
指令
hdfs snapshotDiff <path> <fromSnapshot> <toSnapshot>
引數
路徑 | 可建立快照目錄的路徑。 |
fromSnapshot | 起始快照的名稱。 |
toSnapshot | 結束快照的名稱。 |
請注意,snapshotDiff 可用於取得兩個快照之間或快照與目錄目前狀態之間的差異報告。使用者可以使用「.」來表示目前狀態。
結果
+ | 檔案/目錄已建立。 |
- | 檔案/目錄已刪除。 |
M | 檔案/目錄已修改。 |
R | 檔案/目錄已重新命名。 |
RENAME 項目表示檔案/目錄已重新命名,但仍位於同一個可快照目錄下。如果檔案/目錄重新命名到可快照目錄外,則會報告為已刪除。從可快照目錄外重新命名的檔案/目錄會報告為新建立的。
快照差異報告無法保證相同的作業順序。例如,如果我們將目錄 “/foo” 重新命名為 “/foo2”,然後附加新資料到檔案 “/foo2/bar”,差異報告會是
R. /foo -> /foo2 M. /foo/bar
也就是說,重新命名目錄下的檔案/目錄變更會使用重新命名之前的原始路徑報告(在上述範例中為 “/foo/bar”)。
另請參閱 DistributedFileSystem
中對應的 Java API SnapshotDiffReport getSnapshotDiffReport(Path path, String fromSnapshot, String toSnapshot)
。