HDFS分布式文件系统

1.   HDFS概述

  • 在现代的企业环境中,单机容量往往无法存储大量数据,需要跨机器存储。统一管理分布在集群上的文件系统称为分布式文件系统
  • HDFS(Hadoop Distributed File System)是 Apache Hadoop 项目的一个子项目. Hadoop 非常适于存储大型数据 (比如 TB 和 PB), 其就是使用 HDFS 作为存储系统. HDFS 使用多台计算机存储文件, 并且提供统一的访问接口, 像是访问一个普通文件系统一样使用分布式文件系统.
  •  分布式文件系统解决的问题就是大数据存储。它们是横跨在多台计算机上的存储系统。分布式文件系统在大数据时代有着广泛的应用前景,它们为存储和处理超大规模数据提供所需的扩展能力。

 

 

 

  •  如何实现HDFS 分布式文件系统?

 

 

 

 HDFS 就是一个软件,实现将多个服务器的磁盘进行统一管理,构建出来一个更大的存储空间16T的大小,数据都是保存在每个节点上

2.   HDFS发展历史

  1. Doug Cutting 在做 Lucene 的时候, 需要编写一个爬虫服务, 这个爬虫写的并不顺利, 遇到 了一些问题, 诸如: 如何存储大规模的数据, 如何保证集群的可伸缩性, 如何动态容错等。
  2. 2003年的时候, Google 发布了三篇论文, 被称作为三驾马车, 其中有一篇叫做 GFS, 是描述了 Google 内部的一个叫做 GFS 的分布式大规模文件系统, 具有强大的可伸缩性和容错。
  3. Doug Cutting 后来根据 GFS 的论文, 创造了一个新的文件系统, 叫做 HDFS。

 

  1. 3.   HDFS设计目标

  2. 硬件故障是常态, HDFS将有成百上千的服务器组成,每一个组成部分都有可能出现故障。因此故障的检测和自动快速恢复是HDFS的核心架构目标。
  3. HDFS上的应用与一般的应用不同,它们主要是以流式读取数据。HDFS被设计成适合批量处理,而不是用户交互式的。相较于数据访问的反应时间,更注重数据访问的高吞吐量。
  4. 典型的HDFS文件大小是GB到TB的级别。所以,HDFS被调整成支持大文件。它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。
  5. 大部分HDFS应用对文件要求的是write-one-read-many访问模型。一个文件一旦创建、写入、关闭之后就不需要修改了。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。
  6. 移动计算的代价比之移动数据的代价低。一个应用请求的计算,离它操作的数据越近就越高效,这在数据达到海量级别的时候更是如此。将计算移动到数据附近,比之将数据移动到应用所在显然更好。
  7. 在异构的硬件和软件平台上的可移植性。这将推动需要大数据集的应用更广泛地采用HDFS作为平台。

4.   HDFS应用场景

4.1.    适合的应用场景

  1. 存储非常大的文件:这里非常大指的是几百M、G、或者TB级别,需要高吞吐量,对延时没有要求。
  2. 采用流式的数据访问方式: 即一次写入、多次读取,数据集经常从数据源生成或者拷贝一次,然后在其上做很多分析工作 ,且不支持文件的随机修改。
  3. 正因为如此,HDFS适合用来做大数据分析的底层存储服务,并不适合用来做.网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。
  4. 运行于商业硬件上: Hadoop不需要特别贵的机器,可运行于普通廉价机器,可以处节约成本
  5.  需要高容错性
  6.  为数据存储提供所需的扩展能力

4.2.    不适合的应用场景

  1. 低延时的数据访问 对延时要求在毫秒级别的应用,不适合采用HDFS。HDFS是为高吞吐数据传输设计的,因此可能牺牲延时
  2. 大量小文件 文件的元数据保存在NameNode的内存中, 整个文件系统的文件数量会受限于NameNode的内存大小。 经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间。如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存。因此十亿级别的文件数量在现有商用机器上难以支持。
  3. 多方读写,需要任意的文件修改 HDFS采用追加(append-only)的方式写入数据。不支持文件任意offset的修改HDFS适合用来做大数据分析的底层存储服务,并不适合用来做.网盘等应用,因为,修改不方便,延迟大,网络开销大,成本太高。

