Hadoop HDFS的主要架构与读写文件

Posted 晓之以理的喵~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hadoop HDFS的主要架构与读写文件相关的知识,希望对你有一定的参考价值。

一、Hadoop HDFS的架构

HDFS:Hadoop Distributed File System,分布式文件系统

1,NameNode

  1. 存储文件的metadata,运行时所有数据都保存到内存,整个HDFS可存储的文件数受限于NameNode的内存大小
  2. 一个Block在NameNode中对应一条记录(一般一个block占用150字节),如果是大量的小文件,会消耗大量内存。同时map task的数量是由splits来决定的,所以用MapReduce处理大量的小文件时,就会产生过多的map task,线程管理开销将会增加作业时间。处理大量小文件的速度远远小于处理同等大小的大文件的速度。因此Hadoop建议存储大文件
  3. 数据会定时保存到本地磁盘,但不保存block的位置信息,而是由DataNode注册时上报和运行时维护(NameNode中与DataNode相关的信息并不保存到NameNode的文件系统中,而是NameNode每次重启后,动态重建)
  4. NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性

2,Secondary NameNode

定时与NameNode进行同步(定期合并文件系统镜像和编辑日志,然后把合并后的传给NameNode,替换其镜像,并清空编辑日志,类似于CheckPoint机制),但NameNode失效后仍需要手工将其设置成主机.

3,DataNode

  1. 保存具体的block数据
  2. 负责数据的读写操作和复制操作
  3. DataNode启动时会向NameNode报告当前存储的数据块信息,后续也会定时报告修改信息
  4. DataNode之间会进行通信,复制数据块,保证数据的冗余性

4,Block数据块

  1. 基本存储单位,一般大小为64M(配置大的块主要是因为:
    1)减少搜寻时间,一般硬盘传输速率比寻道时间要快,大的块可以减少寻道时间;
    2)减少管理块的数据开销,每个块都需要在NameNode上有对应的记录;
    3)对数据块进行读写,减少建立网络的连接成本)
  2. 一个大文件会被拆分成一个个的块,然后存储于不同的机器。如果一个文件少于Block大小,那么实际占用的空间为其文件的大小
  3. 基本的读写单位,类似于磁盘的页,每次都是读写一个块
  4. 每个块都会被复制到多台机器,默认复制3份
  5. HDFS2.x以后的block默认128M

二、Hadoop 读文件


1,客户端向NameNode发送读取请求
2,NameNode返回文件的所有block和这些block所在的DataNodes(包括复制节点)
3,客户端直接从DataNode中读取数据,如果该DataNode读取失败(DataNode失效或校验码不对),则从复制节点中读取(如果读取的数据就在本机,则直接读取,否则通过网络读取)

三、Hadoop 写文件

1,客户端将文件写入本地磁盘的 HDFS Client 文件中
2,当临时文件大小达到一个 block 大小时,HDFS client 通知 NameNode,申请写入文件
3,NameNode 在 HDFS 的文件系统中创建一个文件,并把该 block id 和要写入的 DataNode 的列表返回给客户端
4,客户端收到这些信息后,将临时文件写入 DataNodes
(1) 客户端将文件内容写入第一个 DataNode(一般以 4kb 为单位进行传输)
(2) 第一个 DataNode 接收后,将数据写入本地磁盘,同时也传输给第二个 DataNode
(3)依此类推到最后一个 DataNode,数据在 DataNode 之间是通过 pipeline 的方式进行复制的
(4)后面的 DataNode 接收完数据后,都会发送一个确认给前一个 DataNode,最终第一个 DataNode 返回确认给客户端
(5)当客户端接收到整个 block 的确认后,会向 NameNode 发送一个最终的确认信息
(6)如果写入某个 DataNode 失败,数据会继续写入其他的 DataNode。然后 NameNode 会找另外一个好的 DataNode 继续复制,以保证冗余性
(6) 每个 block 都会有一个校验码,并存放到独立的文件中,以便读的时候来验证其完整性
5,文件写完后(客户端关闭),NameNode 提交文件(这时文件才可见,如果提交前,NameNode 垮掉,那文件也就丢失了。只保证数据的信息写到 NameNode 上,但并不保证数据已经被写到DataNode 中)

大数据基石之Hadoop的读写流程与2.X架构

Hadoop读写流程与2.X架构

安全模式

集群启动时的一个状态,处于安全模式的状态下,只向客户端提供文件的只读视图

HDFS的权限

HDFS对权限的控制

  • 只能防止好人做错事
  • 不能防止坏人做坏事

你告诉他你是谁,他就认为你是谁!

机架感知策略

我们需要将副本放在不同的DN节点上,节点也需要一定的考量

  • 可靠性、可用性、带宽消耗

第一个节点

  • 集群内部(优先考虑和客户端相同节点作为第一个节点)
  • 集群外部(选择资源丰富且不繁忙的节点为第一个节点)

