《HDFS源码剖析》–初品ing

HDFS概述

​ HDFS是Hadoop 分布式文件系统,可以运行在通用硬件上、提供流式数据操作、能够处理超大文件的分布式文件系统。HDFS具有高度容错、高吞吐量、容易扩展、高可靠性等特征。

​ HDFS是一个主/从体系结构的分布式系统,拥有1个Namenode和多个Datanodes,用户可以通过HDFS客户端同Namenode和Datanodes交互以访问文件系统。Namenode是HDFS的Master节点, 负责管理文件系统的命名空间,以及数据块到具体Datanode节点的映射等信息。Datanode一般是一个节点一个, 负责管理它所在节点上的存储。一个文件被分成一个或多个数据块, 这些块存储在一组Datanode上Datanode以本地文件的形式保存这些数据块以及数据块的校验信息。

高延迟问题

  • 使用缓存或多master设计,以减轻client的数据压力。

存储小文件问题

  • 归档小文件,将小文件归档起来管理(HBase就是基于此)。如果想找回原来小文件内容,必须知道小文件与归档文件的映射关系。
  • 横向扩展,一个Hadoop集群管理小文件有限,把几个Hadoop集群拖在一个虚拟服务器里面,形成一个大的Hadoop集群。
  • 多Master设计。

HDFS基本概念

​ HDFS文件以数据块形式存储, 数据块是HDFS文件处理(读或者写)的最小单元由于HDFS文件往往较大,同时为了最小化寻址开销,所以HDFS数据块也更大,默认是128MB。数据块以文件形式存储在Datanode的磁盘上。

​ 读操作中,HDFS客户端会首先 到Namenode查找HDFS文件包含的数据块的位置信息,然后根据尾值信息从Datanode读取数据。

​ 写操作中,HDFS客户端也会首先 从Namenode申请新的数据块,然后根据新申请数据块的位置信息建立数据流管道写数据。

​ Namenode 管理着文件系统的命名空间(namespace),包括文件系统目录树、文件/目录信息以及文件的数据块索引,这些信息以两个文件的形式 永久保存在Namenode的本地磁盘,即 命名空间镜像文件和编辑日志文件。同时还保存着 数据块与数据节点的对应关系,这部分数据不保存在本地磁盘,而是在Namenode 启动时动态构建。HDFS客户端会通过名字节点获取上述信息,之后读写文件。

​ Namenode是HDFS的单一故障点,Hadoop2.X引入HA。同一个集群配置两个Namenode, Active-Namenode的内存元数据与Standby-Namenode完全同步

​ 因为Namenode中保存了数据块与数据节点的对应关系。如果 集群文件数量过多,Namenode的内存将成为限制系统横向扩展的瓶颈。为了解决这个问题,Hadoop2.X引入 联邦HDFS机制(Hadoop Federation)。其允许添加Namenode以实现命名空间的扩展, 每个Namenode管理文件系统命名空间的一部分,是一个独立的名空间卷。卷之间相互独立,两两之间不通信,一个Namenode失效了也不会影响其他Namenode所维护的命名空间的可用性

​ Datanode会根据HDFS客户端请求或者Namenode调度将新的数据块写入本地存储,或者读出本地存储上保存的数据块。

​ 作为从节点,Datanode会不断地向Namenode发送心跳、数据块汇报、缓存汇报,Namenode会通过心跳、数据块汇报、缓存汇报的 响应向Datanode发送指令,Datanode会执行这些指令。

​ 由于HDFS作为一个分布式文件系统,某些流程非常复杂,常常涉及Datanode、Namenode、Client三者之间的配合以及相互调用。为了降低耦合,HDFS将这些节点间的调用抽象成不同的接口。

​ Hadoop RPC接口:HDFS基于Hadoop RPC框架实现的接口

​ 流式接口: HDFS基于TCP或者HTTP实现的接口

HDFS主要流程

浅看,未深入源码

异常情况:

​ 读数据时,存储这个数据块的Datanode出现异常,无法读取数据。DFSInputStream会 切换到另一个保存了这个数据块的数据节点读取数据

​ 数据块的应答包中不仅包含了数据,还包含校验值, HDFS客户端收到数据应答包时,会校验数据。如果出现校验错误,也就是数据节点上的这个数据块副本出现了损坏,Client会 向Namenode汇报这个损坏的数据块副本,同时DFSInputStream会 尝试从其他的数据节点读取这个数据块

