我们知道hdfs是hadoop体系上的文件系统,负责具体的数据文件存储,且如果一旦hdfs文件被误删除后,尤其是重要数据,对公司来说影响非常大。所以需要提前做一些安全预防措施,例如使用Hdfs Trash机制,或者重要目录应用Hdfs SnapShot功能,然后针对于删除的文件或者目录可以通过trash或者SnapShot机制来进行恢复,如果数据确实已经删除了(例如直接通过hadoop api进行delete,未配置SnapShot),如果想恢复数据,就需要快速采取一定的措施了。下面我们来分别介绍下这些恢复数据的使用方式与机制。
Hdfs Trash(回收箱)
对于线上生产环境的HDFS,开启回收站功能是必不可少的。该功能类似于linux系统的回收站设计,HDFS会为每个用户创建一个专属的回收站目录(/user/${user.name}/.Trash),用户删除文件时,实际上是被移动到了回收站目录。用于预防当用户误删HDFS上的数据时,能够及时从回收站恢复这些数据(当然回收站是防不住删库跑路的)。
使用这种方式的前提是在hdfs上面开启trash功能,默认是没有开启的。interval的值默认为0,单位是分钟。只需要在hadoop的配置文件core-site.xml中添加下面的内容:
添加好上述内容后,不需要重启后台程序,直接就会生效。执行删除操作后,会先将文件移动到当前操作用户的.Trash/Current目录下面。
Hdfs SnapShot(快照)
hadoop从2.1版本后开始支持HDFS快照(SnapShot)功能,
快照创建瞬时性:除去inode的查询时间,算法消耗O(1)复杂度。
只有在对快照修改时才会消耗额外内存:内存使用O(M),M是被修改的文件或者目录数。
DataNode的block不被复制:快照文件记录block列表和文件大小。不做数据的拷贝复制。
快照不会对正常HDFS操作产生不利影响:所有的修改都按照时间倒序排序,因此当前数据总能被直接访问到。快照数据是根据与当前数据进行变更部分的差值计算得来的。
使用实例:
使用方式:
创建快照:
hdfs fs -allowSnapshot /test
hdfs fs -put test.txt /test
hdfs fs -createSnapshot /test import_data
将test文件删除:
hdfs fs -rmr /test/test.txt
误删除后就可以使用快照目录进行恢复:
hdfs fs -cp /test/.snapshot/import-data/test.txt /text
恢复数据
然而如果直接调用hadoop delete api进行删除操作,是默认不会走trash机制的,同时也未配置快照功能的情况下,文件所对应的block数据已经开始真正从底层文件系统层面进行删除,此时需要快速的做出决断进行恢复操作。因为需要停止数据服务(nn、dn),所以需要综合考虑,去权衡恢复数据和停服对线上服务的影响两者之间的利害关系。
首先梳理下hdfs delete的流程,如下图:
我们可以看到hdfs delete流程中很多环节都是异步进行操作的,所以如果想恢复数据,需要立即做出决定是否进行停服,可以恢复的数据量也取决于操作与停服间隔时间,还有集群的繁忙程度,所以可能恢复全部或者部分数据,如果时间过了很久了,在集群规模比较大、集群比较空闲的情况下,可恢复的数据量百分比就不能太乐观了。下面我们来说明下具体恢复步骤(说明:操作的前提是有删除操作之前的fsimage元数据,同时需要有备用的新集群):
- 及时停止hdfs集群服务(nn、dn),阻止block数据从os上进一步被删除;
由上述的hdfs delete流程可知namenode删除block指令是通过datanode心跳一批批下发的,且datanode是通过异步线程删除block数据, 所以需要立即停止服务进程,阻止datanode上的block文件进一步被删除;
- 拷贝删除数据前的元数据fsimage文件,并在新集群namenode加载
2.1) 通过hdfs审计log找到删除操作开始的确切时间点;
2.2) 从fsimage备份的多个版本中,找到删除操作时间点前的fsimage;
2.3) 停掉新集群所有进程(保留journalnode),初始化新环境;
2.4) 停掉所有journalnode进程,在image目录替换为备份的fsimage文件,替换imaeg、edits、和所有journalnode目录下的VERSION文件为生产环境上的VERSION文件;
2.5) 启动namenode进程;
- 用fsck在新集群namenode获取数据块blockid,生成列表文件
./bin/hadoop fsck 误删目录 -files -blocks (通过脚本生成blockid列表文件)
- 从原集群datanode上拷贝blockid对应的文件到新集群datanode
4.1) 在原集群每个datanode上生成要拷贝的blockid文件目录列表(编写脚本通过ancible执行)
4.2) 统计可以检索出来的存在的blockid文件数量(按照blockid去重)和总blockid数量的比例,根据比例情况判断数据恢复操作是否继续进行;
4.3) 在原集群每个datanode上拷贝blockid对应文件到新集群datanode(编写脚本通过ancible执行,scp,如果有多副本需要copy到不同datanode节点上)
4.4) 对比验证copy到新集群datanode节点上文件数量;
- 启动新集群datanode,检查新集群恢复的数据量,文件数据可用性
5.1) 启动新集群上所有datanode;
5.2) 检查恢复的文件数据量,测试文件数据的可用性
- 恢复老集群服务
启动hdfs集群所有节点的服务进程;
7.从新集群distcp hdfs文件回老集群
以上就是关于hdfs数据误删后数据恢复的步骤,有疑问或者错误的地方的欢迎沟通和指正。
关键词:大数据培训