文章目录
HDFS 快照是从 Hadoop 2.1.0-beta 版本开始引入的新功能,详见 HDFS-2802。
概述
HDFS 快照(HDFS Snapshots)是文件系统在某个时间点的只读副本。可以在文件系统的子树或整个文件系统上创建快照。快照的常见用途主要包括数据备份,防止用户误操作和容灾恢复。
HDFS 快照的实现非常高效:
- 快照的创建非常迅速:除去 inode 的查找时间,时间复杂度为 O(1);
- 仅在对快照进行修改时,才会消耗一些内存:内存使用 O(M),M 是被修改的文件或目录数;
- Datanode 上的 block 是不会被复制的:快照文件记录 block 的列表和文件大小,并不做数据的拷贝;
- 快照不会对常规的 HDFS 操作产生负面影响:所有的修改都按照时间倒序排序,以便可以直接访问当前数据。快照数据是从当前数据中减去修改的数据来计算的。
可快照的目录(Snapshottable Directories)
一旦我们在目录上设置了可快照的属性,那么我们就可以在这个目录上创建快照。一个可快照的目录可以同时容纳65536个快照,但是可快照的目录个数不存在限制。管理员可以将任何目录设置为可快照。如果可快照的目录存在快照,则在删除所有快照之前,既不能删除也不能重命名这个目录。
嵌套的可快照目录目前还不不支持,换句话说,如果某个目录的父目录或子目录是可快照目录,则无法将该目录设置为可快照的。
快照路径(Snapshot Paths)
对于一个可快照的目录,路径组件(path component)“.snapshot”用于访问其快照。假设 /foo 是一个可快照的目录,foo/bar 是 /foo 下的一个文件或者目录,/foo 有一个快照 s0。那么路径 /foo/.snapshot/s0/bar 就是 /foo/bar 的快照。常用的 API 和 CLI 可以识别“.snapshot”路径,下面是一些示例。
- 列出一个可快照目录下的所有快照:
hdfs dfs -ls /foo/.snapshot
hdfs dfs -ls /foo/.snapshot/s0
hdfs dfs -cp -ptopax /foo/.snapshot/s0/bar /tmp
注意,这个示例使用了保留选项(preserve option)来保留时间戳,所有权,权限,ACL 和 XAttrs。
升级到支持快照的 HDFS 版本注意事项
HDFS 快照特性引入一个新的保留路径 .snapshot,用于和快照交互。从不支持快照的旧版 HDFS 升级时,需要首先重命名或删除名为 .snapshot 的现有路径,以避免与保留路径冲突。有关详细信息,请参阅 HDFS 用户指南关于升级的章节。
快照操作
管理员操作
本节中描述的操作需要超级用户权限。
允许快照(Allow Snapshots)
允许创建一个目录的快照。如果该操作执行成功,那么该目录将变为可快照的。命令如下:
hdfs dfsadmin -allowSnapshot <path>
其中,path 为可快照目录的路径。另请参阅 HdfsAdmin 中相应的 Java API void allowSnapshot(Path path)
。
禁止快照
禁止创建一个目录的快照。在禁止快照前,该目录下已有的快照需要被删除。命令如下:
hdfs dfsadmin -disallowSnapshot <path>
其中,path 为需要被禁止快照目录的路径。另请参阅 HdfsAdmin 中相应的 Java API void disallowSnapshot(Path path)
。
用户操作
本节描述用户操作。注意,HDFS 超级用户可以执行所有操作,而无需满足各个操作中的权限要求。
创建快照
为一个可快照的目录创建快照,该操作需要可快照目录的所有者(owner)权限。命令如下:
hdfs dfs -createSnapshot <path> [<snapshotName>]
其中
- path 为可快照目录的路径。
- snapshotName 快照的名称,是一个可选参数。当用户没有指定快照名称时,系统将使用格式为
's'yyyyMMdd-HHmmss.SSS
的时间戳生成默认名称,例如 s20130412-151029.033。
另请参阅 FileSystem 中相应的 Java API Path createSnapshot(Path path)
和 Path createSnapshot(Path path, String snapshotName)
,这些函数的返回值为快照的路径。
删除快照
从一个可快照的目录删除快照,该操作需要可快照目录的所有者(owner)权限。命令如下:
hdfs dfs -deleteSnapshot <path> <snapshotName>
其中
- path 为可快照目录的路径。
- snapshotName 快照的名称。
另请参阅 FileSystem 中相应的 Java API void deleteSnapshot(Path path, String snapshotName)
。
重命名快照
重命名一个快照,该操作需要可快照目录的所有者(owner)权限。命令如下:
hdfs dfs -renameSnapshot <path> <oldName> <newName>
其中
- path 为可快照目录的路径。
- 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>
其中
- path 为可快照目录的路径。
- 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)
。
本文翻译自 HDFS Snapshots。
本博客文章除特别声明,全部都是原创!原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
本文链接: 【HDFS 快照编程指南】(https://www.iteblog.com/archives/2465.html)