HDFS文件系统

一. HDFS概述

1. HDFS 概念
       HDFS,它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。HDFS 的设计适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。

2. HDFS优缺点

    优点:

   1)高容错性
      (1)数据自动保存多个副本。它通过增加副本的形式,提高容错性。
      (2)某一个副本丢失以后,它可以自动恢复。

   2)适合大数据处理
      (1)数据规模:能够处理数据规模达到 GB、TB、甚至 PB 级别的数据。
      (2)文件规模:能够处理百万规模以上的文件数量,数量相当之大。
   3)流式数据访问
      (1)一次写入,多次读取,不能修改,只能追加。

      (2)它能保证数据的一致性。

    4)可构建在廉价机器上,通过多副本机制,提高可靠性。

     缺点:

  1)不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
  2)无法高效的对大量小文件进行存储
     (1)存储大量小文件的话,它会占用 NameNode 大量的内存来存储文件、目录和块信息。这样是不可取的,因为 NameNode 的内存总是有限的。
     (2)小文件存储的寻址时间会超过读取时间,它违反了 HDFS 的设计目标。

 

3. HDFS架构

 

 

       这种架构主要由四个部分组成,分别为 HDFS Client、NameNode、DataNode 和 SecondaryNameNode。下面我们分别介绍这四个组成部分。

1)Client:就是客户端。
(1)文件切分。文件上传 HDFS 的时候,Client 将文件切分成一个一个的 Block,然后进行存储。

(2)与 NameNode 交互,获取文件的位置信息。
(3)与 DataNode 交互,读取或者写入数据。
(4)Client 提供一些命令来管理 HDFS,比如启动或者关闭 HDFS。
(5)Client 可以通过一些命令来访问 HDFS。

2)NameNode:就是 master,它是一个主管、管理者。
(1)管理 HDFS 的名称空间。
(2)管理数据块(Block)映射信息
(3)配置副本策略
(4)处理客户端读写请求。
3) DataNode:就是 Slave。NameNode 下达命令,DataNode 执行实际的操作。
(1)存储实际的数据块。
(2)执行数据块的读/写操作。
4)Secondary NameNode:并非 NameNode 的热备。当 NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。
(1)辅助 NameNode,分担其工作量。
(2)定期合并 Fsimage 和 Edits,并推送给 NameNode。
(3)在紧急情况下,可辅助恢复 NameNode。

 

4. HDFS文件块大小

        HDFS 中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在 hadoop2.x 版本中是 128M,老版本中是 64M。
        HDFS 的块比磁盘的块大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个块组成的文件的时间取决于磁盘传输速率。
如果寻址时间约为 10ms,而传输速率为 100MB/s,为了使寻址时间仅占传输时间的 1%,我们要将块大小设置约为 100MB。默认的块大小 128MB。
        块的大小:10ms*100*100M/s = 100M

5. 其他概念

1)块缓存

        通常datanode从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显式地缓存在内存中,以堆外块缓存的形式存在。默认情况下,一个块仅缓存在一个datanode的内存中,当然可以针每个文件配置datanode的数量。作业调度器(用于MapReduce、spark和其他框架的)通过在缓存块的datanode上运行任务,可以利用块缓存的优势提高读操作的性能。例如,连接join操作中使用的一个小的查询表就是块缓存的一个很好的候选。

        用户或应用通过在缓存池中增加一个cache directive来告诉namenode需要缓存哪些文件及存多久。缓存池是一个用于管理缓存权限和资源使用的管理性分组。

2)联邦HDFS
        namenode在内存中保存文件系统中每个文件和每个数据块的引用关系,这意味着对于一个拥有大量文件的超大集群来说,内存将成为限制系统横向扩展的瓶颈。在2.X发行版本系列中引入的联邦HDFS允许系统通过添加namenode实现扩展,其中每个namenode管理文件系统命名空间中的一部分。例如,一个namenode可能管理/user目录下的所有文件,而另一个namenode可能管理/share目录下的所有文件。
        在联邦环境下,每个namenode维护一个命名空间卷,由命名空间的元数据和一个数据块池(block pool)组成,数据块池包含该命名空间下文件的所有数据块。命名空间卷之间是相互独立的,两两之间并不相互通信,甚至其中一个namenode的失效也不会影响由其他namenode维护的命名空间的可用性。数据块池不再进行切分,因此集群中的datanode需要注册到每个namenode,并且存储着来自多个数据块池中的数据块。
        要想访问联邦HDFS集群,客户端需要使用客户端挂载数据表将文件路径映射到namenode。