5.   HDFS的架构

  • HDFS采用Master/Slave架构,一个HDFS集群有两个重要的角色,分别是Namenode和Datanode。Namenode是管理节点,负责管理文件系统的命名空间(namespace)以及客户端对文件的访问。Datanode是实际存储数据的节点。HDFS暴露了文件系统的命名空间,用户能够以操作文件的形式在上面操作数据。
  • HDFS的四个基本组件:HDFS ClientNameNodeDataNode Secondary NameNode

 

 

 

 

1、Client就是客户端。

  • 文件切分。文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储
  • 与 NameNode 交互,获取文件的位置信息。
  • 与 DataNode 交互,读取或者写入数据。
  • Client 提供一些命令来管理 和访问HDFS,比如启动或者关闭HDFS。

2、NameNode就是 master,它是一个主管、管理者。

  • 管理 HDFS 的名称空间
  • 管理数据块(Block)映射信息
  • 配置副本策略
  • 处理客户端读写请求。

3DataNode就是Slave。NameNode 下达命令,DataNode 执行实际的操作。

  • 存储实际的数据块。
  • 执行数据块的读/写操作。

4Secondary NameNode并非 NameNode 的热备。当NameNode 挂掉的时候,它并不能马上替换 NameNode 并提供服务。

  • 辅助 NameNode,分担其工作量。
  • 定期合并 fsimage和fsedits,并推送给NameNode。
  • 在紧急情况下,可辅助恢复 NameNode。

6.   HDFS的副本机制

6.1.    HDFS文件副本机制

  • HDFS被设计成能够在一个大集群中跨机器可靠地存储超大文件。它将每个文件存储成一系列的数据块,这个数据块被称为block,除了最后一个,所有的数据块都是同样大小的。
  • 为了容错,文件的所有block都会有副本。每个文件的数据块大小和副本系数都是可配置的。
  • 所有的文件都是以 block 块的方式存放在 HDFS 文件系统当中,作用如下
  1. 一个文件有可能大于集群中任意一个磁盘,引入块机制,可以很好的解决这个问题
  2. 使用块作为文件存储的逻辑单位可以简化存储子系统
  3. 块非常适合用于数据备份进而提供数据容错能力
  4. 副本优点是安全,缺点是占空间。

 

 

  • 在 Hadoop1 当中, 文件的 block 块默认大小是 64M, hadoop2 当中, 文件的 block 块大小默认是 128M(134217728字节)。假设文件大小是100GB,从字节位置0开始,每128MB字节划分为一个block,依此类推,可以划分出很多的block。每个block就是128MB大小。
  • block块的大小可以通过 hdfs-site.xml 当中的配置文件进行指定,Hadoop默认的副本数为3,也就是每个block会存三份。

 

#修改文件的路径为
/export/server/hadoop-2.7.5/etc/hadoop/hdfs-site.xml

<!-- 设置一个文件切片的大小:128M-->
<property>
        <name>dfs.blocksize</name>
        <value>134217728</value>
</property>
<!-- 文件切片的副本个数-->
<property>
        <name>dfs.replication</name>
        <value>3</value>
</property>

 

 

注意当一个文件的大小不足128M时,比如文件大小为2M,那么这个文件也占用一个block,但是这个block实际只占2M的空间,所以从某种意义上来讲,block只是一个逻辑单位。

6.2.    HDFS副本放置策略(机架感知):

HDFS分布式文件系统的内部有一个副本存放策略,默认副本数为3,在这里以副本数=3为例:

  • 第一副本:优先放置到离写入客户端最近的DataNode节点,如果上传节点就是DataNode,则直接上传到该节点,如果是集群外提交,则随机挑选一台磁盘不太慢,CPU不太忙的节点。
  • 第二个副本:放置在与第一个同机架的不同机器中
  • 第三个副本:放置在另一个机架中, 某一个服务器中

 

 

