设为首页 加入收藏

TOP

Hadoop学习之路(六):理解Hadoop三大组件之HDFS
2019-04-21 00:00:07 】 浏览:83
Tags:Hadoop 习之 理解 三大 组件 HDFS
版权声明:原创不易,转载请声明出处,谢谢! https://blog.csdn.net/qq_41955099/article/details/89393061

一、分布式文件系统简介

一般而言,常见的文件系统都是单机的,即数据只存储在一台机器上,读写都必须交互这台机器。当数据大小超过一台独立主机的物理存储能力时就必须将数据分区,然后存储到若干台单独计算机上。管理网络中跨多台计算机存储文件的系统称之为分布式文件系统。该系统构建于网络之上,势必会引入网络编程的复杂性,因此分布式文件系统要比普通文件系统复杂得多。

Hadoop有一个称之为HDFS的文件系统,即 Hadoop Distributed Filesystem,是一个分布式文件系统的实现,下面将介绍HDFS。

二、HDFS的设计

HDFS以流式数据访问模式来存储超大文件,运行于商用硬件集群上。
适合使用HDFS的场景:

  • 存储超大文件。超大文件是指具有几百MB、几百GB,甚至几百TB大小的文件。
  • 流式数据访问。HDFS认为一次写入多次读写是最为高效的访问模式。数据集通常由数据源不断产生,或者从数据源复制而来,接着长时间都在数据集上进行各种分析,每次都读取数据集的大部分内容甚至是全部内容,因此读取整个数据集的时延必读取第一条数据的时延更为重要。
  • 运行在廉价设备上。Hadoop并不需要运行在昂贵且高可靠的设备之上,只需运行在廉价的商用硬件上即可。

不适合使用HDFS的场景:

  • 低时间延迟的数据访问。HDFS是为高吞吐量应用优化的,这是以牺牲低时间延时访问为代价的。为此有了一个解决方案,那就是使用HBase。
  • 大量的小文件。namenode节点管理HDFS的目录树,文件系统的元信息存储在该节点上。一般而言,一个文件、目录和数据块的元信息大小为150字节,存储一百万个文件只需要花30MB空间存储元信息,但是如果有数十亿文件则就会超出namenode节点的存储能力,这时候namenode节点便成为了集群的存储瓶颈。
  • 多用户写入,任意修改文件。HDFS可能只有一个writer,而且写操作总是将数据追加到位末尾,它不支持具有多个写入者的操作。

三、HDFS的概念

1.数据块

在计算机中,数据存储在磁盘上,磁盘有默认的块大小,这是磁盘存储数据的最小单位。构建于单个磁盘之上的文件系统通过磁盘的块来管理该文件系统中的块。磁盘块大小一般是512字节,文件系统的块大小一般是磁盘块的整数倍,为几千字节。

HDFS也有块的概念,且比较大,它是HDFS存储的最小逻辑单元。在Hadoop 1.x的时候默认一个块的大小是64MB,在2.x后默认一个块的大小是128MB。在HDFS上的文件也会被分割为若干块,作为单独的存储单元,但是与其他文件系统不同的是,在HDFS中小于默认块大小的文件不会占据整个块空间。块的设计有许多好处:

  • 轻松存储超大文件。一个文件可以大于集群中任意一个存储节点的磁盘大小,因为文件会被分成若干个块分布在整个集群上被存储。
  • 简化了存储子系统的设计。其实就是简化了对于数据 的管理,在HDFS中真正存储的只是数据块,而这个数据块属于哪个文件的,权限等元数据并不会随着块被存储,所以对于存储节点而言,只要管理好自己的块就足够了。
  • 利于备份和容错。块非常适合用于数据备份而提高数据可重用能力和提高可重用性。默认情况下,一个块有三个副本,存储在三台主机上,如果其中有一台主机发生了故障,系统就会从另外两台主机的某一台处复制该块到另一台主机,使得块的副本数恢复到正常水平,这个过程对于用户而言是透明的,这也是HDFS提供可靠存储的措施之一。

