Hadoop-02

  1. 1. HDFS分布式文件系统
    1. 1.1. HDFS的简介
      1. 1.1.1. HDFS的演变
      2. 1.1.2. HDFS的基本概念
      3. 1.1.3. HDFS的特点
    2. 1.2. HDFS的架构和原理
      1. 1.2.1. HDFS存储架构
      2. 1.2.2. HDFS文件读写原理
        1. 1.2.2.1. HDFS写数据原理
        2. 1.2.2.2. HDFS读数据原理
        3. 1.2.2.3. HDFS读数据原理–网络拓扑-节点距离计算
        4. 1.2.2.4. HDFS数据错误与恢复
          1. 1.2.2.4.1. 名称节点出错
          2. 1.2.2.4.2. 数据节点出错
          3. 1.2.2.4.3. 数据出错
    3. 1.3. HDFS的Shell操作
      1. 1.3.1. HDFS Shell介绍
    4. 1.4. HDFS的Java API操作
      1. 1.4.1. HDFS Java API介绍

HDFS分布式文件系统

HDFS的简介

Hadoop的核心是HDFS和MapReduce。其中,HDFS是解决海量大数据文件存储的问题,是目前应用最广泛的分布式文件系统。

HDFS的演变

HDFS 源于 Google 在2003年10月份发表的GFS(Google File System)论文

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

HDFS的基本概念

HDFS(Hadoop Distributed Filesystem)是一个易于扩展的分布式文件系统,运行在成百上千台低成本的机器上。它与现有的分布式文件系统有许多相似之处,都是用来存储数据的系统工具,而区别于HDFS具有高度容错能力,旨在部署在低成本机器上。HDFS主要用于对海量文件信息进行存储和管理,也就是解决大数据文件(如TB乃至PB级)的存储问题。HDFS只是分布式文件管理系统中的一种。

  1. NameNode(名称节点)
    NameNode是HDFS集群的主服务器,通常称为名称节点或者主节点。一旦NameNode关闭,就无法访问Hadoop集群。NameNode主要以元数据的形式进行管理和存储,用于维护文件系统名称并管理客户端对文件的访问;NameNode记录对文件系统名称空间或其属性的任何更改操作;HDFS负责整个数据集群的管理,并且在配置文件中可以设置备份数量,这些信息都由NameNode存储。

  2. DataNode(数据节点)
    DataNode是HDFS集群中的从服务器,通常称为数据节点。文件系统存储文件的方式是将文件切分成多个数据块,这些数据块实际上是存储在DataNode节点中的,因此DataNode机器需要配置大量磁盘空间。它与NameNode保持不断的通信,DataNode在客户端或者NameNode的调度下,存储并检索数据块,对数据块进行创建、删除等操作,并且定期向NameNode发送所存储的数据块列表。

  3. Block(数据块)
    每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位,HDFS同样也有块(block)的概念,它是抽象的块,而非整个文件作为存储单元,在Hadoop2.x版本下,默认大小是128M,且备份3份,每个块尽可能地存储于不同的DataNode中。按块存储的好处主要是屏蔽了文件的大小,提供数据的容错性和可用性。
    ps:HDFS的块设置太小,会增加寻址时间,程序一直在 找块的开始位置;
    pss:如果块设置的太大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。导致程序在处理这块数据时,会非常慢。
    总结: HDFS块的大小设置主要取决于磁盘传输速率。

  4. Rack(机架)
    Rack是用来存放部署Hadoop集群服务器的机架,不同机架之间的节点通过交换机通信,HDFS通过机架感知策略,使NameNode能够确定每个DataNode所属的机架ID,使用副本存放策略,来改进数据的可靠性、可用性和网络带宽的利用率。

  5. Metadata(元数据)
    元数据从类型上分可分三种信息形式,一是维护HDFS文件系统中文件和目录的信息,例如文件名、目录名、父目录信息、文件大小、创建时间、修改时间等;二是记录文件内容存储相关信息,例如文件分块情况、副本个数、每个副本所在的DataNode信息等;三是用来记录HDFS中所有DataNode的信息,用于DataNode管理。

  6. Client(客户端)
    文件切分。文件上传HDFS的时候,Client将文件切分成一 个-个的Block,然后进行上传;
    与NameNode交互,获取文件的位置信息;
    与DataNode交互,读取或者写入数据;
    Client提供-些命令来管理HDFS,比如NameNode格式化;
    Client可以通过一-些命 令来访问HDFS,比如对HDFS增删查改操作;

