深入理解 Hadoop (三)HDFS文件系统设计实现

news/2024/5/20 2:22:14 标签: hadoop, hdfs, 大数据

HDFS FileSystem NameNode 端抽象实现

HDFS 磁盘元数据文件解读

在这里插入图片描述
共有五种格式的文件:
edits_0000000000000041912-0000000000000041913:该 LogSegment 记录了 transaction id 在 41912-41913 之间的事务日志。(最多保留 50 个)
edits_inprogress_0000000000000041914:正在使用的 编辑日志文件,从 transaction id = 41914 开始,之后的事务都往这个文件中进行记录,直到进行了 rollLog 操作:生成一个新的 edits_inprogress_start_transaction_id 文件,把旧的 edits_inprogress_start_transaction_id 改名成 edits_(start_transaction_id)_(end_transaction_id) 。
fsimage_0000000000000041843 和 fsimage_0000000000000041843.md5:transaction id = 41843 以前的事务,都合并到了这个 fsimage 文件中了,.md5 文件存储了它的校验信息(最多保留 2 个)
seen_txid:存储最新的 fsimage 文件的 最新的 transaction id
VERSION:版本信息

HDFS FileSystem NameNode 内部结构

在这里插入图片描述
类比 ZooKeeper 存储模型中的 DataTree + DataNode,NameNode 内存树抽象为 FSDirectory + INode(两个实现类:INodeDirectory: 内部有一个集合 List< INodeDirectory> 或 INodeFile + 文件内部 List< Block>),每个 INode 内部有维护有一个 INode parent。

NameNode 元数据内存部分

也即 FSDirectory 维护的名称空间
在这里插入图片描述
上图涉及到的核心抽象:

  • FileSystem:具体实现: DistributedFileSystem、LocalFileSystem、FSNameSystem
  • FSDirectory
  • INode(INodeDirectory + INodeFile)
  • FSImage
  • FSEditlog

NameNode 磁盘部分核心抽象

public class FSImage implements Closeable {
    // 管理磁盘编辑日志
    protected FSEditLog editLog = null;
    // 管理存储目录
    protected NNStorage storage;
    // 元数据存储目录格式化
    void format(...) throws IOException {}
    // 加载磁盘编辑日志恢复到内存
    long loadEdits(...) throws IOException {}
    // 加载磁盘 fsimage 镜像文件恢复到内存
    void loadFSImage(....) throws IOException {}
    // 生成 fsimage 镜像文件
    void saveFSImage(...) throws IOException {}
    // 保存命名空间
    void saveNamespace(...) throws IOException {}
    // 接收到 SecondaryNameNode 发送的要进行 checkpoint 的请求之后执行的操作
    NamenodeCommand startCheckpoint(...) throws IOException {
        CheckpointSignature sig = rollEditLog(layoutVersion);
        return new CheckpointCommand(sig, needToReturnImg);
    }
}

public class FSEditLog implements LogsPurgeable {
    // dfs.namenode.shared.edits.dir 目录 = qjournal://bigdata02:8485;bigdata03:8485;bigdata04:8485/hadoop330ha
    private final List<URI> editsDirs;
    // dfs.namenode.shared.edits.dir 目录 = qjournal://bigdata02:8485;bigdata03:8485;bigdata04:8485/hadoop330ha
    private final List<URI> sharedEditsDirs;
    private JournalSet journalSet = null;
    EditLogOutputStream editLogStream = null;
    // 事务控制
    private long beginTransaction() {}
    private void endTransaction(long start) {}
    // 记录日志操作, 记录一条日志到 edit_inprogress 文件里面
    void logEdit(final FSEditLogOp op) {}
    synchronized void logEdit(final int length, final byte[] data) {}
    // 开启一个新的编辑日志 LogSegment
    void startLogSegment() throws IOException {}
}

HDFS FileSystem DataNode 端抽象实现

HDFS DataNode 磁盘数据文件解读

HDFS DataNode 支持多磁盘存储,通过以下配置生效:

<property>
    <name>dfs.datanode.data.dir</name>
    <value>dir1,dir2,dir3</value>
</property>

数据目录下的目录结构如下:

  • dir1
    • blockpool 1
      • current
        • finalized 已写成功的数据块的存储目录
          • 还会划分两级存储目录,然后再存数据块
        • rbw 正在执行写操作的数据块
        • layzpresistent:懒持久化,可以配置,写入数据块的时候,先写到内存中,然后到某了合适的时间,再持久化到磁盘
      • tmp
    • blockpool 2
  • dir2
    • blockpool 1
    • blockpool 2
  • dir3
    • blockpool 1
    • blockpool 2

