Apache Hadoop 2.9.0
请查看原文:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsSnapshots.html
概述:
HDFS快照是HDFS文件系统某个时间点的只读副本。快照可以是整个文件系统的快照,也可以是一个文件系统的子目录(subtree)。数据备份、保护数据以防止用户错误以及灾难恢复等都需要用到快照。
HDFS快照实现是非常高效的:
l 快照是可以即时创建的:除去索引节点的查找时间代价是O(1).
l 只有在修改也被应用到快照上的时候才需要额外的存储:存储代价是O(M),M是指修改的文件或者目录数目。
l 数据节点上的文本块是不会被拷贝的:快照文件只是记录文本块列表以及文件大小,并不真正拷贝数据。
l 快照并不影响常规的HDFS操作:修改可以按照修改相反的顺序记录下来,这样当前的数据可以直接被访问。当前的数据加上相应的修改才能得到快照数据。
Snapshottable(可快照) 目录
可以为任意设置为snapshottable的目录创建快照。一个snapshottable目录可以同时存放65,536份快照,并且快照目录的数目没有限制。管理员可以指定任意目录为snapshottable,但是只要在一个snapshottable目录下有快照,这个目录就不能被删除或者重名字,只有当所有快照都被删除时才能删除这个snapshottable目录或者重命名这个目录。
快照路径
针对一个snapshottable目录,“.snapshot”路径用来指定存放的快照。例如:/foo是一个snapshottable目录,/foo/bar是一个 /foo下的一个文件/目录,并且/foo有一个快照s0,那么路径/foo/.snapshort/s0/bar 指向/foo/bar的快照。常用的API以及CLI可以查看“.snapshot”,下面是一些列子。
列出snapshottable目录下的所有快照 :
hdfs dfs -ls foo/.snapshot
列出快照S0下的所有文件:
hdfs dfs -ls foo/.snapshot/s0
从快照S0中拷贝一个文件:
hdfs dfs -cp -ptopax /foo/.snapshot/s0/bar /tmp
备注: 这些例子使用保护的操作保护时间戳、所有权、许可证、ACLs和XAttrs。
升级到一个包含快照特征的HDFS版本
HDFS快照特征使用.snapshot这个保留的目录名来保存快照,当一个旧的不支持快照的HDFS版本需要升级时,首先就要重命名或者删除当前目录中名字为.snapshot的目录来防止和保留名冲突。可以查看hadoop 用户指导中升级的部分来获得更多的信息。
快照操作
管理员操作
这部分讲述的操作需要超级用户的权限。
允许快照
指定一个目录可以创建快照,当这一操作成功,这个目录将会变成可以创建快照的目录。
命令:
hdfs dfsadmin -allowSnapshot
参数:
可以在HdfsAdmin中查看对应的JAVA API void allowSnapshot(Path path)
禁止快照
禁止一个目录创建快照,在禁止之前,当前目录下所有的快照必须已经被删除。
命令:
hdfs dfsadmin -disallowSnapshot
参数:
可以在HdfsAdmin中查看对应的JAVA API void disallowSnapshot(Path path)
用户操作:
这部分描述用户操作,需要特别注意的是超级用户可以执行所有的操作,而不需要个体操作的权限。
创建快照:
创建一个快照,这个操作需要snapshottable 目录的owner权限
命令:
hdfs dfs -createSnapshot []
参数:
path | snapshottable 目录. |
snapshotName | 快照名字,, 这是一个可选项,当省略时,就会用时间戳 "'s'yyyyMMdd-HHmmss.SSS"格式来默认,例如:"s20130412-151029.033" |
可以查看对应的JAVA API 接口 Path createSnapshot(Path path)和Path createSnapshot(Path path, String snapshotName)
删除快照
从snapshottable 目录中删除一个快照,这个操作需要snapshottable 目录的owner权限。
命令:
hdfs dfs -deleteSnapshot
参数:
path | snapshottable 目录路径 |
snapshotName | 快照名 |
在FileSystem中查看对应的JAVA API void deleteSnapshot(Path path, String snapshotName)
重命名快照
重命名快照,这个操作需要snmapshottable目录的owner权限
命令:
hdfs dfs -renameSnapshot
参数:
path | snapshottable 目录路径. |
oldName | 旧快照名字 |
newName | 新快照名字 |
在FileSystem中查看对应的JAVA APIvoid renameSnapshot(Path path, String oldName, String newName)
查看Snapshottable目录列表
查看所有snampshottable目录列表,需要当前用户有快照的权限。
命令:
hdfs lsSnapshottableDir
参数: 无
在FileSystem中查看对应的JAVA APISnapshottableDirectoryStatus[] getSnapshottableDirectoryListing() inDistributedFileSystem.
查看快照之间的差异报告
得到2份快照的差异,这个操作需要2份快照的目录文件的read access权限。
命令:
hdfs snapshotDiff
参数:
path | snapshottable 目录路径. |
fromSnapshot | 开始的快照名字. |
toSnapshot | 结束的快照名字. |
snapshotDiff 就是2份快照的差异,也可以是一份快照和当前状态的差异,用户可以少用“.”来代表当前状态。
结果:
+ | The file/directory 被创建了. |
- | The file/directory 被删除了. |
M | The file/directory 被修改了. |
R | The file/directory 被重名了. |
重命名代表的是 在相同sampshottable目录下的文件/目录被重命名了。如果文件/目录重命名是发生在snapsottable目录之外,那么报告中会显示的一个文件/目录 被删除了。一个文件/目录从snapsshottable目录之外被重命名,那么在报告中会显示是新创建的。
快照差异报告不敢担保和操作的顺序相同,例如,如果我们重命名目录”/foo”为’/foo2”,并且在”/foo2/bar”后面追加数据,那么差异报告将会是如下情况。
R. /foo -> /foo2
M. /foo/bar
可以看到,对一个重命名过的目录上文件/目录的修改使用的是重命名之前的名字(例如上述例子中的/foo/bar)
在DistributedFileSystem查看相应的JAVA APISnapshotDiffReport getSnapshotDiffReport(Path path, String fromSnapshot, String toSnapshot)