什么是HDFS

  1. HDFS是一个使用Java实现的、分布式的、可横向扩展的文件系统。
  2. 是Hadoop的核心组件
  3. 基于Linux/Niunx

HDFS和Hadoop的关系

Hadoop:一个分布式系统基础架构,由Apache基金会开发。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力高速运算和存储。
HDFS: Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。

简单来说Hadoop是一个分布式系统基础架构,而HDFS是Hadoop架构中的一个文件系统组件

HDFS的特点

  1. 高容错性 :认为硬件总是不可靠的
  2. 高吞吐量 :为大连数据访问的应用提供高吞吐量支持
  3. 大文件存储:支持存储TB-PB级别的数据

HDFS适合做什么?

1. 大文件存储
2. 流式数据访问

HDFS不适合做什么?

  1. 大量小文件。原因:原因:NameNode启动时,将文件系统的元数据加载到内存,因此文件系统所能存储的文件总数受限于NameNode内存容量。根据经验,每个文件,目录和数据块的存储信息大约占150字节,如果一百万个文件,且每个文件占一个数据块,那至少需要300MB的内存空间,但是如果存储十亿个文件,那么需要的内存空间将是非常大的。
    个人理解 实际数据是存放在datanode中,但是为了很快的找到数据所以就生成了一个叫元数据的数据,元数据也是一种数据,它里边记载着实际数据存放的datanode节点的地址。类似于操作系统中检索的快表机制。所以如果小文件越多,那么相对应的元数据就越多,就比较浪费存储存储。
  2. 随机写入原因:原因:现在HDFS文件只有一个writer,而且写操作总是写在文件的末尾。
  3. 低延迟读取原因:HDFS是为高数据吞吐量应用优化的,这样就会造成以高时间延迟为代价

HDFS的基本架构

hadoop和linux的关系 hadoop和hdfs的关系_hadoop

HDFS架构包含三个部分

NameNode:NameNode用于存储、生成文件系统的元数据。运行一个实例。

DataNode:DataNode用于存储实际的数据,将自己管理的数据块上报给NameNode ,运行多个实例。

Client:支持业务访问HDFS,从NameNode,DataNode获取数据返回给业务。多个实例,和业务一起运行。

个人理解
NameNode :是用来管理文件系统命名空间的组件,一个HDFS集群只有一个NameNode.

NameNode上存放了HDFS的元数据。

元数据:记载了块的实际数据存放的DateNode的位置。
元数据保存在NameNode的内存当中,一边快速查询。

一个HDFS集群只有一份元数据(因为一个HDFS集群只有一个NameNode)

块的实际数据存放在DataNode上

每个块会在本地文件系统产生两个文件,一个是实际的数据文件,另一个是块的附加信息文件,其中包括数据的校验和,生成时间

DataNode通过心跳包(Heartbeat)与NameNode通讯

客户端读取/写入数据的时候直接与DataNode通信

HDFS的机制

高可靠性:NameNode主备,集群有两个NameNode,由zookeeper进行投票选举,超过一半的为主NameNode节点,另一个自动变成备NameNode节点。

数据副本机制:存储的时候默认为三个副本 按照距离(0,2,4)把副本分发到不同节点
0是本地
2是同一机架的不同服务器
4是不同机架的服务器

元素据持久化

hadoop和linux的关系 hadoop和hdfs的关系_hadoop_02

1.主NameNode每两分钟生成新的日志文件Editlog.new,并将旧的Editlog上传至JournalNode。

2.备NameNode从主NameNode上获取FSImage文件及位于JournalNode上面的旧EditLog。

3.备NameNode将日志和旧的元数据合并,生成新的元数据FSImage.ckpt。

4.备NameNode将元数据上传到主NameNode。

5.主NameNode将上传的元数据进行回滚。
6. NameNode每隔1小时或Editlog满64MB(128M),循环步骤2-5。

hadoop和linux的关系 hadoop和hdfs的关系_分布式_03


EditLog:记录用户的操作日志,用以在FSImage的基础上生成新的文件系统镜像。

FSImage:用以阶段性保存文件镜像。

FSImage.ckpt:在内存中对fsimage文件和EditLog文件合并(merge)后产生新的fsimage,写到磁盘上,这个过程叫checkpoint.。备用NameNode加载完fsimage和EditLog文件后,会将merge后的结果同时写到本地磁盘和NFS。此时磁盘上有一份原始的fsimage文件和一份新生成的checkpoint文件:fsimage.ckpt. 而后将fsimage.ckpt改名为fsimage(覆盖原有的fsimage)。

