2.HDFS

  • Hadoop文件系统
  • HDFS
  • HDFS工作流程
  • HDFS数据输入输出流程分析

一、Hadoop文件系统

    Hadoop有一个抽象的文件系统概念,HDFS只是其中的一个实现。Hadoop文件系统接口由Java抽象类org.apache.hadoop.fs.FileSystem类定义。Hadoop的文件系统如下所示:
在这里插入图片描述
观察上表的多个文件系统,我们可以通过引用URI来实现对特定的文件系统的交互。使用时以HDFS使用最为常见。

二、HDFS

    整个Hadoop的体系结构主要是通过HDFS(Hadoop分布式文件系统)来实现对分布式存储的底层支持,并通过MR来实现对分布式并行任务处理的程序支持。

    HDFS是Hadoop体系中数据存储管理的基础。它是一个高度容错的系统,能检测和应对硬件故障,用于在低成本的通用硬件上运行。HDFS简化了文件的一致性模型,通过流式数据访问,提供高吞吐量应用程序数据访问功能,适合带有大型数据集的应用程序。
    Hadoop结构图解:
在这里插入图片描述
观察上图可以清晰的获取到HDFS主要的组成模块,下文将详细的介绍整个HDFS流程。

三、HDFS工作流程
    在上文不辞辛劳的写下了HDFS的内容之后,我们接下来终于要上点有意思的东西了。首先我们从HDFS的启动着手一点点的剖析整个文件系统的结构。

1.启动namenode

    namenode又叫名称节点,作用相当于书本的目录一样。用于保存文件系统的元数据镜像。ps:什么是元数据呢?简单来说一个人的身高、体重、样貌等的用来描述人本身的信息的数据就叫做元数据。所以元数据不过是一些描述信息而已。 namenode在内存及磁盘上分别存放了一份元数据镜像文件,内存中元数据镜像保证了hdfs问价系统访问效率,磁盘上的元数据镜像保证了hdfs文件系统的安全性。

    namenode有fsimage(保存文件系统至上次checkpoint(后文介绍)为止的目录和文件元数据);edits文件,保存文件系统上次checkpoint起对hdfs的所有操作记录日志信息。

    fsimage与edits存放在哪里呢?默认情况下两个文件存储在系统的/tmp文件夹下,但是这个文件夹是临时性文件,每次重启机器时都会清空这个文件夹。在hdfs中一旦这两个镜像丢失,所有的datanode就都不可用了。所以我们一般会手动设置这个存放目录。设置方法为:修改配置文件core-site.xml中的hadoop.tmp.dir,把这个配置项的值设置成自己想要的路径即可。进入存储这两个镜像文件的目录我们可以看到下图所示的内容:
在这里插入图片描述
图片中就是存储的镜像文件。

    fsimage与edits中存放的是什么呢?前文中已经阐述了存放这两个镜像文件中存放的是一些元数据。这两个文件内部的一些信息呢?这里就要来解释一下上文留下的疑问点,什么是checkpoint?fsimage:文件是文件系统元数据的一个永久性检查点,包含文件系统中的所有目录和文件idnode的序列化信息;edits:文件系统的写操作首先把它记录在edit中。

    将这两个过程分开,是为了提升内存的处理效率。如果不分开处理,即所有的写操作均记录在一个文件中,比如,fsimage中,那么每个操作都会对这个文件进行修改,因为这个文件可能会很大,所以每次进行写操作的时候就会很慢,随着fsimage越来越大,速度便会越来越低。Hadoop的解决方案是辅助Namenode(SecondaryNameNode)节点,文件系统的写操作不是直接被修改到fsimage中,而是多个edits中,辅助Namenode节点负责将两者在自己的内存中整合然后进行相应的替换操作,这样会频繁的对edits进行修改而不是fsimage,而edits文件的大小是可以接受的,而且大小也不会不断增加。具体的checkpoint执行过程如下:

  1. 辅助Namenode请求主Namenode停止使用edits文件,暂时将新的写操作记录到一个新文件中,如edits.new。
  2. 辅助Namenode节点从主Namenode节点获取fsimage和edits文件(采用HTTP GET)
  3. 辅助Namenode将fsimage文件载入到内存,逐一执行edits文件中的操作,创建新的fsimage文件
  4. 辅助Namenode将新的fsimage文件发送回主Namenode(使用HTTP POST)。
  5. 主Namenode节点将从辅助Namenode节点接收的fsimage文件替换旧的fsimage文件,用步骤1产生的edits.new文件替换旧的edits文件(即改名)。同时更新fstime文件来记录检查点执行的时间。
    在这里插入图片描述
    之前以为SecondaryNameNode是namenode的一个副本而已,现在来看理解的一点儿也不对啊,没有SNN就会使得NN从开始到关闭期间所有的操作都存到edits中,这样直接造成下一次启动时非常慢。在首次安装时要对namenode进行format的目的是什么,其实就是清空原有的镜像信息,重新构建这个文件目录结构。

    到现在终于把namenode是啥和如何记录信息的搞定了。那么回到最初的问题**启动namenode!**这个的启动我们在代码层面上简单瞅一下这个启动的过程。

  1. 初始化过程:获取一些必要的参数值,初始化FSImage,FSNameSystem,NameNode等类。这个过程在很多启动描述中都被忽略,不是很重要。需要注意的是,这个过程在recover, format和finalize几种启动时的操作略有不同。
  2. 构造Configuration对象:看对象名字就这个这个对象是用来管理配置信息的,默认取core-site.xml文件中配置信息。
  3. 构造namenode对象:这是namenode启动最重要的阶段。Namenode对象主要包括两部分,一个是Server类成员对象,第二个是FSNameSystem类成员对象。
  4. Server成员的构造:Server是namenode用于与client和datanode之间进行RPC通信的服务端。Namenode中有一个或两个Server成员,由不同的Hadoop版本决定,两个的时候分别负责和client和Datanode的通信。
  5. FSNameSystem的构造:Server构造完成后,调用namenode的initialize方法,接下来的操作都在这个方法中完成。先是构造FSNameSystem对象,FSNameSystem对象就是namenode上元数据的真正的存放数据结构。它主要包括两部分,第一部分是一些数据结构,包括:
    <1> blockMap: map,保存数据块block相关的映射关系,包括文件与块,块与datanode的映射等等
    <2>curruptReplicasMap:保存所有损坏的块。
    <3>datanodeMap:曾经连接过的所有datanode
    <4>recentInvalidateSets:最近失效的block
    <5>excessReplicateMap:机器与机器上多余的block的映射,这些block等待被删除。
    <6>Heartbeats:当前发送心跳包的datanode,也就是alive的datanode。
    第二部分是FSDirectory对象,这里存放着文件系统的层次结构。FSNameSystem对象的构造过程,首先初始化blocksMap等数据结构,然后加载fsimage文件到类FSImage中,然后读取edits文件,利用fsimage和edits构造文件系统的层次结构。
  6. 启动后台守护进程:启动一系列后台守护进程。比如监控block的复制过程啊,心跳包的检测啊,副本数量啊(如果不够就开始copy),控制多人写文件,处理datanode的退役啊等等的进程。
  7. 启动RPC Server服务和web服务:Namenode和datanode以及client之间的通信都是通过RPC方式的,下面是简单描述RPC的通信过程。
  8. 进入安全模式:amenode对象构造完成后,namenode进入安全模式,在这个阶段等待datanode的注册。为什么一定要在第3步以后呢?是因为只有RPC启动后,datanode才能与namenode进行通信,才能注册。
  9. 退出安全模式,启动成功:在等待datanode注册的过程中,namenode有一个timeout设置,等待超时后,namenode就会默认已经没有要注册的datanode了,离开安全模式。
    现在我们理解了namenode其实是个服务端,客户端可以通过服务端对文件系统进行各种操作,而服务端则不断的记录客户端操作的信息到edits文件中。namenode也更像是datanode和client间的一个桥梁。就像两个客户端的通信一样。