注意:每个 blockpool 对应联邦集群中的一个 NameService

DataNode 的每个数据存储目录结构示例如下:

// 这个 current 就表示是某一个 配置的存储目录(dir1, dir2, dir3 的其中之一)
├── current
    // 块池目录
    ├── BP-2052521754-192.168.123.102-1614493867466
    ├── BP-2052521754-192.168.123.102-1614493867477
    │ ├── current
    │ │ ├── dfsUsed
    │ │ ├── finalized
    │ │ │ └── subdir0
    │ │ │ ├── subdir0
    │ │ │ ├── subdir1
    │ │ │ ├── subdir10
    │ │ │ │ ├── blk_1073744394
    │ │ │ │ ├── blk_1073744394_3617.meta
    │ │ │ │ ├── blk_1073744618
    │ │ │ │ └── blk_1073744618_3841.meta
    │ │ │ ├── subdir11
    │ │ │ │ ├── blk_1073744640
    │ │ │ │ ├── blk_1073744640_3863.meta
    │ │ │ │ ├── blk_1073744892
    │ │ │ │ └── blk_1073744892_4115.meta
    │ │ │ ├── subdir12
    │ │ │ │ ├── blk_1073744948
    │ │ │ │ ├── blk_1073744948_4171.meta
    │ │ │ │ ├── blk_1073745141
    │ │ │ │ └── blk_1073745141_4375.meta
    │ │ │ ├── subdir2
    │ │ │ ├── subdir3
    │ │ │ ├── subdir4
    │ │ │ ├── subdir5
    │ │ │ ├── subdir6
    │ │ │ ├── subdir7
    │ │ │ ├── subdir8
    │ │ │ │ ├── blk_1073744026
    │ │ │ │ ├── blk_1073744026_3243.meta
    │ │ │ │ ├── blk_1073744038
    │ │ │ │ └── blk_1073744038_3261.meta
    │ │ │ └── subdir9
    │ │ │ ├── blk_1073744252
    │ │ │ ├── blk_1073744252_3475.meta
    │ │ │ ├── blk_1073744377
    │ │ │ └── blk_1073744377_3600.meta
    │ │ ├── rbw
    │ │ └── VERSION
    │ ├── scanner.cursor
    │ └── tmp
    └── VERSION
├── in_use.lock

上述目录结构的一些相关解释:
BP-2052521754-192.168.123.102-1614493867477:在 HDFS Fedaration 集群中,有多个NameSpace,对应多组 NameNode,每一组 NameNode 都有一个独立的 BlockPool 块池,一个 BlockPool 块池目录保存了 该 BlockPool 在当前存储目录中的所有数据块。
VERSION:版本文件,该文件是一个标准的 Properties 文件,可自行查看
finalized:数据块存储目录,保存的是写入成功的数据块,包含数据块文件和 .meta 校验文件
rbw:数据块存储目录,保存的是正在写入的数据块,包含数据块文件和 .meta 校验文件
tmp:数据块存储目录
scanner.cursor:DataNode 对数据块进行校验的一个遍历游标,用来记录此时遍历到的数据块的位置
in_use.lock:DataNode 线程持有的目录锁,防止多线程对该文件夹进行修改操作

DataStorage 抽象

DataStorage 管理与组织磁盘存储目录。
在这里插入图片描述

public abstract class Storage extends StorageInfo {
    // 一个 DataNode 可以配置多个存储目录
    private final List<StorageDirectory> storageDirs = new CopyOnWriteArrayList<>();
}

public class DataStorage extends Storage {
    public final static String BLOCK_SUBDIR_PREFIX = "subdir";
    final static String STORAGE_DIR_DETACHED = "detach";
    public final static String STORAGE_DIR_RBW = "rbw";
    public final static String STORAGE_DIR_FINALIZED = "finalized";
    public final static String STORAGE_DIR_LAZY_PERSIST = "lazypersist";
    public final static String STORAGE_DIR_TMP = "tmp";
    
    // BlockPoolSliceStorage 负责管理块池目录
    private final Map<String, BlockPoolSliceStorage> bpStorageMap = Collections.synchronizedMap(
        new HashMap<String, BlockPoolSliceStorage>());
}

FsDatasetImpl 抽象