7.   HDFS的Shell命令行使用

7.1.    Shell命令行客户端

  • HDFS是存取数据的分布式文件系统,那么对HDFS的操作,就是文件系统的基本操作,比如文件的创建、修改、删除、修改权限等,文件夹的创建、删除、重命名等。对HDFS的操作命令类似于Linux的shell对文件的操作,如ls、mkdir、rm等。

 

  • Hadoop提供了文件系统的shell命令行客户端,使用方法如下:

hadoop  fs  <args>

 

  • 文件系统shell包括与Hadoop分布式文件系统(HDFS)以及Hadoop支持的其他文件系统(如本地FS,HFTP FS,S3 FS等)直接交互的各种类似shell的命令。

 

  • 所有FS shell命令都将路径URI作为参数。URI格式为scheme://authority/path。对于HDFS,该scheme是hdfs,对于本地FS,该scheme是file。scheme和authority是可选的。如果未指定,则使用配置中指定的默认方案。

 

  • 对于HDFS,命令示例如下:

hadoop fs -ls  hdfs://namenode:host/parent/child

hadoop fs -ls  /parent/child    #hdfs-site.xml中的fs.defaultFS中有配置

 

  • 对于本地文件系统,命令示例如下:

hadoop fs -ls file:///root/

 

如果使用的文件系统是HDFS,则也可使用hdfs dfs <args>命令。

7.2.    Shell命令选项

选项名称

使用格式

含义

-ls

-ls <路径>

查看指定路径的当前目录结构

-lsr

-lsr <路径>

递归查看指定路径的目录结构

-du

-du <路径>

统计目录下个文件大小

-dus

-dus <路径>

汇总统计目录下文件(夹)大小

-count

-count [-q] <路径>

统计文件(夹)数量

-mv

-mv <源路径> <目的路径>

移动

-cp

-cp <源路径> <目的路径>

复制

-rm

-rm [-skipTrash] <路径>

删除文件/空白文件夹

-rmr

-rmr [-skipTrash] <路径>

递归删除

-put

-put <多个linux上的文件> <hdfs路径>

上传文件

-copyFromLocal

-copyFromLocal <多个linux上的文件> <hdfs路径>

从本地复制

-moveFromLocal

-moveFromLocal <多个linux上的文件> <hdfs路径>

从本地移动

-getmerge

-getmerge <源路径> <linux路径>

合并到本地

-cat

-cat <hdfs路径>

查看文件内容

-text

-text <hdfs路径>

查看文件内容

-copyToLocal

-copyToLocal [-ignoreCrc] [-crc] [hdfs源路径] [linux目的路径]

从本地复制

-moveToLocal

-moveToLocal [-crc] <hdfs源路径> <linux目的路径>

从本地移动

-mkdir

-mkdir <hdfs路径>

创建空白文件夹

-setrep

-setrep [-R] [-w] <副本数> <路径>

修改副本数量

-touchz

-touchz <文件路径>

创建空白文件

-stat

-stat [format] <路径>

显示文件统计信息

-tail

-tail [-f] <文件>

查看文件尾部信息

-chmod

-chmod [-R] <权限模式> [路径]

修改权限

-chown

-chown [-R] [属主][:[属组]] 路径

修改属主

-chgrp

-chgrp [-R] 属组名称 路径

修改属组

-help

-help [命令选项]

帮助

 

 

格式:  hadoop fs -ls  URI
作用:类似于Linux的ls命令,显示文件列表
hadoop fs -ls  /

格式  :  hdfs  dfs -lsr URI
作用  : 在整个目录下递归执行ls, 与UNIX中的ls-R类似
hdfs dfs -ls -R /

格式 : hdfs  dfs -mkdir [-p] <paths>
作用 :   以<paths>中的URI作为参数,创建目录。使用-p参数可以递归创建目录
hadoop fs -mkdir /dir1
hadoop fs -mkdir /dir2
hadoop fs -p -mkdir /aaa/bbb/ccc