EditLog.new: NameNode每隔1小时或Editlog满64MB就触发合并,合并时,将数据传到Standby NameNode时,因数据读写不能同步进行,此时NameNode产生一个新的日志文件
Editlog.new用来存放这段时间的操作日志。Standby NameNode合并成fsimage后回传给主NameNode替换掉原有fsimage,并将Editlog.new 命名为Editlog。

 Datanode会周期性地向主备namenode上报数据块和datanode的对应信息

HDFS数据写入流程

hadoop和linux的关系 hadoop和hdfs的关系_大数据_04


(1)客户端对DistributedFileSystem对象调用create()方法来创建文件。

(2)DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中创建一个新文件,此时该文件中还没有相应的数据块。namenode执行各种检查以确保这个文件不存在,并且客户端有创建该文件的权限。如果这些检查均通过,namenode就会为创建新文件记录一条记录;否则,创建失败,并向客户端抛出一个IOException异常。DistributedFileSystem向客户端返回一个FSDataOutputStream(文件输出流)对象,由此客户端可以开始写数据。就像读取数据一样,FSDataOutputStream封装一个DFSOutputStream(输出流)对象,该对象负责处理datanode和namenode之间的通信。

(3)在客户端写入数据时,DFSOutputStream(输出流)将他们分成一个个的数据包,并写入内部队列,成为数据队列(data queue)。

(4)DataStreamer(数据流)处理数据队列,它的责任是根据从NameNode获取到数据块编号、位置信息来存储数据。将需要写入数据的一组datanode组成一个管线—我们假设副本数量为3,所以管线中有3个节点。DataStreamer将数据包流式的传输到管线的第一个datanode,该datanode存储数据并将数据发送到管线的第二个datanode。同样的,第二个datanode存储该数据包并发送给管线中的第三个(也就是最后一个)datanode。

(5)FSOutputStream也维护着一个内部数据包队列来等待datanode的收到确认回执,成为“确认队列”(ack queue)。当管线中所有datanode确认信息后,该数据包才会从确认队列中删除。

(6)客户端完成写入后,会对数据流调用close()方法关闭文件,并联系namenode确认文件写完成。

(7)namenode已经知道文件由那些数据块组成,持久化元数据。

这概念确实很多,大致看一遍就能知道啥意思了,如果实在不想看就看下边这个简单的理解也可以。

简单理解:Client向HDFS写数据,首先要跟NameNode通信确认可以写文件并获得接收文件block的DataNode,然后,clent按顺序将文件分块之后逐个block传递给相应DataNode,并由接收block的DataNode负责向其他DataNode复制block的副本。

个人理解
(1) 客户端发送请求,调用DistributedFileSystem API的create方法去请求namenode,并告诉namenode上传文件的文件名、文件大小、文件拥有者。
(2) namenode根据以上信息算出文件需要切成多少块block,以及block要存放在哪个datanode上,并将这些信息返回给客户端。
(3) 客户端调用FSDataInputStream API的write方法首先将其中一个block写在datanode上,每一个block默认都有3个副本,并不是由客户端分别往3个datanode上写3份,而是由已经上传了block的datanode产生新的线程,由这个namenode按照放置副本规则往其它datanode写副本,这样的优势就是快。
(4) 写完后返回给客户端一个信息,然后客户端在将信息反馈给namenode。

HDFS的数据读取流程

hadoop和linux的关系 hadoop和hdfs的关系_hadoop_05


(1) 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是分布式文件系统的一个实例。

(2) DistributedFileSystem通过RPC(远程过程调用)来调用namenode,以确定文件起始块的位置。此外这些datanode根据他们与client的距离来排序。
DistributedFileSystem类返回一个FSDataInputStream对象(一个支持文件定位的输入流)给客户端并读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理着namenode和datanode的I/O。

(3) 接着客户端对这个输入流调用read()方法。 DFSInputStream随即连接存储着文件起始块的距离最近的datanode。
(4) 通过对数据流反复调用read()方法,可以将数据从datanode传输到客户端
(5) 到达块的末端时,DFSInputStream会关闭与该datanode的连接,然后寻找下一个块的最佳datanode。客户端只需连续的读取连续的流,并且对于客户端都是透明的

***数据读取流程个人理解

  1. client访问NameNode,查询元数据信息,获得这个文件的数据块位置列表,返回输入流对象。
  2. 就近挑选一台datanode服务器,请求建立输入流 。
  3. DataNode向输入流中中写数据,以packet为单位来校验。
  4. 关闭输入流

后续的有不足的地方在慢慢更改和补充。

啊~,第一次开始写呀,有什么有问题的地方麻烦各位多多指教,谢谢。