背景&现象
断电导致HDFS服务不正常,并显示块损坏
恢复步骤
检查HDFS系统文件健康
$>hdfs fsck /
注:通过web ui也可以进行查看
检查是对应的哪些block发生了损坏
$>hdfs fsck -list-corruptfileblocks
出来的结果是损坏的block及对应的file所在的路径
生产场景分析
业务场景如下:MySQL ----同步数据----> 大数据平台
只需要从MySQL中XXXX这张表的数据重新刷一份到HDFS平台即可
因为从上述的检查结果来看我们是知道了XXXX这张表的数据出现了问题
获取损坏文件的块分布在哪些机器上
目前是只知道对应file所对应的block名字是什么,但是并不知道这些block是分布在哪些机器上面的,我们是未知的
块、文件、机器的关系:
1个文件对应多个块,每个块分布在不同的机器上面
我们可以使用命令:
$>hdfs fsck xxx -files -locations -blocks -racks
对应参数的含义:
- -files 文件分块信息,
- -blocks 在带-files参数后才显示block信息
- -locations 在带-blocks参数后才显示block块所在datanode的具体IP位置,
- -racks 在带-files参数后显示机架位置
对于损坏块的文件,是无法进行显示的
对于好的没有损坏的文件,是能够显示块分布情况的
如果我们知道块分布在哪台机器上,我们就直接去对应机器的目录上面,删除对应的Linux文件即可,最终的效果就是将该损坏的块给删除了,路径为/dfs/dn…
而使用hdfs fsck / -delete命令是直接将损坏的文件给删除了,那么该文件对应的所有的块也就删除了
方式一:delete方式暴力解决
最终删除损坏块的文件,然后对应的业务系统数据重刷
$>hdfs fsck / -delete
注:该命令仅仅只是删除损坏块所对应的文件,而不是删除损坏的那个块
带来的三点思考:
- 如果仅仅删除损坏块对应的文件,那么对应的数据丢了多少我们是不知道的,如何去确保数据补回来呢? 这是需要思考的。
- 如果是日志类的数据,丢一点点是没有关系的,那就没事
- 如果对应的数据是业务数据,比如订单数据,那是不能丢的,数据重刷和维护都是需要报告的
方式二:debug方式优雅处理
使用debug命令进行手动恢复
直接命令行输入hdfs,并敲击回车之后,所显示的一串命令当中,是没有debug命令的
但是实际上hdfs debug是有这个组合命令的
手动修复Block的命令(最多重试10次):
$> hdfs debug recoverLease -path /blockrecover/ruozedata.md -retries 10
这样做是基于这样的思考:1个block有对应的三个副本,其中一个副本损坏了,但是有另外两个副本存在,是可以利用另外两个副本进行修复的,因此我们可以使用debug命令进行修复
方式三:配置参数自动修复
在HDFS中实际上也可以配置块的自动修复的
当数据块损坏后,DataNode节点在执行directoryscan操作之前,都不会发现损坏
directoryscan操作是间隔6h进行的
dfs.datanode.directoryscan.interval : 21600
在DataNode向NameNode进行blockreport之前,都不会恢复数据块;
blockreport操作是间隔6h进行的
dfs.blockreport.intervalMsec : 21600000
当NameNode收到blockreport才会进行恢复操作