格式   : hadoop fs -put <localsrc >  ... <dst>
作用 :  将单个的源文件src或者多个源文件srcs从本地文件系统拷贝到目标文件系统中(<dst>对应的路径)。也可以从标准输入中读取输入,写入目标文件系统中
echo “Hello HDFS” >> /root/1.txt
hadoop fs -put  /root/1.txt  /dir1

格式: hdfs  dfs -moveFromLocal  <localsrc>   <dst>
作用:   和put命令类似,但是源文件localsrc拷贝之后自身被删除
echo “Hello HDFS” >> /root/2.txt
hdfs  dfs -moveFromLocal  /root/2.txt  /

格式:  hadoop fs  -get [-ignorecrc ]  [-crc]  <src> <localdst>
作用:  将文件拷贝到本地文件系统。 CRC 校验失败的文件通过-ignorecrc选项拷贝。 文件和CRC校验和可以通过-CRC选项拷贝
hadoop fs  -get   /2.txt  /export/data

格式: hadoop fs -getmerge -nl  < hdfs dir >  < local file >
功能:合并下载多个文件
参数: 加上nl后,合并到local file中的hdfs文件之间会空出一行
示例:比如hdfs的目录 /aaa/下有多个文件:log.1, log.2,log.3,...
hadoop fs -getmerge  /aaa/log.*  ./log.sum

格式  : hdfs  dfs -mv URI   <dest>
作用: 将hdfs上的文件从原路径移动到目标路径(移动之后文件删除),该命令不能夸文件系统
hdfs dfs -mv /dir1/a.txt /dir2

格式: hadoop fs -rm [-r] 【-skipTrash】 URI 【URI 。。。】
作用:   删除参数指定的文件和目录,参数可以有多个,删除目录需要加-r参数
如果指定-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件;
否则,在回收站可用时,在HDFS Shell 中执行此命令,会将文件暂时放到回收站中。
hadoop fs -rm /2.txt       #删除文件
hadoop fs -rm  -r  /dir1  #删除目录

格式: hdfs  dfs  -cp URI [URI ...] <dest>
作用:将文件拷贝到目标路径中。如果<dest>  为目录的话,可以将多个文件拷贝到该目录下。
-f 选项将覆盖目标,如果它已经存在。
-p 选项将保留文件属性(时间戳、所有权、许可、ACL、XAttr)。
hadoop fs -cp /dir1/1.txt  /dir2/2.txt

hadoop fs  -cat  URI [uri  ...]
作用:将参数所指示的文件内容输出到控制台
hadoop fs  -cat  /dir2/2.txt
hadoop fs  -cat  URI 

功能:显示目录中所有文件大小,当只指定一个文件时,显示此文件的大小。
hadoop fs -du /

格式:  hadoop fs  -chmod  [-R]  URI[URI  ...]
作用: 改变文件权限。如果使用  -R 选项,则对整个目录有效递归执行。使用这一命令的用户必须是文件的所属用户,或者超级用户。
例如:可以创建一个用户hadoop,将/a.txt的所属用户和所属用户组修改为hadoop
hadoop fs -chmod -R 777 /dir1

格式: hdfs   dfs  -chmod  [-R]  URI[URI  ...]
作用:改变文件的所属用户和用户组。如果使用  -R 选项,则对整个目录有效递归执行。使用这一命令的用户必须是文件的所属用户,或者超级用户。
hadoop fs  -chown  -R hadoop:hadoop  /a.txt
 
格式: hadoop fs -appendToFile <localsrc> ... <dst>
作用: 追加一个或者多个文件到hdfs指定文件中.也可以从命令行读取输入.
cd /export/server/hadoop2.7.5/etc/hadoop/
hadoop fs -appendToFile  *.xml  /big.xml

7 hdfs 的高级命令

