HDFS之DataNode工作原理超全总结

本文深入探讨了HDFS DataNode的工作流程,包括启动流程、存储目录结构、数据块管理、流式接口实现、读写数据的细节以及数据块的恢复和心跳机制。详细介绍了DataNode如何与NameNode交互、存储目录的创建与管理、数据块的创建、提交和删除,以及数据流管道的建立与数据传输。此外,还阐述了DataNode如何通过数据块扫描器进行数据健康检查,确保数据一致性。
摘要由CSDN通过智能技术生成

启动流程

  1. 检查配置项${dfs.data.dir}对应的存储目录是否创建,是否具有读写的权限检查;
  2. 获取本节点的主机名称NameNode的地址,以及其他一些运行时需要的配置项
  3. 构造向NameNode注册需要的DataNodeRegistration对象,并在接下来进行一些属性的初始化;
  4. 建立到NameNodeIPC连接,并调用handshake()方法与NameNode进行握手,得到了NamespaceInfo对象,包含了layoutVersionnamespaceIDcTime等信息;
  5. 构造数据节点存储DataStorage对象,执行可能的存储空间状态恢复,接着构造数据节点使用的FSDataset对象;
  6. 创建流式接口服务器DataXceiverServer对象;
  7. 创建数据块扫描器DataBlockScanner对象;
  8. 创建数据节点上的HTTP信息服务器,该服务器提供了数据节点上的运行状态信息
  9. 创建该数据节点IPC服务器,对外提供ClientDatanodeProtocolInterDatanodeProtocol远程接口服务;
  10. 最后,调用NameNode的远程接口register()进行注册,并启动DataNode线程开始对外提供服务。

存储目录的文件结构以及特点

image

  1. blocksBeingWritten:保存了客户端发起的,当前正在写的数据块;

  2. detach:用于配合数据节点升级,==数据块分离==操作时的临时文件夹;

  3. tmp:保存了用于数据块复制时,当前正在写的数据块;

  4. in_user.lock:表示当前目录已经被使用,实现了一种机制,这样DataNode可以独自使用该目录;

  5. current:保存了已写入HDFS文件系统的数据块和一些系统工作时需要的文件;

    • blk_开头的文件HDFS数据块,用来保存HDFS文件内容;
    • .meta后缀文件CRC32校验文件,保存数据块的校验信息;

    current目录达到一定规模时(由配置项${dfs.datanode.numblocks}指定),DataNode会在current目录下新创建一个子目录subdir*,用于保存新的数据块和元数据。

    默认配置下,current目录下最多只有64个数据块(128个文件)和64个子目录。通过这种手段,DataNode既保证目录不会太深,影响文件检索性能,同时也避免了某个目录保存大量的数据块。

对存储目录的管理

数据节点的业务逻辑主要由文件结构对象提供的服务进行管理,数据节点的文件结构管理包括两部分内容:数据节点存储DataStorage文件系统数据集FSDataSet

DataStorage

image

数据节点存储DataStorage是抽象类Storage的子类,而抽象类Storage又继承自StorageInfo。和DataStorage同级的FSImage类主要用于组织NameNode的磁盘数据,FSImage的子类CheckpointStorage,则管理SecondaryNameNode使用的文件结构。

StorageInfo包含了三个重要的共有的属性,包括HDFS存储系统信息结构版本号layoutVersion、存储系统标识namespaceID和存储系统创建时间cTime。这些信息都保存在current目录下的VERSION文件中,典型的VERSION文件内容为:

namespaceID=1301932004
storageID=DS-1056522850-172.31.207.102-50010-1498861743747
cTime=0
storageType=DATA_NODE
layoutVersion=-32

StorageInfo的基础上,抽象类Storage可以管理多个目录,存储目录的实现类为StorageDirectory,它是Storage的内部类,提供了在存储目录上的一些通用操作

DataStorage扩展了Storage,专注于数据节点存储空间的生命周期管理,其代码可以分为两个部分:升级相关升级无关的。在数据节点第一次启动时,会调用DataStorage.format()创建存储目录结构,通过删除原有目录及数据,并重新创建目录,然后将VERSION文件的属性赋值,并持久化到磁盘中。