HDFS的特点

  • 优点:高容错,流式数据访问,支持超大文件,高数据吞吐量
  • 缺点:高延迟,不适合小文件,不适合并发写入

HDFS的架构和原理

HDFS存储架构

  • HDFS采用主从架构(Master/Slave架构)。
  • HDFS集群是由一个NameNode和多个的 DataNode组成。
  • 名称节点作为中心服务器,负责管理文件系统的命名空间及客户端对文件的访问。集群中的数据节点一般是一个节点运行一个数据节点进程,负责处理文件系统客户端的读/写请求,在名称节点的统一调度下进行数据块的创建、删除和复制等操作。每个数据节点的数据实际上是保存在本地Linux文件系统中的
  • HDFS是一个部署在集群上的分布式文件系统,因此,很多数据需要通过网络进行传输
  • 所有的HDFS通信协议都是构建在TCP/IP协议基础之上的
  • 客户端通过一个可配置的端口向名称节点主动发起TCP连接,并使用客户端协议与名称节点进行交互
  • 名称节点和数据节点之间则使用数据节点协议进行交互
  • 客户端与数据节点的交互是通过RPC(Remote Procedure Call)来实现的。在设计上,名称节点不会主动发起RPC,而是响应来自客户端和数据节点的RPC请求
  • HDFS只设置唯一一个名称节点,这样做虽然大大简化了系统设计,但也带来了一些明显的局限性,具体如下:
    (1)命名空间的限制:名称节点是保存在内存中的,因此,名称节点能够容纳的对象(文件、块)的个数会受到内存空间大小的限制。
    (2)性能的瓶颈:整个分布式文件系统的吞吐量,受限于单个名称节点的吞吐量。
    (3)隔离问题:由于集群中只有一个名称节点,只有一个命名空间,因此,无法对不同应用程序进行隔离。
    (4)集群的可用性:一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。

在HDFS中,名称节点(NameNode)负责管理分布式文件系统的命名空间(Namespace),保存了两个核心的数据结构,即FsImage和EditLog
FsImage用于维护文件系统树以及文件树中所有的文件和文件夹的元数据
操作日志文件EditLog中记录了所有针对文件的创建、删除、重命名等操作
名称节点记录了每个文件中各个块所在的数据节点的位置信息

FsImage文件包含文件系统中所有目录和文件inode的序列化形式。每个inode是一个文件或目录的元数据的内部表示,并包含此类信息:文件的复制等级、修改和访问时间、访问权限、块大小以及组成文件的块。对于目录,则存储修改时间、权限和配额元数据
FsImage 地址:/usr/local/hadoop/tmp/dfs/name

在名称节点启动的时候,它会将FsImage文件中的内容加载到内存中,之后再执行EditLog文件中的各项操作,使得内存中的元数据和实际的同步,存在内存中的元数据支持客户端的读操作。

一旦在内存中成功建立文件系统元数据的映射,则创建一个新的FsImage文件和一个空的EditLog文件

名称节点起来之后,HDFS中的更新操作会重新写到EditLog文件中,因为FsImage文件一般都很大(GB级别的很常见),如果所有的更新操作都往FsImage文件中添加,这样会导致系统运行的十分缓慢,但是,如果往EditLog文件里面写就不会这样,因为EditLog 要小很多。每次执行写操作之后,且在向客户端发送成功代码之前,edits文件都需要同步更新