7.1.    HDFS的安全模式

  • 安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性。当集群启动的时候,会首先进入安全模式。当系统处于安全模式时会检查数据块的完整性。
  • 假设我们设置的副本数(即参数dfs.replication)是3,那么在datanode上就应该有3个副本存在,假设只存在2个副本,那么比例就是2/3=0.666。hdfs默认的副本率0.999。我们的副本率0.666明显小于0.999,因此系统会自动的复制副本到其他dataNode,使得副本率不小于0.999。如果系统中有5个副本,超过我们设定的3个副本,那么系统也会删除多于的2个副本。
  • 在安全模式状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。在当整个系统达到安全标准时,HDFS自动离开安全模式。

 

  • 安全模式操作命令

hdfs  dfsadmin  -safemode  get #查看安全模式状态

hdfs  dfsadmin  -safemode  enter #进入安全模式

hdfs  dfsadmin  -safemode  leave #离开安全模式

 

1.2.    HDFS基准测试

  • 实际生产环境当中,hadoop的环境搭建完成之后,第一件事情就是进行压力测试,测试我们的集群的读取和写入速度,测试我们的网络带宽是否足够等一些基准测试

1.2.1.   测试写入速度

向HDFS文件系统中写入数据,10个文件,每个文件10MB,文件存放到/benchmarks/TestDFSIO中

hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -fileSize 10MB

 

完成之后查看写入速度结果

hadoop fs -text /benchmarks/TestDFSIO/io_write/part-00000

1.2.2.   测试读取速度

测试hdfs的读取文件性能

在HDFS文件系统中读入10个文件,每个文件10M

hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar  TestDFSIO -read -nrFiles 10 -fileSize 10MB

 

查看读取果

 

hadoop fs -text /benchmarks/TestDFSIO/io_read/part-00000

 

1.2.3.   清除测试数据

 

 hadoop jar /export/servers/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean

 

8.HDFS基本原理

namenode的原理

  • NameNode在内存中保存着整个文件系统的名称空间和文件数据块的地址映射,整个HDFS可存储的文件数受限于NameNode的内存大小

  • NameNode元数据信息 文件名,文件目录结构,文件属性(生成时间,副本数,权限)每个文件的块列表。 以及列表中的块与块所在的DataNode之间的地址映射关系 在内存中加载文件系统中每个文件和每个数据块的引用关系(文件、block、datanode之间的映射信息) 数据会定期保存到本地磁盘(fsImage文件和edits文件)

    NameNode文件操作 NameNode负责文件元数据的操作 DataNode负责处理文件内容的读写请求,数据流不经过NameNode,会询问它跟那个DataNode联系

    dataNode副本文件数据块到底存放到哪些DataNode上,是由NameNode决定的,NameNode根据全局情况做出放置副本的决定

    NameNode心跳机制全权管理数据块的复制,周期性的接受心跳和块的状态报告信息(包含该DataNode上所有数据块的列表) 若接受到心跳信息,NameNode认为DataNode工作正常,如果在10分钟后还接受到不到DataNode的心跳,那么NameNode认为DataNode已经宕机 ,这时候NN准备要把DN上的数据块进行重新的复制。 块的状态报告包含了一个DataNode上所有数据块的列表,blocks report 每隔1小时发送一次.

 

 

 

datanode的原理

  • Data Node以数据块的形式存储HDFS文件

  • DataNode也称为Slave。

  • NameNode和DataNode会保持不断通信。

  • DataNode启动时,它将自己发布到NameNode并汇报自己负责持有的块列表。

  • 当某个DataNode关闭时,它不会影响数据或群集的可用性。NameNode将安排由其他DataNode管理的块进行副本复制。

  • DataNode所在机器通常配置有大量的硬盘空间。因为实际数据存储在DataNode中。

  • DataNode会定期(dfs.heartbeat.interval配置项配置,默认是3秒)向NameNode发送心跳,如果NameNode长时间没有接受到DataNode发送的心跳, NameNode就会认为该DataNode失效。timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval,而默认的heartbeat.recheck.interval 大小为5分钟(单位毫秒),dfs.heartbeat.interval默认的大小为3秒。所以namenode如果在10分钟+30秒后,仍然没有收到datanode的心跳,就认为datanode已经宕机,并标记为dead。

  • datanode中的数据block汇报时间间隔取参数dfs.blockreport.intervalMsec,参数未配置的话默认为6小时.