2.namenode、datanode和secondarynamenode

在HDFS集群上有三类主机,即一个名称节点namenode,一个辅助名称节点secondarynamenode和多个数据节点datanode。

  • namenode管理系统的名字命名空间,维护着目录树内所有的文件和目录,这些信息以两个文件永久保存在namenode节点的磁盘上:命名空间镜像文件和编辑日志文件。namenode也记录者每个文件中各个块所在数据节点信息,但是它不会永久保存块的位置信息,因为这些信息会在系统启动时由数据节点重建。如果namenode节点损坏,则会丢失文件的元信息,所以无法根据datanode里的块重建文件,就相当于丢失了整个集群的数据。
  • datanode是HDFS数据真正存储的节点,datanode根据要求存储和检索块,并且会定期向namenode发送自己的块列表。如果HDFS所有数据节点都损坏了则该集群将无法存储数据。
  • secondarynamenode也叫辅助namenode,作用是定期融合编辑日志和命名空间镜像文件,以防止编辑日志过大。辅助namenode在不同于namenode的一台主机上运行,它会保存合并后命名空间镜像的副本,并在namenode发生故障时启用,但是辅助namenode的保存状态总是滞后于namenode,所以难免会有部分数据丢失。

3.HDFS的高可用

从上面介绍可知,namenode是HDFS的核心节点,但是存在着故障的风险,虽然可以通过辅助namenode进行恢复,但是会存在滞后性,导致数据丢失。因此在Hadoop2.x版本后针对以上问题,在HDFS中增加高可用性的支持,即 HDFS HA支持。在实现中,配置了一对活动-备用namenode(active - standby)namenode。当活动namenode失效后,备用namenode就会接管它的任务并开始于来自服务端的请求,不会有明显的中断,需要在传统的架构上做如下修改:

  • namenode之间需要通过高可用的共享存储来实现编辑日志的共享。当备用namenode接管工作后将读取全部编辑日志,恢复至与活动namenode一致的状态,并继续读取活动namenode写入的新条目。
  • datanode需要同时向两个namenode发送块处理报告,因为数据块的映射信息存在namenode的内存而非磁盘中。
  • 客户端需要使用特定的机制来处理namenode失效问题,这一机制对于用户来说是透明的。

实际上,要实现HDFS的高可用,仅凭Hadoop是没办法实现的,需要引入其它的服务,就是分布式服务协调Zookeeper,两个namenode需要在Zookeeper上注册,并且要发送心跳信息给Zookeeper,Zookeeper会在两个namenode上都启动容灾控制器,当活动的namenode发生故障时,Zookeeper会马上感知,容灾控制器会进行namenode的状态切换,将活动的namenode状态修改为standby,备用的namenode状态修改为active,备用namenode会在很短的时间内实现任务接管。

四、HDFS的常用命令

一般而言,交互HDFS有两种常用方式:使用命令交互,另一种则是使用Java的接口,即各种JavaAPI交互,使用JavaAPI内容比较多,单独出来介绍,现在介绍经常使用的命令。

1. hdfs namenode -format

这条命令用于格式化HDFS,在格式化完后namenode和datanode会产生一个clusterID,这个ID是唯一的,唯一标识该集群,如果再次格式化集群(这是一个很危险的操作),则会重新分配一个ID。

2. hdfs dfs