在名称节点运行期间,HDFS的所有更新操作都是直接写到EditLog中,久而久之, EditLog文件将会变得很大

虽然这对名称节点运行时候是没有什么明显影响的,但是,当名称节点重启的时候,名称节点需要先将FsImage里面的所有内容映像到内存中,然后再一条一条地执行EditLog中的记录,当EditLog文件非常大的时候,会导致名称节点启动操作非常慢,而在这段时间内HDFS系统处于安全模式,一直无法对外提供写操作,影响了用户的使用

第二名称节点是HDFS架构中的一个组成部分,它是用来保存名称节点中对HDFS 元数据信息的备份,并减少名称节点重启的时间。SecondaryNameNode一般是单独运行在一台机器上

SecondaryNameNode的工作情况:
(1)SecondaryNameNode会定期和NameNode通信,请求其停止使用EditLog文件,暂时将新的写操作写到一个新的文件edit.new上来,这个操作是瞬间完成,上层写日志的函数完全感觉不到差别;
(2)SecondaryNameNode通过HTTP GET方式从NameNode上获取到FsImage和EditLog文件,并下载到本地的相应目录下;
(3)SecondaryNameNode将下载下来的FsImage载入到内存,然后一条一条地执行EditLog文件中的各项更新操作,使得内存中的FsImage保持最新;这个过程就是EditLog和FsImage文件合并;
(4)SecondaryNameNode执行完(3)操作之后,会通过post方式将新的FsImage文件发送到NameNode节点上
(5)NameNode将从SecondaryNameNode接收到的新的FsImage替换旧的FsImage文件,同时将edit.new替换EditLog文件,通过这个过程EditLog就变小了

  • 数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表

  • 每个数据节点中的数据会被保存在各自节点的本地Linux文件系统中

作为一个分布式文件系统,为了保证系统的容错性和可用性,HDFS采用了多副本方式对数据进行冗余存储,通常一个数据块的多个副本会被分布到不同的数据节点上,如图3-5所示,数据块1被分别存放到数据节点A和C上,数据块2被存放在数据节点A和B上。这种多副本方式具有以下几个优点:
(1)加快数据传输速度
(2)容易检查数据错误
(3)保证数据可靠性

HDFS文件读写原理

HDFS写数据原理

Client从HDFS中存储数据,即为Write(写)数据。

  1. 客户端发起文件上传请求,通过RPC(远程过程调用)与NameNode建立通讯
  2. NameNode检查元数据文件的系统目录树
  3. 若系统目录树的父目录不存在该文件相关信息,返回客户端可以上传文件
  4. 客户端请求上传第一个Block数据块以及数据块副本的数量
  5. NameNode检测元数据文件中DataNode信息池,找到可用的数据节点
  6. NameNode检查元数据文件的系统目录树
  7. 若系统目录树的父目录不存在该文件相关信息,返回客户端可以上传文件
  8. DataNode之间建立Pipeline后,逐个返回建立完毕信息
  9. 客户端与DataNode建立数据传输流,开始发送数据包
  10. 客户端向DataNode_01上传第一个Block数据块,当DataNode_01收到一个Packet就会传给DataNode_02,DataNode_02传给DataNode_03,DataNode_01每传送一个Packet都会放入一个应答队列等待应答。
  11. 数据被分割成一个个Packet数据包在Pipeline上依次传输,而在Pipeline反方向上,将逐个发送Ack,最终由Pipeline中第一个DataNode节点DataNode_01将Pipeline的 Ack信息发送给客户端。
  12. DataNode返回给客户端,第一个Block块传输完成。客户端则会再次请求NameNode上传第二个Block块和第三块到服务器上,重复上面的步骤,直到3个Block都上传完毕。

HDFS读数据原理

