Hadoop从2.1.0版开始提供了HDFS SnapShot的功能。一个snapshot(快照)是一个全部文件系统、或者某个目录在某一时刻的镜像。快照在下面场景下是非常有用:
防止用户的错误操作:管理员可以通过以滚动的方式周期性设置一个只读的快照,这样就可以在文件系统上有若干份只读快照。如果用户意外地删除了一个文件,就可以使用包含该文件的最新只读快照来进行回复。
备份:管理员可以根据需求来备份整个文件系统,一个目录或者单一一个文件。管理员设置一个只读快照,并使用这个快照作为整个全量备份的开始点。增量备份可以通过比较两个快照的差异来产生。
试验/测试: 一个用户当想要在数据集上测试一个应用程序。一般情况下,如果不做该数据集的全量拷贝,测试应用程序会覆盖/损坏原来的生产数据集,这是非常危险的。管理员可以为用户设置一个生产数据集的快照(Read write)用于用户测试使用。在快照上的改变不会影响原有数据集。
灾难恢复:只读快照可以被用于创建一个一致的时间点镜像用于拷贝到远程站点作灾备冗余。
通过下面命令对某一个路径(根目录/,某一目录或者文件)开启快照功能,那么该目录就成为了一个snapshottable的目录。snapshottable下存储的snapshots 最多为65535个,保存在该目录的.snapshot下。
1 2 | hdfs dfsadmin -allowSnapshot /user/spark Allowing snaphot on /user/spark succeeded |
下面创建一个snapshot,命令格式为hdfs dfs -createSnapsshot [snapshot names]
1 2 | hdfs dfs -createSnapshot /user/spark s0 Created snapshot /user/spark/.snapshot/s0 |
该快照会被立即创建出来,创建动作仅仅是在目录对应的Inode上加个快照的标签,因为此时快照目录里不包含任何实际数据。不同的快照间采用硬链接的方式,引用相同的数据块,所以也不会涉及到数据块的拷贝操作。而对文件的删除和追加,快照中的块将会的指向所作的修改的块,所以也不会对读写性能有影响,但是会占用namenode一定的额外内存来存放快照中被修改的文件和目录的元信息。参考:大数据实践:通过Snapshot对HDFS文件系统进行备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #创建f1,f2,f3三个文件 hdfs dfs -touchz /user/spark/tmp/f{1,2,3} #新建快照s1 hdfs dfs -createSnapshot /user/spark s1 Created snapshot /user/spark/.snapshot/s1 #此时当前文件系统和s1中都包含f1,f2,f3三个文件 hdfs dfs -ls -R /user/spark drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f1 -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f2 -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f3 #删除f3 hdfs dfs -rm /user/spark/tmp/f3 14/12/20 10:46:09 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes. Moved: 'hdfs://hdp01:8020/user/spark/tmp/f3' to trash at: hdfs://hdp01:8020/user/hdfs/.Trash/Current #查看快照内容,可以发现当前文件系统已经没有f3,而快照s1还有f3文件存在。这样,通过拷贝s1下的f3文件就可以进行恢复。 hdfs dfs -ls -R /user/spark/.snapshot drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:28 /user/spark/.snapshot/s0 drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s0/tmp drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1 drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f1 -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f2 -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1/tmp/f3 hdfs dfs -ls -R /user/spark/ drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:46 /user/spark/tmp -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f1 -rw-r--r-- 3 hdfs supergroup 0 2014-12-20 10:45 /user/spark/tmp/f2 #RO的快照不能被修改,目前还没有找到RW的实现方法=。= hdfs dfs -touchz /user/spark/.snapshot/s1/f4 touchz: Modification on a read-only snapshot is disallowed |
此外,另外几个常用的命令:
(1). 修改snapshot名称: hdfs dfs -renameSnapshot
例如:将s0修改为s_init
1 2 3 4 5 | hdfs dfs -renameSnapshot /user/spark s0 s_init hdfs dfs -ls /user/spark/.snapshot Found 2 items drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:45 /user/spark/.snapshot/s1 drwxr-xr-x - hdfs supergroup 0 2014-12-20 10:28 /user/spark/.snapshot/s_init |
(2). 通过hdfs lsSnapshottableDir 来列出snapshottable的目录
1 2 | hdfs lsSnapshottableDir drwxr-xr-x 0 hdfs supergroup 0 2014-12-20 10:45 2 65536 /user/spark |
(3). 比较两个快照之间的差异:hdfs snapshotDiff
1 2 3 4 5 6 | hdfs snapshotDiff /user/spark s_init s1 Difference between snapshot s_init and snapshot s1 under directory /user/spark: M ./tmp + ./tmp/f1 + ./tmp/f2 + ./tmp/f3 |
(4). 删除快照:hdfs dfs -deleteSnaphost
1 | hdfs dfs -deleteSnapshot /user/spark s_init |
(5). 关闭 Snapsshots: hdfs dfsadmin -disallowSnapshot
1 | hdfs dfsadmin -disallowSnapshot /user/spark |
通过Snapshot可以按照定时任务,按固定时间间隔(例如每天)的方式创建文件快照,并删除过期的文件快照,减少业务误操作造成的数据损失。快照的操作远低于外部备份开销,可作为我们备份HDFS系统最常用的方式。