2.启动datanode
  1. 首先是datanode向namenode注册。datanode通过DatanodeProtocal协议进行注册,向namenode发送注册信息,包括服务地址,信息查询端口,客户端访问端口以及datanodeID等,还包括block_report块数据;namenode接收到信息后(这时的namenode处在安全模式中,等待注册),先检验datanode的版本,然后把datanode交给FSNameSystem处理;FSNameSystem先验证该datanode是否被允许挂载(通过dfs.hosts列表验证),然后把datanode数据映射到元数据中,这里主要是获取block_report块与datanode的映射关系,添加到BlocksMap中,然后再把这个datanode添加到heartsbeats中进行监控。最后返回注册信息。
  2. 启动datanode线程。Datanode线程实际上是在不断调用offerService,周期性向namenode发送block_Report和heartbeats,同时接受namenode的指令。
3.启动SNN

首先与namenode建立连接,注册到namenode,并且从namenode同步当前的fsimage,edits等文件信息;第二部分,是启动secondary namenode上用于轮训的进程,定期执行检查点的创建操作。

四、HDFS数据输入输出流程分析

1.数据读取

假设在HDFS中存储了一个文件/user/test.txt,HDFS客户端要读取该文件。

  • HDFS客户端首先要访问NameNode,并告诉它所要读取的文件。在这之前,HDFS会对客户的身份进行验证。验证的方式分为两种:一种是通过信任的客户端,由其指定用户名;第二种方式是通过诸如Kerberos等强制验证机制来完成。
  • 当文件确实存在,且该用户对其有访问权限,这时NameNode会告诉HDFS客户端这个文件的第一个数据块的标号以及保存有该数据块的DataNode列表。这个列表是DataNode与HDFS客户端的距离进行了排序。
  • 有了数据块标号和DataNode的主机名,HDFS客户端便可以直接访问最合适的DataNode,读取数据块。

2.数据写入

  • 首先HDFS客户端通过HDFS先关API发送请求,打开一个要写入的文件,如果该用户有写入文件的权限,那么这一请求将被送达NameNode,并建立该文件的元数据。但此时新建立的文件元数据并未和任何数据块相关联,这时HDFS客户端会收到“打开文件成功”的响应,接着就可以写入数据了。
  • 当客户端打开输入流时,数据会被自动拆分成数据包,并将数据保存在内存队列中。客户端有一个独立的线程,它从队列中读取数据包,并向NameNode请求一组DataNode列表,以便写入下一个数据的多个副本。
  • HDFS客户端将连接到列表中的第一个DataNode,而该DataNode又连接到第二个DataNode,第二个又连接到第三个,如此就建立了数据块的复制管道。复制管道中的每一个DataNode都会确认所收到的数据已经成功写入磁盘。
  • 当数据块被写入到列表中的DataNode时,HDFS将重新向NameNode申请下一个DataNode,最终将剩余数据全部写入磁盘

那么在写入数据时,复制管道上的一个复制块发生故障了怎么办?

如果写入过程中,复制管道上一个节点发生故障,管道会立即关闭,将已发送但未收到确认信息的数据包回退给队列,确保管道中错误节点的下游节点可以得到数据包。而在剩下的健康的DataNode中,正在写入的数据块会被重新分配ID,这样当发生故障的数据节点恢复后,其上的相关数据块会因为不属于任何文件而被自动丢弃。
NameNode如果发现文件的某个数据块正在通过复制管道进行复制,就会异步地创建一个新的复制块,这样即便HDFS的多个DataNode发生故障,HDFS客户端仍然可以从数据块的副本中回复数据。前提是满足最少数目要求的数据副本已经被正确写入。

3.数据完整性————校验和

五、HDFS新特性
namenode ha
namenode federation

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值