从HDFS中查找数据,即为Read(读)数据。

  1. 客户端向NameNode发起RPC请求,来获取请求文件Block数据块所在的位置。
  2. NameNode检测元数据文件,会视情况返回Block块信息或者全部Block块信息,对于每个Block块,NameNode都会返回含有该Block副本的DataNode地址。
  3. 客户端会选取排序靠前的DataNode来依次读取Block块,每一个Block都会进行CheckSum若文件不完整,则客户端会继续向NameNode获取下一批的Block列表,直到验证读取出来文件是完整的,则Block读取完毕。
  4. 客户端会把最终读取出来所有的Block块合并成一个完整的最终文件(例如:1.txt)。

HDFS读数据原理–网络拓扑-节点距离计算

在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据。那么这个最近距离怎么计算呢?
节点距离:两个节点到达最近的共同祖先的距离总和。

HDFS数据错误与恢复

HDFS具有较高的容错性,可以兼容廉价的硬件,它把硬件出错看作一种常态,而不是异常,并设计了相应的机制检测数据错误和进行自动恢复,主要包括以下几种情形:名称节点出错、数据节点出错和数据出错。

名称节点出错

名称节点保存了所有的元数据信息,其中,最核心的两大数据结构是FsImage和Editlog,如果这两个文件发生损坏,那么整个HDFS实例将失效。因此,HDFS设置了备份机制,把这些核心文件同步复制到备份服务器SecondaryNameNode上。当名称节点出错时,就可以根据备份服务器SecondaryNameNode中的FsImage和Editlog数据进行恢复。

数据节点出错

每个数据节点会定期向名称节点发送“心跳”信息,向名称节点报告自己的状态

当数据节点发生故障,或者网络发生断网时,名称节点就无法收到来自一些数据节点的心跳信息,这时,这些数据节点就会被标记为“宕机”,节点上面的所有数据都会被标记为“不可读”,名称节点不会再给它们发送任何I/O请求

这时,有可能出现一种情形,即由于一些数据节点的不可用,会导致一些数据块的副本数量小于冗余因子

名称节点会定期检查这种情况,一旦发现某个数据块的副本数量小于冗余因子,就会启动数据冗余复制,为它生成新的副本

HDFS和其它分布式文件系统的最大区别就是可以调整冗余数据的位置

数据出错

网络传输和磁盘错误等因素,都会造成数据错误

客户端在读取到数据后,会采用md5和sha1对数据块进行校验,以确定读取到正确的数据

在文件被创建时,客户端就会对每一个文件块进行信息摘录,并把这些信息写入到同一个路径的隐藏文件里面

当客户端读取文件的时候,会先读取该信息文件,然后,利用该信息文件对每个读取的数据块进行校验,如果校验出错,客户端就会请求到另外一个数据节点读取该文件块,并且向名称节点报告这个文件块有错误,名称节点会定期检查并且重新复制这个块

HDFS的Shell操作

HDFS Shell介绍

Shell在计算机科学中俗称“壳”,是提供给使用者使用界面的进行与系统交互的软件,通过接收用户输入的命令执行相应的操作,Shell分为图形界面Shell和命令行式Shell。

文件系统(FS)Shell包含了各种的类Shell的命令,可以直接与Hadoop分布式文件系统以及其他文件系统进行交互。

命令参数 功能描述
-ls 查看指定路径的目录结构
-du 统计目录下所有文件大小
-mv 移动文件
-cp 复制文件
-rm 删除文件/空白文件夹
-cat 查看文件内容
-text 源文件输出为文本格式
-mkdir 创建空白文件夹
-put 上传文件
-help 删除文件/空白文件夹

