hdfs数据误删后恢复方式

我们知道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中添加下面的内容:

<!--Enable Trash -->
<property>
      <name>fs.trash.interval</name>
      <value>120</value>
</property>
<property>
      <name>fs.trash.checkpoint.interval</name>
      <value>120</value>
</property>

添加好上述内容后,不需要重启后台程序,直接就会生效。执行删除操作后,会先将文件移动到当前操作用户的.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元数据,同时需要有备用的新集群):

  1. 及时停止hdfs集群服务(nn、dn),阻止block数据从os上进一步被删除;

由上述的hdfs delete流程可知namenode删除block指令是通过datanode心跳一批批下发的,且datanode是通过异步线程删除block数据, 所以需要立即停止服务进程,阻止datanode上的block文件进一步被删除;

  1. 拷贝删除数据前的元数据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进程;

  1. 用fsck在新集群namenode获取数据块blockid,生成列表文件

./bin/hadoop fsck 误删目录  -files -blocks  (通过脚本生成blockid列表文件)

  1. 从原集群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节点上文件数量;

  1. 启动新集群datanode,检查新集群恢复的数据量,文件数据可用性

5.1) 启动新集群上所有datanode;

5.2) 检查恢复的文件数据量,测试文件数据的可用性

  1. 恢复老集群服务

启动hdfs集群所有节点的服务进程;

7.从新集群distcp hdfs文件回老集群 

以上就是关于hdfs数据误删后数据恢复的步骤,有疑问或者错误的地方的欢迎沟通和指正。

关键词:大数据培训

作者:小谷哥原文地址:https://segmentfault.com/a/1190000041459877

%s 个评论

要回复文章请先登录注册