对于Datanode, 当Datanode成功地接收一个新的数据块时 ,Datanode会向Namenode汇报, Namenode会更新内存中的数据块与数据节点的对应关系

异常情况:

​ 客户端写文件是, 数据流管道中的Datanode故障,有如下故障恢复操作:

  • 输出流中缓存的没有确认的packet会重新加入发送队列输出流会为数据块申请一块新的时间戳,用新时间戳重新建立数据流管道。这保证 故障Datanode上的数据块的时间戳会过期,故障恢复之后,由于数据块的时间戳与Namenode元数据中的不匹配而被删除,保证了集群中所有数据块的正确性。
  • 故障Datanode点会从Datanode列表中删除,通知Namenode分配新的Datanode到数据流管道中。接下来输出流会将新分配的Datanode添加到数据流管道中,并使用新的时间戳重新建立数据流管道。由于 新添加的Datanode上并没有存储这个新的数据块,HDFS客户端会通知数据流管道中的一个Datanode复制这个数据块到新的Datanode上
  • 接下来以Datanode列表中的第一个Datanode作为”主节点”,其他Datanode作为”副本节点”。
  • 数据流管道重新建立之后,输出流会更新Namenode中的元数据。故障恢复完成,客户端可以完成后续的写操作。

追加写指打开一个已有文件并执行追加写操作,和写流程很类似,只不过在初始建立数据流管道时有些不同。

  • 打开已有的HDFS文件,获取文件最后一个数据块的位置信息,如果数据块写满则返回null。创建到这个数据块的输出流对象DFSOutputStream, 获取文件租约
  • 判断最后一个数据块是否写满,
  • 如果没有写满,根据该数据块的位置信息建立到该数据块的数据流管道;
  • 如果写满了,向Namenode申请一个新的数据块之后建立数据流管道。
  • 通过数据流管道写入数据,和上面写流程类似。
  • 关闭输入流,提交文件。同上

Datanode启动后与Namenode的交互主要包括三个部分:握手;注册;快汇报以及缓存汇报

Datanode启动过程

  • Datanode启动时会首先获取Namenode的版本号以及存储信息,并比较,确保Datanode和Namenode版本号一致。
  • Namenode收到注册请求后,判断当前Datanode的配置是否属于这个集群,版本号是否一致。
  • 注册成功后,Datanode将本地存储的所有数据块以及缓存的数据块上报到Namenode,Namenode会利用这些信息重新建立内存中数据块与Datanode之间的对应关系。

Datanode工作过程

  • Datanode成功启动后,需要定期向Namenode发送心跳,让Namenode知道其仍处于活动状态。Namenode会在Datanode的心跳响应中携带指令,知道Datanode进行数据块复制、删除以及恢复等操作。
  • Datanode成功添加一个新的数据块或者删除了一个已有的数据块时,向Namenode汇报,Namenode更新数据块与Datanode的对应关系。

  • Active Namenode 和 Standby Namenode 是实时同步的。

  • 为了使Standby节点和Active节点状态能够同步一致,要求两个Namenode的命名空间一致并且数据块与Datanode之间的对应关系一致。
  • 命名空间一致:两个节点都要与一组独立运行的节点(JournalNodes,JNS)通信,当Acvive 执行了修改命名空间的操作时,它会 定期将执行的操作记录在 editlog中, 并写入JNS的多数节点中。Standby 会一直监听JNS上editlog的变化,如果有改动,就会读取editlog并与当前的命名空间合并。
  • 当发生了错误切换,Standby节点会先保证已经从JNS上读取了 所有的editlog并与命名空间合并,然后才切换到Active状态。
  • 数据块与Datanode对应关系的一致性:要求HDFS集群中所有的Datanode 同时向这两个Namenode发送心跳以及快汇报信息。这样就完全同步了,也就可以实现 热备
  • 自动Failover机制:
  • Zookeeper集群
  • ZKFailoverController:实时监控Namenode的HA状态,如果Active不可服务,那么会其会自动触发主备切换操作。

Hadoop RPC

RPC(Remote Procedure CallProtocol,远程过程调用协议),允许本地程序像调用本地方法一样调用远程机器上应用程序提供的服务。

Namenode

Datanode

《Hadoop 2.X HDFS源码剖析》