管理和组织 DataNode 上的数据块及其元数据。
在这里插入图片描述

// FsDatasetImpl 负责为 DataNode 提供磁盘服务
class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
    // DataNode 上的所有数据块的一个管理载体
    final ReplicaMap volumeMap;
    // 存储目录管理组件
    private final FsVolumeList volumes;
}

// FsVolumeList 就是对多个存储目录 FsVolumeImpl 的一个封装抽象
class FsVolumeList {
    private final CopyOnWriteArrayList<FsVolumeImpl> volumes = new CopyOnWriteArrayList<>();
}

// 一个 FsVolumeImpl 负责管理一个存储目录下的所有数据块,一个存储目录下又有多个块池,所以映射到多个 BlockPoolSlice 来进行管理
public class FsVolumeImpl implements FsVolumeSpi {
    // 记录存储位置信息
    private final StorageLocation storageLocation;
    // 对应的数据块管理组件
    private final FsDatasetImpl dataset;
    // 一个 FsVolumeImpl 映射到多个块池,BlockPoolSlice 负责管理一个块池
    private final Map<String, BlockPoolSlice> bpSlices = new ConcurrentHashMap<String, BlockPoolSlice>();
}

class ReplicaMap {
    // 一个 BlockPool 一个 TreeSet
    private final Map<String, FoldedTreeSet<ReplicaInfo>> map = new HashMap<>();
}

http://www.niftyadmin.cn/n/5322481.html

相关文章

node-sass@4.7.2 postinstall: `node scripts/build.js`

Can‘t find Python executable “D:\Python36\python.EXE“, you can set the PYTHON env variable.-CSDN博客 gyp ERR! build error gyp ERR! stack Error: C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe failed with exit code: 1 gyp ERR! stack at Chil…

uniapp 制作 wgt 包(用于 app 的热更新)

升级版本号 修改 manifest.json 的配置&#xff0c;应用版本名称和应用版本号 必须高于上一版的值。 制作 wgt 包 发布 wgt 包 打开 uni-admin 项目的升级中心 上传后会自动生成下载链接 app 的静默热更新 发布新版后&#xff0c;用户打开app&#xff0c;后台会自动下载 wgt…

python subprocess执行cmd同时输入密码获取参数

python subprocess执行cmd同时输入密码获取参数 一&#xff1a;手动输入cmd命令 我们再执行命令时需要同时传入密码或其他参数的时候&#xff0c;我们可以使用 echo {password} | adb shell ls /log这个命令是一个组合的命令&#xff0c;涉及到 echo、管道 | 和 adb shell ls…

【Arduino】编程语言:定时函数、数学函数、字符函数(功能、语法格式、参数说明、返回值) | 软件开发环境:安装步骤介绍(EXE安装版、ZIP安装版)

你的负担将变成礼物,你受的苦将照亮你的路。———泰戈尔 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🏅[4] 阿里云社区…

OpenssH 漏洞修复

文章目录 OpenSSH 漏洞修复需求&#xff1a;准备环境配置阿里云yum源关闭防火墙 && SELinux安装 telnet-server安装 zlib 软件包安装OpenssL安装 OpenssH报错信息 OpenSSH 漏洞修复 场景&#xff1a; CentOS Stream 9 系统ssh默认版本一般是OpenSSH_8.7p1 &#xff0c;…

【洛谷】P2709 小B的询问——莫队问题

文档快速阅读 题目链接题目概况小B的询问题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 个人思路参考代码C 题目链接 小B的询问 题目概况 小B的询问 题目描述 小B 有一个长为 n n n 的整数序列 a a a&#xff0c;值域为 [ 1 , k ] [1,k] [1,k]。 他一共…

基于遗传算法改进BP神经网络的承载力预测,基于ga-bp的破坏模式预测

目录 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 遗传算法原理 遗传算法主要参数 遗传算法流程图 完整代码包含数据下载链接: 基于遗传算法改进BP神经网络的承载力预测,基于ga-bp的破坏模式预…

Ceph入门到精通-通过 CloudBerry Explorer 管理对象bucket

简介 CloudBerry Explorer 是一款可用于管理对象存储&#xff08;Cloud Object Storage&#xff0c;COS&#xff09;的客户端工具。通过 CloudBerry Explorer 可实现将 COS 挂载在 Windows 等操作系统上&#xff0c;方便用户访问、移动和管理 COS 文件。 支持系统 支持 Wind…