二.HDFS的数据流

2.1 HDFS 写数据流程

2.1.1 读流程剖析

1)客户端通过 DistributedFileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是Distributed FileSystem的一个实例(图中的步骤1)DistributedFileSystem通过使用远程过程调用(RPC)来调用namenode,以确定文件起始块的位置(步骤2)。对于每一个块,namenode返回存有该块副本的datanode地址。此外,这些datanode根据它们与客户端的距离来排序(根据集群的网络拓扑)。如果该客户端本身就是一个datanode(比如,在一个mapreduce任务中),那么该客户端将会从保存有相应数据块复本的本地datanode读取数据。

2)  DistributedFileSystem类返回一个FSDataInputStream对象(一个支持文件定位的输入流)给客户端以便读取数据。FSDataInputstream类转而封装DFSInputStream对象,该对象管理着datanode和namenode的I/O。

3)接着,客户端对这个输入流调用read()方法(步骤3)。存储着文件起始几个块的datanode地址的DFSInputStream随即连接距离最近的文件中第一个块所在的datanode。通过对数据流反复调用read()方法,可以将数据从datanode传输到客户端(步骤4)。到达块的末端时,DFSInputStream关闭与该datanode的连接,然后寻找下一个块的最佳datanode(步骤5)。所有这些对于客户端都是透明的,在客户看来它一直在读取一个连续的流。

4)客户端从流中读取数据时,块是按照打开DFSInputstreanm与datanode新建连接的顺序读取的。它也会根据需要询namenode来检索下一批数据块的datanode的位置。一旦客户端完成读取,就对FSDataInputStream调用close()方法(步骤6)。

5)在读取数据的时候,如果DFSInputStream在与datanode通信时遇到错误,会尝试从这个块的另外一个最邻近datanode读取数据。它也记住那个故障datanode,以保证以后不会反复读取该节点上后续的块。DFSInputstream也会通过校验和确认从datanode发来的数据是否完整。如果发现有损坏的块,DFSInputStream会试图从其他读取其复本,也会将被损坏的块通知给namenode。

6)这个设计的一个重点是,客户端可以直接连接到datanode检索数据,且namenode告知客户端每个块所在的最佳datanode,由于数据流分散在集群中的所有datanode,所以这种设计能使HDFS扩展到大量的并发客户端。同时,namenode只需要响应块位置的请求(这些信息存储在内存中,因而非常高效),无需响应数据请求,否则随着客户端数量的增长,namenode会很快成为瓶颈。

2.1.2 机架感知(副本节点选择)

1)低版本 Hadoop 副本节点选择
第一个副本在 client 所处的节点上。如果客户端在集群外,随机选一个。
第二个副本和第一个副本位于不相同机架的随机节点上。
第三个副本和第二个副本位于相同机架,节点随机。

2)Hadoop2.7.2 副本节点选择
第一个副本在 client 所处的节点上。如果客户端在集群外,随机选一个。
第二个副本和第一个副本位于相同机架,随机节点。
第三个副本位于不同机架,随机节点。

3)HDFS 如何控制客户端读取哪个副本节点数据
HDFS 满足客户端访问副本数据的最近原则。即客户端距离哪个副本数据最近,HDFS就让哪个节点把数据给客户端。

 

2.2  HDFS 写数据流程

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

2)在客户端写入数据时(步骤3),DFSOutputStream将它分成一个个的数据包,并写入内部队列,称为“数据队列”(dataqgueue)。Datastreamer处理数据队列,它的责任是挑选出适合存储数据复本的一组datanode,并据此来要求namenode分配新的数据块。这一组构成一个管线一我们假设复本数为3,所以管线中有3个节点。Datastreamer将数据包流式传输到管线中第1个datanode,该
datanode存储数据包并将它发送到管线中的第2个datanode。同样,第2个datanode存储该数据包并且发送给管线中的第3个(也是最后一个)datanode(步骤4)。

3)DFSOutputStream也维护者一个内部数据包队列来等待datanode的收到确认回复,称为“确认队列”。收到管道中所有datanode确认信息后,该数据包才会从确认队列删除(步骤5).

