问题导读
1.快照的作用是什么?
2.HDFS Snapshot的原理是什么?
【简介】
HDFS中可以对目录创建Snapshot,创建之后不管后续目录发生什么变化,都可以通过snapshot找回原来的文件和目录结构。
为了启用这种功能,首先需要启用目标目录的snapshot功能,可以通过下面的命令来执行:
hdfs dfsadmin -allowSnapshot 启用snapshot功能后,并不会自动进行snapshot保存,还需要先创建snapshot, 通过下面的命令来执行:
hdfs dfs -createSnapshot []
可以为相同的目录创建多个snapshot, 不同的snapshot通过名字来区分,默认是syyyyMMdd-HHmmss.SSS,例如/storage/WALs/.snapshot/s20140515-084657.639
【实现原理】
实现上是通过在每个目标节点下面创建snapshot节点,后续任何子节点的变化都会同步记录到snapshot上。例如删除子节点下面的文件,并不是直接文件元信息以及数据删除,而是将他们移动到snapshot下面。这样后续还能够恢复回来。另外snapshot保存是一个完全的现场,不仅是删除的文件还能找到,新创建的文件也无法看到。后一种效果的实现是通过在snapshot中记录哪些文件是新创建的,查看列表的时候将这些文件排除在外。
在HDFS中INode表示一个节点,其中INodeFile表示文件,INodeDirectory表示目录。INodeFileWithSnapshot表示带有快照的文件,INodeDirectoryWithSnapshot表示带有快照的目录, (INodeDirectorySnapshottable表示可以创建快照的目录,INodeDirectoryWithSnapshot不能创建新的快照,只能将目录的变化记录到现有的快照里面)相关的类结构如下:
图中红线表示的是关键类的引用关系,其中最重要的是DirectoryDiffList,里面保存了一些快照和当前目录的差别。每一个DirectoryDiff中包含快照以及儿子变化,是实现快照功能的核心。ChilderenDiff中created list保存的是从快照时间之后新创建的节点,deteled list保存的新删除的节点。snapshot中的root节点保存了snapshot的name,可以通过这个找到对应的快照。
【例子分析】
我们通过一个例子来分析整个snapshot的实现细节:
1. 文件目录树如下图所示,并且我们已经通过命令启动了a的snapshot功能,结构如下图所示:
图中.snapshot是虚拟节点,保存了所有的snapshot列表,其中diff中还保存当前节点下面的变化,一个snapshot对应于一个diff.要注意的是snapshot中可以被多个目录的diff引用,后续会进行说明。
2. 当我们执行createSnapshot命令时,结果如下:
3. 当删除文件e的时候
不论是删除一个文件还是一个目录,只要是直接子节点,都会将节点转换为快照版本.例如e会变成INodeFileWithSnapshot,在a的DirectoryDiff中ChildDiff中deleted列表中将会包含e,而在a的正常节点下会被删除。目录节点的处理同样。
4. 删除孙子节点是的情况
处理这种节点的原则是:先将孙子节点转变为Snapshot版本,然后将父节点变为snapshot版本,同时将孙子节点版本加入到直接父节点的diff列表中。为了能够通过同一个snapshot找到当时的文件,需要将新的diff指向到老的snapshot版本上。图中d节点是INodeDirectoryWithSnapshot(不是INodeDiretorySnapshottable, 本身不允许在d上创建snapshot)
|