美文网首页
HDFS 数据块管理

HDFS 数据块管理

作者: wayyyy | 来源:发表于2022-11-22 10:55 被阅读0次

    Namenode 维护着 HDFS 中两个重要的关系:

    • HDFS 文件系统和目录树
    • 数据块和数据节点的对应关系,即指定数据块的副本保存了哪些数据节点上的信息。这个信息是在 Datanode 启动时,由 Datanode 上报给 Namenode 的。

    INodeFile.blocks 字段记录了一个HDFS文件拥有的所有数据块,也正是通过这个字段,HDFS 第一关系与第二关系发生了关联。

    Block,BlockInfo,BlocksMap

    Block

    Block 类用来唯一标识Namenode 中的数据块,是HDFS 数据块最基本的抽象接口。
    Block 类定义了三个字段:

    blockId    // 唯一标识
    numBytes    // numBytes 是这个数据块的大小
    generationStamp    // 数据块的时间戳 
    

    其他包括序列化,反序列化的方法。

    BlockInfo

    BlockInfo 类扩展至 Block类,是 Block类的补充和完善。

    private BlockCollection bc;
    private Object[] triplets;
    

    bc 是 类型,记录了该HDFS文件的INode 对象的引用。
    triplets 保存了这个Block 副本存储在哪些数据节点上,triplets[] 数组有3 * 三个元素。假设 i 为 第 i 个保存该数据块副本的 datanode,那么 是保存这个数据块副本的第 个 datanode 对象。

    BlockInfo 中定义的方法大都是维护 这个数据结构。

    BlocksMap

    BlocksMap 是Namenode 上与数据块相关的最重要的类,它管理着Namenode 上数据块的元数据,包括当前数据块属于哪个HDFS文件,以及当前数据块保存在哪些Datanode 上。
    当 datanode 启动时,会对 datanode 的本地磁盘进行扫描,并将当前datanode 上保存的数据块信息汇报到 namenode,namenode 收到 datanode 的汇报信息之后,会建立这个数据块与保存这个数据块的数据节点的对应关系,并将这个信息保存在 BlockMap 中。所以无论是获取某个数据块对应的HDFS 文件,还是获取数据块保存在哪些数据节点上,都需要通过 BlockMap 对象。

    BlocksMap 实现比较简单,通过一个GSet 对象维护了 Block -> BlockInfo 的映射关系。

    private final int capacity
    private final GSet<Block, BlockInfo> blocks
    

    为什么BlockMap 维护的是 Block -> BlockInfo 的对应关系呢?

    HDFS 定义的副本有 5 种状态:

    static public enum ReplicaState {
        FINALIZED (0),
        RBW(1),
        RWR(2)
        RUR(3),
        TEMPORARY(4),
    }
    
    • FINALIZED
      datanode 上的副本已经完成操作,不再修改。

    • RBW
      刚刚被创建或者追加写的副本,处于写操作的数据流管道中,正在被写入,且已写入的副本的内容还是可读的。

    • RUR
      Lease 过期之后发生租约恢复和数据块恢复时副本所处的状态,RUR状态的副本使用的类描述

    • RWR
      如果一个datanode 挂掉并且重启后,所有RBW状态的副本都转换为RWR状态。RWR 状态的副本都将转换为RWR 状态。RWR 状态的副本不会出现在数据流管道中,结果就是等着进行租约恢复。

    • TEMPORARY
      datanode 之间传输副本时,正在传输的副本状态就是处于 状态,和 RBW 状态的副本不同的是,TEMPORARY 状态的副本内容是不可读的,如果 Datanode 重启,会直接删除处于状态的副本,

    而 Namenode 中的数据块有以下4种状态:

    static public enum BlockUCState {
        COMPLETE,
        UNDER_CONSTRUCTION,
        UNDER_RECOVERY,
        COMMITED;
    }
    
    • UNDER_CONSTRUCTION
      文件被创建或者进行追加写的操作时,正在被写入的数据块处于 UNDER_CONSTRUCTION 状态。处于该状态的数据块长度和时间戳都是可变的,但是处于该状态的数据块对于读取操作来说时可见的。

    • COMMITED
      客户端在写文件时,每次请求新的数据块或者关闭文件时,都会顺带对上一个数据块进行提交操作,上一个是数据块会从 UNDER_CONSTRUCTION 状态转为 COMMITED 状态,COMMITED 状态的数据块表明客户端已经把该数据块的所有数据都发送到了 Datanode 组成的数据流管道中,并且已经收到了下游的ACK响应。但是namenode 还没有收到任何一个datanode 汇报有 副本。

    • COMPLETE
      数据块的 length 和 gs 不再发生变化,并且 Namenode 已经收到至少一个 Datanode 报告有 FINALIZED 状态的副本。一个 COMPLETE 状态的数据块会在 Namenode 的内存中保存所有 FINALIZED 副本的位置。只有当HDFS文件的所有数据块都处于 COMPLETE 状态时,该HDFS文件才能被关闭。

    • UNDER_RECOVERY

    BloackManager 类

    BlockManager 类来管理和维护所有与数据块相关的操作。BlockManager

    相关文章

      网友评论

          本文标题:HDFS 数据块管理

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