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>方法。