常用命令:
(0)启动Hadoop集群(方便后续的测试)
sbin/start-dfs.sh
sbin/start-yarn.sh
(1)-help:输出这个命令参数
hadoop fs -help rm
(2)-ls: 显示目录信息
hadoop fs -ls /
(3)-mkdir:在HDFS上创建目录
hadoop fs -mkdir -p /sanguo/shuguo
(4)-moveFromLocal:从本地剪切粘贴到HDFS
hadoop fs -moveFromLocal ./kongming.txt /sanguo/shuguo
(5)-appendToFile:追加一个文件到已经存在的文件末尾
hadoop fs -appendToFile liubei.txt /sanguo/shuguo/kongming.txt
(6)-cat:显示文件内容
hadoop fs -cat /sanguo/shuguo/kongming.txt
(7)-chgrp 、-chmod、-chown:Linux文件系统中的用法一样,修改文件所属权限
hadoop fs -chmod 666 /sanguo/shuguo/kongming.txt
hadoop fs -chown atguigu:atguigu /sanguo/shuguo/kongming.txt
(8)-copyFromLocal:从本地文件系统中拷贝文件到HDFS路径去
hadoop fs -copyFromLocal README.txt /
(9)-copyToLocal:从HDFS拷贝到本地
(10)-cp :从HDFS的一个路径拷贝到HDFS的另一个路径
hadoop fs -cp /sanguo/shuguo/kongming.txt /zhuge.txt
(11)-mv:在HDFS目录中移动文件
hadoop fs -mv /zhuge.txt /sanguo/shuguo/
(12)-get:等同于copyToLocal,就是从HDFS下载文件到本地
hadoop fs -get /sanguo/shuguo/kongming.txt ./
(13)-getmerge:合并下载多个文件,比如HDFS的目录 /user/atguigu/test下有多个文件:log.1, log.2,log.3,…
hadoop fs -getmerge /user/atguigu/test/* ./zaiyiqi.txt
(14)-put:等同于copyFromLocal
hadoop fs -put ./zaiyiqi.txt /user/atguigu/test/
(15)-tail:显示一个文件的末尾
hadoop fs -tail /sanguo/shuguo/kongming.txt
(16)-rm:删除文件或文件夹
hadoop fs -rm /user/atguigu/test/jinlian2.txt
(17)-rmdir:删除空目录
hadoop fs -mkdir /test
hadoop fs -rmdir /test

HDFS的Java API操作

HDFS Java API介绍

由于Hadoop是使用Java语言编写的,因此可以使用Java API操作Hadoop文件系统。HDFS Shell本质上就是对Java API的应用,通过编程的形式操作HDFS,其核心是使用HDFS提供的Java API构造一个访问客户端对象,然后通过客户端对象对HDFS上的文件进行操作(增、删、改、查)。

包名 功能描述
org.apache.hadoop.fs.FileSystem 它是通用文件系统的抽象基类,可以被分布式文件系统继承,它具有许多实现类
org.apache.hadoop.fs.FileStatus 它用于向客户端展示系统中文件和目录的元数据
org.apache.hadoop.fs.FSDataInputStream 文件输入流,用于读取Hadoop文件
org.apache.hadoop.fs.FSDataOutputStream 文件输出流,用于写Hadoop文件
org.apache.hadoop.conf.Configuration 访问配置项,默认配置参数在core-site.xml中
org.apache.hadoop.fs.Path 表示Hadoop文件系统中的一个文件或者一个目录的路径

在Java中操作HDFS,创建一个客户端实例主要涉及以下两个类:
Configuration:该类的对象封装了客户端或者服务器的配置,Configuration实例会自动加载HDFS的配置文件core-site.xml,从中获取Hadoop集群的配置信息。
FileSystem:该类的对象是一个文件系统对象。

方法名 功能描述
copyFromLocalFile(Path src,Path dst) 类从本地磁盘复制文件到HDFS
copyToLocalFile(Path src,Path dst) 从HDFS复制文件到本地磁盘
mkdirs(Path f) 建立子目录
rename(Path src,Path dst) 重命名文件或文件夹
delete(Path f) 删除指定文件