综述

HDFS快照是一个只读的基于时间点文件系统拷贝。快照可以是整个文件系统的也可以是一部分。常用来作为数据备份,防止用户错误和容灾。

HDFS实现了:

  • Snapshot 创建的时间 复杂度为O(1),但是不包括INode 的寻找时间
  • 只有当修改SnapShot时,才会有额外的内存占用,内存使用量为O(M),M 为修改的文件或者目录数
  • 在datanode 上面的blocks 不会复制,做Snapshot 的文件是纪录了block的列表和文件的大小,但是没有数据的复制
  • Snapshot 并不会影响HDFS 的正常操作:修改会按照时间的反序记录,这样可以直接读取到最新的数据。快照数据是当前数据减去修改的部分计算出来的。

可以被快照的目录

快照会存储在snapshottable的目录下。snapshottable下存储的snapshots 最多为65535个。没有限制snapshottable目录的数量。管理员可以设置任何的目录成为snapshottable。如果snapshottable里面存着快照,那么文件夹不能删除或者改名。

网络的snapshottable目录现在是不允许的。另外如果一个目录的父目录或者子目录是snapshottable,那么这个文件夹不能作为snapshottable。

快照的目录

对于一个snapshottable文件夹,".snapshot" 被用于进入他的快照 /foo 是一个snapshottable目录,/foo/bar是一个/foo下面的文件目录,/foo有一个快照s0,那么路径就是

/foo/.snapshot/s0/bar

引用快照副本/foo/bar。常用的API和CLI能够在".snapshot" 的路径下运行。下面是一些例子。

列出snapshottable目录的所有快照

  • hdfs dfs -ls /foo/.snapshot

列出在快照s0的所有文件

  • hdfs dfs -ls /foo/.snapshot/s0

从s0拷贝一个文件:

  • hdfs dfs -cp /foo/.snapshot/s0/bar /tmp

注意".snapshot"正在被前一个版本的HDFS使用,他必须在升级之前重命名,否则会升级失败。 

操作

管理员操作

本节的操作需要超级用户权限。

快照可用

快照目录建立。如果这个操作成果,那么目录会变成snapshottable。

命令

  • hdfs dfsadmin -allowSnapshot <path>
  • 参数:

path

snapshottable目录路径.

同时请参考在HdfsAdmin中 void allowSnapshot(Path path)的API。

快照不可用

文件夹里面的所有快照在失效快照前必须被删除,如果没有该目录会被建立。

命令:

  • hdfs dfsadmin -disallowSnapshot <path>
  • 参数:

path

snapshottable目录路径.

同时请参考在HdfsAdmin中 void disallowSnapshot(Path path)的API。

用户操作

本小节描述用户操作。注意HDFS超级用户可以执行所有的操作除了有权限的需求的操作。

创建快照

snapshottable目录创建一个快照。这个操作需要snapshottable目录的权限。

命令

  • hdfs dfs -createSnapshot <path> [<snapshotName>]
  • 参数:

path

The path of the snapshottable directory.

snapshotName

"'s'yyyyMMdd-HHmmss.SSS", 例如 "s20130412-151029.033".

可以createSnapshot(Path path)和createSnapshot(Path path, String snapshotName)在文件系统中的API,方法的返回值是snapshot 路径

删除快照

从一个snapshottable目录删除的快照。这个操作需要snapshottable目录的权限。

命令:

  • hdfs dfs -deleteSnapshot <path> <snapshotName>
  • 参数:

path

The path of the snapshottable directory.

snapshotName

快照名字

参考FileSystem类void deleteSnapshot(Path path, String snapshotName)的API

重命名快照

重命名快照。这个命令也需要snapshottable目录的权限。

命令:

  • hdfs dfs -renameSnapshot <path> <oldName> <newName>
  • 参数:

path

The path of the snapshottable directory.

oldName

老的快照名字

newName

新的快照名字

参考FileSystem类 void renameSnapshot(Path path, String oldName, String newName) 的API

snapshottable目录列表

获取当前用户的所有snapshottable。

命令:

  • hdfs lsSnapshottableDir
  • 参数: 无

参考DistributedFileSystem类 SnapshottableDirectoryStatus[] getSnapshottableDirectoryListing() 的API

获取快照差异报告

得到两个快照之间的不同。需要两个目录的权限。

命令:

  • hdfs snapshotDiff <path> <fromSnapshot> <toSnapshot>
  • 参数:

path

The path of the snapshottable directory.

fromSnapshot

开始的快照名字

toSnapshot

结束的快照名字。

参考DistributedFileSystem类 SnapshotDiffReport getSnapshotDiffReport(Path path, String fromSnapshot, String toSnapshot) 的API