HDFS快照是文件系统的只读的实时的拷贝,可以是文件系统的一部分或者整个文件系统。快照的一些通用场景是数据备份,对用户错误的保护和灾难恢复。HDFS的快照实现是高效的:
- 快照的创建时瞬间完成的,排除查找inode的时间,需要花费O(1),即常数时间。
- 只有执行与快照相关的修改时才需要额外的内存,内存开销为O(M),M为修改的文件或者目录的数量。
- DataNodes中的块不会被复制,快照文件只记录块列表和文件的大小,没有数据的复制。
- 快照对常规HDFS操作没有有害影响,修改按时间逆序记录这样当前数据可以直接被访问(因为当前数据排在最前面,逆序)。快照数据通过从当前数据中减去修改来计算。
只要目录被设置为使用快照,快照就可以作用在目录上,一个启用快照的目录能够同时容纳65536个快照,对于能够启用快照的目录数量不做限制,管理员或许会将每个目录设置为启用快照。如果在启用快照的目录中存在快照,该目录在所有的快照删除之前既不可以被删除也不可以重命名。嵌套启用快照的目录目前是不支持的。换句话说如果一个目录的祖先或者后代是启用快照的目录,那么该目录是不能设置为启用快照的。
对于启用快照的目录,路径中.snapshot用于访问它的快照。假设/foo是快照目录,/foo/bar是/foo中的一个文件或者目录,/foo有一个快照s0,那么路径/foo/.snapshot/s0/bar引用/foo/bar的快照。通常使用的HDFS API和CLI都可以使用.snapshot路径访问快照,例如:
- hdfs dfs -ls /foo/.snapshot 列出快照目录下的所有快照
- hdfs dfs -ls /foo/.snapshot/s0 列出快照s0下的文件
- hdfs dfs -cp -ptopax /foo/.snapshot/s0/bar /tmp 从快照s0拷贝文件bar到/tmp
最后一个例子使用了保持选项-ptopax以保持原有的时间戳(t),拥有者(o),权限(p),访问控制列表(a)和XAttrs(x)。
在学习了HDFS快照的基本概念和特点后,接下来要实际执行一些与快照相关的操作,比如启用快照,禁用快照,创建快照等,下面分别进行学习。要启用快照或者禁用快照必须具备超级用户的权限,启用快照的命令如下,如果该命令执行成功则相应目录启用了快照,其中path为需要启用快照的目录。
- hdfs dfsadmin -allowSnapshot <snapshotDir>
假设将test目录设置为启用快照,执行的命令及输出结果如下,此时仅仅是对test目录启用了快照,并为创建快照文件。
- [hadoop@hadoop ~]$ hdfs dfsadmin -allowSnapshot test/
- Allowing snaphot on test/ succeeded
在禁用某个目录的快照之前,需要删除该目录的所有快照,禁用快照的命令为:
- hdfs dfsadmin -disallowSnapshot <snapshotDir>
- [hadoop@hadoop ~]$ hdfs dfsadmin -disallowSnapshot test
- Disallowing snaphot on test succeeded
下面为创建快照、删除快照等操作,这些操作普通用户可以执行,但必须满足这些操作的权限要求,而超级用户可执行下面的所有命令且不用满足权限要求。首先是创建快照的命令,该操作要求用户必须是启用快照的目录的拥有者,命令及演示效果为:
- hdfs dfs -createSnapshot <snapshotDir> [<snapshotName>]
- [hadoop@hadoop ~]$ hdfs dfs -createSnapshot test
- Created snapshot /user/hadoop/test/.snapshot/s20141023-111821.944
- [hadoop@hadoop ~]$ hdfs dfs -ls test/.snapshot
- drwxr-xr-x - hadoop supergroup 0 2014-10-23 11:18 test/.snapshot/s20141023-111821.944
该命令的第二个参数为快照的名称,若未指定则系统将生成以字符s开头紧跟当前时间戳的名称,如上面的s20141023-111821.944。
可以对快照重命名,该操作要求用户拥有快照目录的所有者权限,该命令如下及执行结果如下所示,需要注意的是命令中的oldName或者newName仅为快照的文件名,而不包含.snapshot部分。
- hdfs dfs -renameSnapshot <snapshotDir> <oldName> <newName>
- [hadoop@hadoop ~]$ hdfs dfs -renameSnapshot test/ s20141023-111821.944 snapshot01
- [hadoop@hadoop ~]$ hdfs dfs -ls test/.snapshot/
- Found 1 items
- drwxr-xr-x - hadoop supergroup 0 2014-10-23 11:18 test/.snapshot/snapshot01
可以使用下面的命令获取当前用户有权限创建快照的所有快照目录,注意获取的是所有已经启用快照的目录。
- [hadoop@hadoop ~]$ hdfs lsSnapshottableDir
- drwxr-xr-x 0 hadoop supergroup 0 2014-10-23 11:18 1 65536 /user/hadoop/test
下面的命令用于删除快照,该命令也要求用户具有快照目录的所有者权限:
- hdfs dfs -deleteSnapshot <snapshotDir> <snapshotName>
- [hadoop@hadoop ~]$ hdfs dfs -deleteSnapshot test/ snapshot01