美文网首页
hdfs 集群重建,block损坏定位以及修复,Blocks w

hdfs 集群重建,block损坏定位以及修复,Blocks w

作者: 邵红晓 | 来源:发表于2021-09-01 10:16 被阅读0次

    背景

    说点没用的,我司进行集群迁移,没有用的测试机器要进行格式化卖掉了,然后突然一条伟大的命令,误删除了正在使用的hadoop集群所有节点的操作系统盘,数据盘保留,灾难就此来了。

    hdfs 集群重建和数据恢复

    HDFS metadata以树状结构存储整个HDFS上的文件和目录,以及相应的权限、配额和副本因子(replication factor)等。
    nn启动的时候:会将磁盘上的元数据加载到内存中,
    磁盘中的元数据只有:
    1)抽象目录树
    2)数据和块的对应关系,
    3)没有 块的存储位置
    磁盘上仅仅会存储一个空的节点列表,这个节点列表是在datanode发送心跳报告之后填上的。
    例如:/aa/hadoop2.7.6.tar.gz [blk_237838365:[],blk_237838366:[]]
    而块的存储位置是在datanode向namenode发送心跳报告的时候汇报的,datanode向namenode汇报自己身上的块的存储信息。
    例如:hadoop01:blk_237838365,blk_237838366,blk_237838367
    然后内存接收datanode的心跳包 ,补全块的存储位置列表整。
    例如:/aa/hadoop2.7.6.tar.gz [blk_237838365:[hadoop01,hadoop02],blk_237838366:[hadoop01]]

    NameNode

    HDFS metadata主要存储两种类型的文件
    1、fsimage
    记录某一永久性检查点(Checkpoint)时整个HDFS的元信息
    2、edits
    所有对HDFS的写操作都会记录在此文件中
    3、Checkpoint介绍
    standbynamenode HDFS会定期(dfs.namenode.checkpoint.period,默认3600秒)的对最近的fsimage和一批新edits文件进行Checkpoint(也可以手工命令方式),Checkpoint发生后会将前一次Checkpoint后的所有edits文件合并到新的fsimage中,HDFS会保存最近两次checkpoint的fsimage。Namenode启动时会把最新的fsimage加载到内存中。

    基础知识。

    1、namenode cat /export/hadoop/hdfs/namenode/current/VERSION

    namespaceID=1242163293
    clusterID=CID-124668a8-9b25-4ca7-97bf-5dd5c25041a9
    cTime=1455091012961
    storageType=NAME_NODE
    blockpoolID=BP-180412957-40.32.10.18-1419305031110
    layoutVersion=-60
    

    layoutVersion- HDFS metadata版本号,通常只有HDFS增加新特性时才会更新这个版本号
    namespaceID/clusterID/blockpoolID - 这三个ID在整个HDFS集群全局唯一,作用是引导Datanode加入同一个集群。在HDFS Federation机制下,会有多个Namenode,所以不同Namenode直接namespaceID是不同的,分别管理一组blockpoolID,但是整个集群中,clusterID是唯一的,每次format namenode会生成一个新的,也可以使用-clusterid手工指定ID

    namespaceID是文件系统的唯一标识,是在文件系统首次格式化时设置的。
    clusterID是HDFS集群作为一个整体的唯一标识。这两个属性对HDFS联邦很重要,因为一个集群可能由多个namespace组成,每个namespace由一个NameNode管理。
    blockpool块池的唯一标识,块池表示一个namespace下的所有文件,由NameNode管理。
    storageType - 有两种取值NAME_NODE /JOURNAL_NODE,对于JournalNode的参数dfs.journalnode.edits.dir,其下的VERSION文件显示的是JOURNAL_NODE
    cTime - HDFS创建时间,在升级后会更新该值
    2、edits_start transaction ID-end transaction ID
    finalized edit log segments,在HA环境中,Standby Namenode只能读取finalized log segments,
    3、edits_inprogress__start transaction ID
    当前正在被追加的edit log,HDFS默认会为该文件提前申请1MB doublebuffer空间以提升性能
    4、fsimage_end transaction ID
    每次checkpoing(合并所有edits到一个fsimage的过程)产生的最终的fsimage,同时会生成一个.md5的文件用来对文件做完整性校验
    5、seen_txid
    保存最近一次fsimage或者edits_inprogress的transaction ID。需要注意的是,这并不是Namenode当前最新的transaction ID,该文件只有在checkpoing(merge of edits into a fsimage)或者edit log roll(finalization of current edits_inprogress and creation of a new one)时才会被更新。
    这个文件的目的在于判断在Namenode启动过程中是否有丢失的edits,由于edits和fsimage可以配置在不同目录,如果edits目录被意外删除了,最近一次checkpoint后的所有edits也就丢失了,导致Namenode状态并不是最新的,为了防止这种情况发生,Namenode启动时会检查seen_txid,如果无法加载到最新的transactions,Namenode进程将不会完成启动以保护数据一致性。
    6、in_use.lock
    防止一台机器同时启动多个Namenode进程导致目录数据不一致

    hdfs集群重建步骤,前提是从last+found找回了元数据

    lost+found目录的文件通常是未链接的文件(名字以及被删除),这些文件还被一些进程使用(数据没有删除),在系统突然关机时(内核panic或突然断电)出现。这些文件系统会删除的,你不需要担心。当因为软件或硬件出现错误,导致文件系统不一致,也有可能把有问题的文件放入到lost+found目录。它提供了恢复丢失文件的一种方法。

    1、看运维大佬能不能恢复磁盘。
    2、查看NN和JN下面是不是还有没有删干净的,注意lost+found下面也是可以用的。
    3、重建集群指定dfs.namenode.name.dirdfs.journalnode.edits.dirdfs.namenode.data.dir配置要和故障集群一致,启动新建集群,只启动NN和JN,DN不启动,观察是否可以正常启动。
    4、同步故障集群Blockpool ID,Namespace ID,Cluster ID 到新建集群两个namenode节点,同步点
    NAME_NODE /export/hadoop/hdfs/namenode/current/VERSION
    JOURNAL_NODE /export/hadoop/hdfs/journal/xcardata/current/VERSION
    fsimage,edits,seen_txid 同步两个nn一致
    因为是拷贝数据节点的VERSION,所以datanode不需要修改。
    如果集群没有启用Federation机制,那么Blockpool ID,Namespace ID,Cluster ID全部一致,如果启用Federation机制Blockpool ID,Namespace ID会有2套,当前集群是没有启用。

    Federation是指HDFS集群可使用多个独立的NameSpace(NameNode节点管理)来满足HDFS命名空间的水平扩展,【单机namenode的瓶颈大约是在4000台集群,而后则需要使用联邦机制】
    这时候在DataNode上就不仅仅存储一个Block Pool下的数据了,而是多个(大家可以在DataNode的datadir所在目录里面查看BP-xx.xx.xx.xx打头的目录).

    6、重启新集群,等待nn启动加载fsimage和edit_image元数据和dn的block位置上报。
    7、观察监控发现。
    under replicated blocks 100w 副本数小于指定副本数的block数量
    block with corrupted replication 108w 损坏块个数

    • 解决步骤
      1、退出安全模式
      hadoop dfsadmin -safemode leave
      2、列出损坏文件,损坏的文件无法恢复,只能删除
      hdfs fsck /
      3、只删除有问题的块文件,delete corrupted files
      hdfs fsck -delete

    补充
    定位under replicated blocks,并解决
    hdfs fsck / | grep 'Under replicated' | awk -F':' '{print $1}'
    hadoop fs -setrep 3 /file_name
    定位有问题块
    hdfs fsck / | egrep -v '^\.+$' | grep -v replica | grep -v Replica
    打印出来块位置信息
    hdfs fsck /path/to/corrupt/file -locations -blocks -files
    删除问题块
    hdfs fs -rm /path/to/file/with/permanently/missing/blocks
    获取有关正在复制(或等待复制)的块的信息
    hadoop dfsadmin -metasave metasave-report.txt
    文件metasave-report.txt 生成在/var/log/hadoop/hdfs/下
    手动修复损坏的块数据 ,释放指定路径上的租约,路径必须位于HDFS文件系统上。默认重试次数为1。
    lease recovery 的目的是当 Client 在写入过程中挂了后,经过一定的超时时间后,收回租约并关闭文件
    hdfs debug recoverLease -path/path/to/corrupt/file -retries 10

    自动修复损坏的块数据
    当数据块损坏后,DN节点执行directoryscan操作之前,都不会发现损坏;
    也就是directoryscan操作是间隔6h
    dfs.datanode.directoryscan.interval : 21600
    在DN向NN进行blockreport前,都不会恢复数据块;
    也就是blockreport操作是间隔6h
    dfs.blockreport.intervalMsec : 21600000
    当NN收到blockreport才会进行恢复操作。

    metasave-report.txt 测试环境

        1 51298 files and directories, 29092 blocks = 80390 total
        2 Live Datanodes: 3
        3 Dead Datanodes: 0
        4 Metasave: Blocks waiting for replication: 27359
        5 /apps/hbase/data/WALs/yhg-hadoop-54188.xxx.com.cn,16020,1645421741628/yhg-hadoop-54188.xxx.com.cn%2C16020%2C1645421741628..meta.1645421772554.meta: blk_1074217482_487322 (replicas: l: 2 d: 0 c: 0 e: 0)  10.20.54.188:50010 :        10.20.54.186:50010 :
        6 /apps/hbase/data/data/dalishen/test-media_user/63f4084799ca7ba20683b4215774531e/f/02b6bed1897946ef9cbdbf29ef46a4f6: blk_1074217498_487338 (replicas: l: 2 d: 0 c: 0 e: 0)  10.20.54.188:50010 :  10.20.54.186:50010 :
        7 /apps/hbase/data/WALs/yhg-hadoop-54188.xxx.com.cn,16020,1645421741628/yhg-hadoop-54188.xxx.com.cn%2C16020%2C1645421741628..meta.1645421767092.meta: blk_1074217464_487302 (replicas: l: 2 d: 0 c: 0 e: 0)  10.20.54.188:50010 :        10.20.54.186:50010 :
    ...
    27363 /ranger/audit/hdfs/20201018/hdfs_ranger_audit_yhg-hadoop-54185.xxx.com.cn.log: blk_1074092260_362169 (replicas: l: 2 d: 0 c: 0 e: 0)  10.20.54.186:50010 :  10.20.54.187:50010 :
    27364 Mis-replicated blocks that have been postponed:
    27365 Metasave: Blocks being replicated: 1
    27366 blk_1074194618_464433 StartTime: 09:53:25 NumReplicaInProgress: 1
    27367 Metasave: Blocks 0 waiting deletion from 0 datanodes.
    27368 Corrupt Blocks:
    27369 Metasave: Number of datanodes: 3
    27370 10.20.54.186:50010 IN 563438292480(524.74 GB) 243224936448(226.52 GB) 43.17% 319746468176(297.79 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:57 CST 2022
    27371 10.20.54.188:50010 IN 563438292480(524.74 GB) 243148734464(226.45 GB) 43.15% 319822670160(297.86 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:57 CST 2022
    27372 10.20.54.187:50010 IN 563438292480(524.74 GB) 32843665966(30.59 GB) 5.83% 530336495115(493.91 GB) 0(0 B) 0(0 B) 100.00% 0(0 B) Mon Feb 21 14:04:55 CST 2022
    
    启动过程中遇到的问题

    问题1

    2020-10-16 01:17:27,500 INFO  impl.MetricsSystemImpl (MetricsSystemImpl.java:shutdown(606)) -
     NameNode metrics system shutdown complete. 2020-10-16 01:17:27,501 ERROR namenode.NameNode 
    (NameNode.java:main(1783)) - Failed to start namenode. java.io.FileNotFoundException: 
    /export/hadoop/hdfs/namenode/current/VERSION (Permission denied)         at
     java.io.RandomAccessFile.open0(Native Method)         at 
    java.io.RandomAccessFile.open(RandomAccessFile.java:316)     
    datanode启动失败 Changing permission for /export4/hadoop/hdfs/data/ from 755 to 750
    

    解决
    chown -R hdfs:hadoop /export[1-12]/hadoop/

    问题2
    image.png

    Blocks with no live replicas!=0 这意味着,有些块只有一个副本,就在当前节点上,如果数据节点被“删除”,则带有这些块的文件将被损坏。

    • 解决
      优雅的方法是通过一个使用来自-dfsadmin命令“metasave”。
      rm /tmp/single_replica
      hdfs dfsadmin -metasave metasave-report.txt
      cat /path/to/logs/hadoop/hdfs/metasave-report.txt | grep "l: 1" | cut -d':' -f1 >> /tmp/single_replica
      for hdfsfile in `cat /tmp/single_replica`; do hadoop fs -setrep 3 $hdfsfile; done
      设置副本数为3,依靠集群进行复制。
      image.png
    问题3

    报错 invalidate block

    • 情况1、在DataNode的块汇报以及增量块汇报操作时,NameNode会将汇报的数据块副本信息与当前NameNode内存中的数据块信息对比,然后计算出损坏的数据块副本,NameNode会调用BlockManager.markBlockAsCorrupt()方法处理损坏的副本
    • 情况2、客户端读文件以及DataNode的数据块扫描器都可能发现损坏的数据块副本,客户端会通过ClientProtocol.reportBadBlocks()方法向NameNode汇报损坏的数据块副本,DataNode会通过DatanodeProtocol.reportBadBlocks()方法向NameNode汇报损坏的数据块副本。

    markBlockAsCorrupt()方法会将损坏的副本加入corruptReplicas队列中,然后判断该副本对应的数据块是否有足够的副本数量,如果数据块已经有足够的备份数量,则将调用invalidateBlock()方法直接将损坏的副本加入invalidateBlocks队列中进行删除操作。如果副本系数不足,则更新neededReplications队列,复制该数据块
    使用invalidateBlock()方法删除副本的操作主要包括两个部分:
    ①调用addToInvalidates()方法将数据块加入invalidateBlocks队列中,之后BlockManager会将这个副本的删除指令通过心跳响应发送给Datanode。
    ②调用removeStoredBlock()从BlockManager.blocksMap中移除这个DataNode上的副本信息,同时更新excessReplicateMap、corruptReplicas以及neededReplications队列。

    当触发NAMENODE的双活切换(active-namenode给zk的心跳超时会发生)
    Datanode增量汇报该block-datanode映射给 namenode(切换后的active namenode)的时候,edit log还没从JournalNode同步过来,这时在namenode中已经有了block-datanode映射(从刚才datanode的report中来),但是还没有block-file映射(从edits文件里面来),导致namenode认为这个块不属于任何文件,定义为该块为invalidate block。

    这个在后台日志可以查到(后台standby没有完全变成activenamenode之前,会出现包含 invalidate block 的后台日志。)
    edits文件(包含block-file映射): 对于HDFS文件来说,包含的信息有修改时间、访问时间、块大小和组成一个文件块信息等;而对于目录来说,包含的信息主要有修改时间、访问控制权限等信息

    • 解决
      重新上报block信息
      hdfs dfsadmin -triggerBlockReport datanode_ip:port

    注意

    1、如果元数据完全丢失,datanode没有存储数据和块的关联信息,所以集群数据无法恢复
    2、经此一役,一定要做好元数据备份,所以定期及时的备份fsimage、edits和seen_txid文件非常重要(建议直接备份current整个目录)!即使存在HA的架构建议也备份下,多一份备份多一分安全。

    参考
    hdfs需要知道的
    hdfs wiki-非常有用

    相关文章

      网友评论

          本文标题:hdfs 集群重建,block损坏定位以及修复,Blocks w

          本文链接:https://www.haomeiwen.com/subject/ewbziltx.html