该命令用于直接操作HDFS上的数据,常接的参数有:

  • hdfs dfs -ls :用于列出给定路径下的文件或目录。
  • hdfs dfs -cat :用于查看给定路径下的文件内容。
  • hdfs dfs -put :用于上传一个给定本地路径下的文件到指定的HDFS路径下。
  • hdfs dfs -get:用于下载一个指定的HDFS路径下的文件到当前本地目录。
  • hdfs dfs -mkdir:用于在指定的HDFS路径下创建一个目录。
  • hdfs dfs -rm:用于删除指定HDFS路径下的文件。
  • hdfs dfs -cp:用于复制HDFS下的某个文件到另一路径下。
  • hdfs dfs -mv:用于移动HDFS下的某个文件到另一路径下。
  • hdfs dfs -chmod:用于改变指定HDFS路径下的文件权限。
  • hdfs dfs -chown:用于改变指定HDFS路径下的文件用户。
  • hdfs dfs -chgroup:用于改变指定HDFS路径下的文件用户组。

3. hdfs dfsadmin

该命令用于管理HDFS节点,常接的参数有:

  • hdfs dfsadmin -report:查看集群所有节点的状态。
  • hdfs dfsadmin -safemode:进入、退出、查看安全模式状态。
  • hdfs dfsadmin -setquota:设置HDFS中指定目录的配额。
  • hdfs dfsadmin -clrquota:删除HDFS中指定目录的配额。
  • hdfs dfsadmin -rolledits:手动滚动编辑日志。

五、HDFS的读写流程

1. HDFS的读取

在这里插入图片描述

  • 客户端通过调用FileSystem的open()方法获得DistributedFileSystem的实例。
  • DistributedFileSystem类通过RPC调用向namenode申请待读取文件的块databode地址列表。
  • DistributedFileSystem类返回一个FSDataInputStream对象给客户端,FSDataInputStream封装了DFSInputStream,该对象管理datanode与namenode的IO。
  • 客户端反复调用FSDataInputStream对象的read()方法,而DFSInputStream会调用read()方法将数据从datanode读取数据到客户端。
  • 当读完某一个块的数据后,DFSInputStream关闭客户端与该datanode的连接,然后查找并建立与下一个数据块所在datanode的连接。客户端只需读取持续的流,中间datanode的切换工作对其而言是透明的。
  • 所有块读取完成后,客户端会对FSDSataInputStream调用close()方法。

1. HDFS的写入

在这里插入图片描述

  • 客户端调用DistributedFileSystem的create()方法来创建文件。
  • DistributedFileSystem调用create()方法对namenode创建一个文件,此时该文件还没有任何数据块。
  • namenode会对新创建的文件执行各种检查,包括是否存在、权限是否合法等等,如果有一项不符合则文件创建失败并向客户端抛出一个IOExection,如果成功则会为创建新文件添加一条记录。
  • namenode检查通过后DistributedFileSystem会为客户端创建FSDataOutputStream对象,FSDataOutputStream里封装了DFSOutputStream,该对象管理datanode与namenode的IO。
  • 客户端调用FSDataOutputStream的write()写入数据时,DFSOutputStream会将其分为一个个数据包,并写进内部队列,称之为“数据队列”。DataStreamer负责处理数据队列,它的任务是根据datanode列表建立一个管线,现在假设副本数为3,则管线中有三个datanode节点,DataStreamer把数据包传送给第一个节点,第一个datanode存储数据包并将数据包发送给第二个节点,如此下去直到管线上所有的datanode都接收到了数据包。
  • DFSOutputStream内部也维护着一个数据包队列来等待datanode的“确认收到数据包”回执,称之为“确认队列”,收到管线上所有datanode的确认后,从队列删除数据包。
  • 客户端完成数据写入后,调用FSDataOutputStream的close()方法关闭,并等待最后确认。

六、总结

HDFS作为Hadoop的存储组件承担着非常之重要的任务,本文仅对HDFS的基本信息做了介绍,HDFS的内容非常之多,比如还有数据的压缩,数据的序列化,以及数据的安全保障等等,有兴趣的小伙伴可以读一下《Hadoop权威指南》这本书,本文的内容也是参考这本书。感谢您的阅读,如有错误请不吝赐教!

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Hadoop-->HDFS原理总结 下一篇sqoop   把 hdfs 和关系型数..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目