DataStorage的升级操作

HDFS升级时需要复制以前版本的元数据(对NameNode数据(对DataNode。在DataNode上,升级并不需要两倍的集群存储空间,DataNode使用了Linux文件系统的硬链接技术,可以保留对同一个数据块的两个引用,即当前版本以前版本。通过这样的技术,就可以在需要的时候,轻松回滚到以前版本的文件系统。

硬链接是一种特殊的文件系统机制,它允许一个文件可以有多个名称。当一个文件有多个名称时,删除其中的一个名称,并不会删除文件数据,只有所有的文件名被删除后,文件系统才会真正删除文件数据。

好比在Java中,一个对象的多个引用。将其中一个引用置为null,垃圾收集器并不会去回收该对象,只有所有对该对象的引用都断开时,该对象才会被垃圾回收器回收。

  1. 升级操作

    HDFS升级最多保留前一版本的文件系统,没有多版本的升级、回滚机制。同时引入升级提交机制,该机制用于删除以前的版本,所以在升级提交后,就不能回滚到以前版本了。综上所述,DataNode和NameNode升级过程采用了下图的状态机:

    image

    数据节点的升级主要由DataStorage.doUpgrade()方法实现,其中升级过程主要涉及如下几个目录:

    • curDir:当前版本目录,通过StorageDirectory.getCurrentDir()获得,目录名为current
    • prevDir:上一版本目录,目录名为previous
    • tmpDir:上一版本的临时目录,目录名为${dfs.data.dir}/previous.tmp

    DataStorage.doUpgrade()升级流程如下:

    • 确保上述涉及的目录处于正常状态:current存在、previous存在则删除、previous.tmp存在则抛出异常;
    • current目录改名为previous.tmp
    • 使用HardLink,在新创建的current目录下,建立到previous.tmp目录中数据块数据块校验文件的硬链接;
    • 在新的current目录下,创建新版本的VERSION文件。
    • 最后,将previous.tmp目录改名为previous目录,完成升级。

    这时,DataNode上存储着previouscurrent两个目录,而他们包含了同样的数据块和数据块校验文件,但他们有各自的VERSION文件。

  2. 升级回滚

    • 检查previous目录是否存在,如果不存在,则无法回滚;
    • 检查previous目录下的VERSION文件中的layoutVersioncTime,如果preLayoutVersion小于当前系统的HDFS存储系统信息结构版本号或者preCTime小于当期存储系统的创建时间cTime,则无法进行回滚。
    • current目录重命名为removed.tmp
    • previous目录重命名为current
    • 删除removed.tmp目录;
  3. 升级提交

    • previous重命名为finalized.tmp
    • 启动一个线程删除finalized.tmp

升级过程中临时文件的用途

因为升级、升级提交或升级回滚都需要进行一定的耗时操作。在系统升级过程中,doUpgrade()需要建立数据块文件的硬链接,在这一过程中,如果突然出现故障,那么存储空间就有可能处于某一中间状态。因此,引入上述的目录,系统就能够判断目前doUpgrade()处于什么阶段,并采取相应的措施。

数据节点Storage状态机

image

StorageDataStorage提供了一个完美的HDFS数据节点升级机制,Storage状态机、以及配合状态机工作的临时文件,提供了一个完备的升级方法。在升级过程中或者升级回滚过程中的任意步骤出现错误,都可以通过状态机恢复到正常状态。

FSDataset

image

  1. FSDatasetInterface接口

    FSDatasetInterface接口的方法主要分为三类:

    • 数据块相关的方法FSDataset管理了DataNode上的数据块,大量的FSDataset方法和数据块相关,如创建数据块、打开数据块的输入、输出流、提交数据块等;
    • 数据块校验信息文件相关的方法:包括维护数据块和校验信息文件的关系,如校验信息文件输入流等方法。
    • 其他方法:包括FSDataset健康检查、关闭FSDatasetshutDown()等方法。
  2. FSDirFSVolumeFSVolumeSet

    FSDataset借鉴了LVM的一些概念,可以管理多个数据目录,文件数据集将它管理的存储空间分为三个级别,分别用FSDir

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值