第二个节点

  • 选择和第一个节点不同机架的其他节点

第三个节点

  • 与第二个节点相同机架的其他节点

第N个节点

  • 与前面节点不重复的其他节点

HDFS写数据流程

宏观流程

    1. 客户端向HDFS发送写数据请求
    1. filesystem通过rpc调用namenode的create方法
    • nn首先检查是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在,权限

        1. 有:NN会针对这个文件创建一个空的Entry对象,并返回成功状态给DFS
        1. 没有:直接抛出对应的异常,给予客户端错误提示信息
  • 3.DFS如果接收到成功状态,会创建一个对象 FSDataOutputStream的对象给客户端使用

  • 4.客户端需要向NN询问第一个Block存放的位置

      1. NN通过机架感知策略 (node1 node 2 node8)
  • 5.需要将客户端和DN节点创建连接

    • pipeline(管道)

      • 客户端和node1创建连接 socket
      • node1和node2创建连接 socket
      • node2 和Node8创建连接 socket
    1. 客户端将文件按照块block切分数据,但是按照packet发送数据
    • 默认一个packet大小为64K,Block128M为2048个packet
    1. 客户端通过pipeline管道开始使用FSDataOutputStream对象将数据输出
      1. 客户端首先将一个packet发送给node1,同时给予node1一个ack状态
      1. node1接受数据后会将数据继续传递给node2,同时给予node2一个ack状态
      1. node2接受数据后会将数据继续传递给node8,同时给予node8一个ack状态
      1. node8将这个packet接受完成后,会响应这个ack给node2为true
      1. node2会响应给node1 ,同理node1响应给客户端
    1. 客户端接收到成功的状态,就认为某个packet发送成功了,直到当前块所有的packet都发送完成
    1. 如果客户端接收到最后一个pakcet的成功状态,说明当前block传输完成,管道就会被撤销
    1. 客户端会将这个消息传递给NN,NN确认传输完成
      1. NN会将block的信息记录到Entry,客户端会继续向NN询问第二个块的存储位置,依次类推
      1. block1 (node1 node2 node8)
      1. block2 (node1 node8 node9)
      1. blockn(node1 node7 node9)
    1. 当所有的block传输完成后,NN在Entry中存储所有的File与Block与DN的映射关系关闭FsDataOutPutStream

微观流程

  • 1.首先客户端从自己的硬盘以流的方式读取数据文件到自己的缓存中

  • 2.然后将缓存中的数据以chunk(512B)和checksum(4B)的方式放入到packet(64K)

      1. chunk:checksum=128:1
      1. checksum:在数据处理和数据通信领域中,用于校验目的的一组数据项的和
      1. Packet中的数据分为两类,一类是实际数据包,另一类是header包。
      1. 一个Packet数据包的组成结构
  • 3.当packet满的时候加入到 添加到 dataqueue

  • 4.datastreamer开始从dataqueue队列上取出一个packet,通过FSDataOPS发送到Pipleline

    • 在取出的时候,也会将packet加入到ackQueue,典型的生产者消费者模式
  • 5.客户端发送一个Packet数据包以后开始接收ack,会有一个用来接收ack的ResponseProcessor进程,如果收到成功的ack

      1. 如果某一个packet的ack为true,那么就从ackqueue删除掉这个packet
      1. 如果某一个packet的ack为false,将ackqueue中所有的packet重新挂载到 发送队列,重新发送
    1. 最终DFS保存的数据格式为
    • blk_ 为trunk文件
    • blk_ .mate 为checksum文件

HDFS读数据流程

首先客户端发送请求到DFS,申请读取某一个文件

DFS去NN查找这个文件的信息(权限,文件是否存在)

  • 如果文件不存在,抛出指定的错误
  • 如果文件存在,返回成功状态

DFS创建FSDataInputStream对象,客户端通过这个对象读取数据

客户端获取文件第一个Block信息,返回DN1 DN2 DN8

客户端直接就近原则选择DN1对应的数据即可

依次类推读取其他块的信息,直到最后一个块,将Block合并成一个文件

关闭FSDataInputStream

Hadoop1的困境

单点故障

  • 每个群集只有一个NameNode,NameNode存在单点故障(SPOF)

水平扩展

  • 将来服务器启动的时候,启动速度慢

namenode随着业务的增多,内存占用也会越来越多

  • 如果namenode内存占满,将无法继续提供服务

业务隔离性差

丢失inprocess

以上是关于Hadoop HDFS的主要架构与读写文件的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop-HDFS压测针对HDFS进行读写性能测试

小记---------Hadoop读写文件步骤,HDFS架构理解

大数据HDFS部署及文件读写(包含eclipse hadoop配置)

大数据基石之Hadoop的读写流程与2.X架构

1.浅析Hadoop之HDFS

hadoop学习系列(1.大数据典型特性与分布式开发难点)