4)如果任何datanode在数据写入期间发生故障,则执行以下操作(对写入数据的客户端是透明的)。首先关闭管线,确认把队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包。为存储在另一正常datanode的当前数据块指定一个新的标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块。从管线中删除故障datanode,基于两个正常datanode构建一条新管线。余下的数据块写入管线中正常的datanode。namenode注意到块复本量不足时,会在另一个节点上创建一个新的复本。后续的数据块继续正常接受处理。

5)在一个块被写入期间可能会有多个datanode同时发生故障,但非常少见。只要写入了dfs.namenode.replication.min的复本数(默认为1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数(dfs.replication的默认值为3)。

6)客户端完成数据的导入后,对数据流调用close()方法(步骤6)。该操作将剩余的所有数据包写入datanode管线,并在联系到namenode告知其文件写入完成之前,等待确认(步骤7)。namenode已经知道文件由哪些块组成(因为Datastreamer请求分配数据块),所以它在返回成功前只需等待数据块进行最小量的复制。
 

三. NameNode 工作机制

3.1 NameNode&Secondary NameNode 工作机制

1)第一阶段:namenode 启动
(1)第一次启动 namenode 格式化后,创建 fsimage 和 edits 文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)namenode 记录操作日志,更新滚动日志。
(4)namenode 在内存中对数据进行增删改查。
2)第二阶段:Secondary NameNode 工作
(1)Secondary NameNode 询问 namenode 是否需要 checkpoint。直接带回 namenode 是否检查结果。
(2)Secondary NameNode 请求执行 checkpoint。
(3)namenode 滚动正在写的 edits 日志。
(4)将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode。
(5)Secondary NameNode 加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件 fsimage.chkpoint。
(7)拷贝 fsimage.chkpoint 到 namenode。
(8)namenode 将 fsimage.chkpoint 重新命名成 fsimage。

3.2 镜像文件和编辑日志文件

      namenode 被格式化之后,将在/opt/module/hadoop-2.7.2/data/tmp/dfs/name/current 目录中产生如下文件

(1)Fsimage 文件:HDFS 文件系统元数据的一个永久性的检查点,其中包含 HDFS文件系统的所有目录和文件 idnode 的序列化信息。
(2)Edits 文件:存放 HDFS 文件系统的所有更新操作的路径,文件系统客户端执行的所有写操作首先会被记录到 edits 文件中。
(3)seen_txid 文件保存的是一个数字,就是最后一个 edits_的数字
(4)每次 Namenode 启动的时候都会将 fsimage 文件读入内存,并从 00001 开始到 seen_txid 中记录的数字依次执行每个edits 里面的更新操作,保证内存中的元数据信息是最新的、同步的,可以看成 Namenode 启动的时候就将 fsimage 和 edits 文件进行了合并。

3.3 SecondaryNameNode 目录结构

      Secondary NameNode 用来监控 HDFS 状态的辅助后台程序,每隔一段时间获取 HDFS元数据的快照。

SecondaryNameNode 的 namesecondary/current 目录和主 namenode 的 current 目录的布局相同。
好 处 : 在 主 namenode 发 生 故 障 时 ( 假 设 没 有 及 时 备 份 数 据 ) , 可 以 从SecondaryNameNode 恢复数据。


3.4 Namenode 故障处理方法

Namenode 故障后,可以采用如下两种方法恢复数据。
方法一:将 SecondaryNameNode 中数据拷贝到 namenode 存储数据的目录;
方法二: 使 用 -importCheckpoint 选 项 启 动 namenode 守 护 进 程 , 从 而 将SecondaryNameNode 中数据拷贝到 namenode 目录中。

 

四. DataNode 工作机制

4.1 DataNode 工作机制

1)一个数据块在 datanode 上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。
2)DataNode 启动后向 namenode 注册,通过后,周期性(1 小时)的向 namenode 上报所有的块信息。
3)心跳是每 3 秒一次,心跳返回结果带有 namenode 给该 datanode 的命令如复制块数据到另一台机器,或删除某个数据块。如果超过 10 分钟没有收到某个 datanode 的心跳,则认为该节点不可用。
4)集群运行中可以安全加入和退出一些机器

 

4.2 数据完整性
1)当 DataNode 读取 block 的时候,它会计算 checksum
2)如果计算后的 checksum,与 block 创建时值不一样,说明 block 已经损坏。
3)client 读取其他 DataNode 上的 block。
4)datanode 在其文件创建后周期验证 checksum

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值