Original: https://www.cnblogs.com/ogleede/p/16536953.html
Author: 茶倌
Title: 《HDFS源码剖析》–初品ing

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/586369/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring 源码(16)Spring Bean的创建过程(7)属性填充

    知识回顾 上一篇介绍了 Spring中三级缓存的 singletonObjects、 earlySingletonObjects、 singletonFactories, Spri…

    Java 2023年6月14日
    072
  • (Ⅱ)Java学习笔记

    Scanner对象 Scanner s = new Scanner(System.in); String str = scanner.next(); next(): 1、一点要读取…

    Java 2023年6月7日
    063
  • 三个线程交替按顺序打印ABC之条件队列的理解

    如题。本文给出交替打印的代码示例,并解释了条件变量在代码实现中所起的作用。 使用三个线程,一个只负责打印A,另一个只负责打印B,最后一个只负责打印C 按顺序交替。即打印A后,才能打…

    Java 2023年5月30日
    071
  • 现代医院信息化建设策略与实践

    概要: 优化医院服务流程,改善患者就医体验。 支撑门诊医疗服务,提高门诊诊疗水平。 规范急诊业务管理,强化急救治疗能力。 提高医院医疗效率,保障临床医疗质量。 规范护理服务流程,提…

    Java 2023年5月29日
    083
  • (转)Java atomic原子类的使用方法和原理(一)

    在讲atomic原子类之前先看一个小例子: <span class="hljs-keyword">public <span class=&qu…

    Java 2023年5月29日
    088
  • 【转载】springboot四 全局异常处理

    http://tengj.top/2018/05/16/springboot13/ https://www.jb51.net/article/110533.htm Original…

    Java 2023年5月29日
    081
  • k8s v-1.20版本部署详细过程[实测可用无坑]

    k8s v-1.20版本部署详细过程[实测可用无坑] 1.部署环境准备 1.1 各软件版本 系统 Docker k8s Linux master 3.10.0-1160.el7.x…

    Java 2023年6月9日
    060
  • Python工具箱系列(四)

    上期描述了如何在Windows下安装官方的Python3.8,本期描述如何安装Anaconda。建立Python环境这个话题,为何要大费周章、不厌其烦的叙述呢,主要的原因是: 所有…

    Java 2023年6月16日
    073
  • Makfile总结

    Makefile基础以及小技巧 当我们在命令行当中输入 make的时候他的执行流程如下: make命令首先会在当前目录下面寻找makefile或者Makefile文件。 寻找到ma…

    Java 2023年6月8日
    0139
  • 多线程相关知识整理

    java内存区域和内存模型是不一样的东西,内存区域是指Jvm运行时将数据分区存储,强调对内存空间的划分。而内存模型是定义了线程和主内存之间的关系,即JVM在计算内存中的工作方式,如…

    Java 2023年6月8日
    072
  • Maven使用总结

    Maven使用总结 一、Maven的主要作用 Maven 翻译为”专家”、”内行”,是 Apache 下的一个纯 Java 开发的开…

    Java 2023年6月8日
    086
  • java实现空心金字塔

    前言 最近在学习java,遇到了一个经典打印题目,空心金字塔,初学者记录,根据网上教程,有一句话感觉很好,就是先把麻烦的问题转换成很多的简单问题,最后一一解决就可以了,然后先死后活…

    Java 2023年6月13日
    098
  • 选择结构-Java学习日记

    /* 选择结构: 也被称为分支结构。 选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个,所以产生选择,按照不同的选择执行不同的代码。 Java语言提…

    Java 2023年6月5日
    071
  • 枚举.Java学习

    今天复习一下Java里面的 枚举 。 枚举简介 使用enum关键字开发一个枚举类的时候,这个类会默认继承Enum系统类。而且是一个final类。 当多个枚举存在时候。需要逗号分隔,…

    Java 2023年6月9日
    052
  • HTML5笔记:跨域通讯、多线程、本地存储和多图片上传技术

    最近做项目在前端我使用了很多新技术,这些技术有bootstrap、angularjs,不过最让我兴奋的还是使用了HTML5的技术,今天我想总结一些HTML5的技术,好记性不如烂笔头…

    Java 2023年5月29日
    093
  • 从Go编程看IO多路复用Epoll

    IO多路复用使得一个线程就可就可以处理多个网络连接,无需要创建多个线程来处理多个socket连接,减少不必要的资源开销,但是Select还是Poll、Epoll模式都有着不同的区别…

    Java 2023年6月16日
    070
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球