【hadoop】HDFS块修复

当我们发现hdfs有异常的数据块的时候,往往会使用 hdfs fsck命令来查看情况,然后使用以下两个命令

hdfs debug recoverLease -path 文件绝对路径  -retries 2

hdfs fsck -delete 文件绝对路径

但是什么情况下,用哪个,会有什么影响,其实一直没怎么认真考虑过这些问题,今天就来模拟下丢数据的场景,然后测试下这两个命令

背景

HDFS场景下,有时候某些异常会导致丢失文件块!这时候,我们如何处理这些文件块,或者说这些文件块是否还有救?

丢文件块是一种统一的说法,实际上是两种情况,一个是 Corrupt blocks,一个是Missing replicas

先说个背景知识:当我上传一个文件到HDFS,这个文件在HDFS上看得到,也可以正常使用,实际上在磁盘上会存两种类型的文件

举例:

1、blk_1073743119
2、blk_1073743119_2295.meta

第一个文件就是实际上的数据,如果你的文件是文本类型的,你甚至可以直接cat这个blk文件,另一个是这个块的meta信息,相当于有了这个meta信息,我才能知道实际的数据在哪个blk里

如果是Corrupt blocks,那基本上是namenode里有这个文件块的meta信息,但是实际磁盘上找不到真实的数据块,而且是任何一个地方都找不到了,这种情况很可能数据就丢了;另一种是Missing replicas,这是数据块的副本缺失(比如正常情况下这个文件块副本数是3个,但是丢了一个只剩下2个了,那么显示的就是miss replicas)

 

正文

1、模拟丢失实际数据块

(1)、hdfs创建目录,生成一个文件,上传文件到hdfs

(2)、通过fsck命令,查看到这个文件块对应的blk名称(本次测试默认是2副本,不是3副本)

hadoop fsck /block/test.md -files -blocks

(上面的命令也可以加下 -locations就能看到实际存储在哪些datanode上)

到worker的机器上执行(所以文件块在worker2和worker3上):

sudo find / -name "blk_1073742058_1234*"

/mnt/disk3/hdfs/current/BP-551425355-192.168.2.237-1616556672088/current/finalized/subdir0/subdir0/blk_1073742058_1234.meta

cat blk_1073742058

asdascnoiansc0iqnv0qinmscpasmciapmcpaosncai0ncpa

 

备注:当我们写入一个文件到hdfs,会生成两种类型的文件 blk_xxxx(真正的文件),blk_1073743107_后缀.meta(这个是meta信息)

(3)、将实际的文件块改名(在worker2上改的)

sudo mv blk_1073742058 back_blk_1073742058_xxxx

然后在这台机器上cat这个文件块,我们发现会先在当前机器上找这个文件,报错后,去其他机器上找

hdfs dfs -cat /block/test.md

 

在抛这个错之后,我发现worker1的datanode从worker3那边拉了一个备份过来了(看了worker1的datanode日志)

也就是说hdfs正常情况下,如果发现块有异常,会自动做副本的同步!

备注:fsck检测文件的时候,是检测meta信息是否存在,实际上blk文件是否存在是不会检测的,也就是说我把blk重命名了,fsck是看不出来异常的

(4)、如果将以前改掉名字的文件块名字还原回去又重启datanode

可以看到datanode会把多余的副本删除的,始终保持了2副本

(5)、同时将两个blk文件改名

然后hdfs dfs -cat /block/test.md,然后这个块就真的miss了

(6)、尝试通过hdfs debug recoverLease -path /block/test.md  -retries 2修复

虽然显示成功,但是文件块还是读不了

(7)、只能将文件块元数据信息删除

hdfs fsck -delete /block/test.md

上面这个黄色的框,重启namenode就会消失

但是delete命令执行之后,这个文件块就彻底看不到了(虽然磁盘上这个数据还在,但是namenode里没有对应的信息了)

 

 

2、模拟丢失meta数据块

(1)、重新上传一个文件aaa.md

(2)、在worker2上面把meta信息的文件改掉

然后重启worker2的datanode之后,看到丢失了副本

(3)、使用debug命令修复

hdfs debug recoverlease -path /block/aaa.md

(4)、查看相应日志

看worker2的日志里,先是有找不到对应块的meta信息(因为被我rename了)

然后我修复块的时候,他开始从其他机器拉这个块过来,凑巧发现了这个块已经存在,然后把原来的实际数据块删除了,然后在另一块盘上生成了这个文件快

 

 

3、小tips

在hadoop的mapred-site.xml的配置文件里有这个参数mapreduce.client.submit.file.replication,默认为10

这个参数是我们提交一个任务到yarn上面,会默认把一些jar包文件设置成10副本,让不同的datanode机器拉取这些jar包运行的时候,可以更快,一般设置为集群datanode机器个数的开方(比如25台datanode,这个参数就改成5)

然后如果你的datanode的个数小于10,那你跑任务就会有丢失副本(Missing replicas),可以批量的修改文件的副本数来解决类似的问题

## 修复Under-replicated blocks:
## 查询到Under-replicated blocks的路径
hdfs fsck / | grep 'Under replicated' | awk -F':' '{print $1}' >> /tmp/under_replicated_files
##再根据路径进行修复
for hdfsfile in `cat /tmp/under_replicated_files`; do echo "Fixing $hdfsfile :" ; hadoop fs -setrep 副本数 $hdfsfile; done

 

总结

1、一般情况下,丢数据,很可能是什么磁盘异常,磁盘满了,datanode挂掉等场景,所以如果发现丢数据,可以先看下hdfs各个datanode的情况

2、理论上来说,如果所有文件块(包括副本)都丢了,那基本是没救了,只能通过 -delete 命令来清除这些块的元数据信息,避免计算引擎读这些块的时候出现异常而终止

3、hdfs debug recoverlease 这个命令回显的success,有些场景下,数据块还是异常的

4、如果一次性提交较多的任务,默认情况下就会有很多副本数为10的文件块,会导致datanode的压力,可以加大datanode的内存,或者减少提交任务的副本数

5、可以直接通过 hadoop fs -setrep 设置副本数,来释放磁盘上的空间

fsck命令详细用法,请参考:

hdfs fsck命令查看HDFS文件对应的文件块信息(Block)和位置信息:http://lxw1234.com/archives/2015/08/452.htm

 

菜鸡一只,如果有哪里写的不对的地方,还请大家批评指正!

好久没写文章了,年后其实还是比较忙的

累是累点,但还是有很多值得开心的事情的,努力努力~

这篇文章,基本上还是从结果来判断过程,希望以后我也有机会好好读读hdfs的源码!!

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值