HDFS的工作机制

HDFS的写入机制

写入机制流程:

 

 

 

详细步骤解析:

  1. client发起文件上传请求,通过RPC与NameNode建立通讯,NameNode检查目标文件是否已存在,父目录是否存在,返回是否可以上传;

  2. client请求第一个 block该传输到哪些DataNode服务器上;

  3. NameNode根据配置文件中指定的备份数量及副本放置策略进行文件分配,返回可用的DataNode的地址,如:A,B,C;

  4. client请求3台DataNode中的一台A上传数据(本质上是一个RPC调用,建立pipeline),A收到请求会继续调用B,然后B调用C,将整个pipeline建立完成,后逐级返回client;

  5. client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(默认64K),A收到一个packet就会传给B,B传给C;A每传一个packet会放入一个应答队列等待应答。

  6. 数据被分割成一个个packet数据包在pipeline上依次传输,在pipeline反方向上,逐个发送ack(命令正确应答),最终由pipeline中第一个DataNode节点A将pipeline ack发送给client;

  7. 当一个block传输完成之后,client再次请求NameNode上传第二个block到服务器。

HDFS的读取机制

 

 

 

详细步骤解析:

  1. Client向NameNode发起RPC请求,来确定请求文件block所在的位置;

  2. NameNode会视情况返回文件的部分或者全部block列表,对于每个block,NameNode都会返回含有该block副本的DataNode地址;

  3. 这些返回的DN地址,会按照集群拓扑结构得出DataNode与客户端的距离,然后进行排序,排序两个规则:网络拓扑结构中距离Client近的排靠前;心跳机制中超时汇报的DN状态为STALE,这样的排靠后;

  4. Client选取排序靠前的DataNode来读取block,如果客户端本身就是DataNode,那么将从本地直接获取数据;底层上本质是建立Socket Stream(FSDataInputStream),重复的调用父类DataInputStream的read方法,直到这个块上的数据读取完毕;

  5. 当读完列表的block后,若文件读取还没有结束,客户端会继续向NameNode获取下一批的block列表;

  6. 读取完一个block都会进行checksum验证,如果读取DataNode时出现错误,客户端会通知NameNode,然后再从下一个拥有该block副本的DataNode继续读。

  7. read方法是并行的读取block信息,不是一块一块的读取;NameNode只是返回Client请求包含块的DataNode地址,并不是返回请求块的数据;

最终读取来所有的block会合并成一个完整的最终文件。

HDFS的元数据辅助管理

主要功能

将 edits 文件和 fsimage 文件进行合并操作,形成新的fsimage 文件。

 

 

 

snn 元数据辅助执行流程

第一步:将hdfs更新记录写入一个新的文件——edits.new。

第二步:将fsimage和editlog通过http协议发送至secondary namenode。

第三步:将fsimage与editlog合并,生成一个新的文件——fsimage.ckpt。这步之所以要在secondary namenode中进行,是因为比较耗时,如果在namenode中进行,或导致整个系统卡顿。

第四步将生成的fsimage.ckpt通过http协议发送至namenode。

第五步重命名fsimage.ckpt为fsimage,edits.new为edits。

第六步等待下一次checkpoint触发SecondaryNameNode进行工作,一直这样循环操作。

fsimage的信息查看

cd /export/server/hadoop2.7.5/hadoopDatas/namenodeDatas
hdfs oiv -i fsimage_0000000000000000864 -p XML -o fsimage.xml

edits的文件查看

cd /export/server/hadoop2.7.5/hadoopDatas/namenodeDatas
hdfs oev -i edits_0000000000000000865-0000000000000000866 -p XML -o myedit.xml

 

 

 

 

posted on 2021-02-07 09:15  王平  阅读(187)  评论(0)    收藏  举报