先给大家介绍一下什么叫HDFS,我们生活在信息爆炸的时代,随着数据量越来越大,在一个操作系统存不下所有的数据,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,迫切需要一种系统来管理多台机器上的文件,这就是分布式文件管理系统。HDFS只是分布式文件管理系统中的一种。
HDFS(Hadoop Distributed File System),它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的使用场景:适合一次写入,多次读出的场景。一个文件经过创建、写入和关闭之后就不需要改变。
(1)数据自动保存多个副本。通过增加副本的形式,提高容错性。
(2)某一个副本丢失以后,她可以自动恢复。
(1)数据规模:能够处理数据规模达到GB,TB,甚至PB级别的数据;
(2)小文件存储的寻址时间会超过读取时间,它违反了HDFS的设计目标。
(1)一个文件这只能有一个写,不允许多个线程同时写;
(2)仅支持数据append(追加),不支持文件的随机修改。
HDFS是一个部署在集群上的分布式文件系统,因此很多数据需要通过网络进行传输。
所有的HDFS通信协议都是构建在TCP/IP协议基础之上的。
客户端通过一个可配置的端口向名称节点主动发起TCP连接,并使用客户端协议与名称节点进行交互。
名称节点和数据节点之间则使用数据节点协议进行交互。
客户端与数据节点的交互是通过 RPC(Remote Procedure Call)来实现的。
HDFS 只设置唯一一个名称节点,这样做虽然大大简化了系统设计,但也带来了一些明显的局限性,具体如下。
(1)命名空间的限制。名称节点是保存在内存中的,因此名称节点能够容纳对象(文件、块)的个数会受到内存空间大小的限制。
(2)性能的瓶颈。整个分布式文件系统的吞吐量受限于单个名称节点的吞吐量。
(3)隔离问题。由于集群中只有一个名称节点,只有一个命名空间,因此无法对不同应用程序进行隔离。
(4)集群的可用性。一旦这个唯一的名称节点发生故障,会导致整个集群变得不可用。
HDFS相关概念
(1)HDFS的块设置太小,会增加寻址实践,程序一直在找块的开始位置;
(2)如果块设置的太大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。导致程序在处理这块数据时,会非常慢。
总结:HDFS块的大小设置主要取决于磁盘传输速率。
名称节点:主角色:NameNode 负责管理分布式文件系统的命令空间,保存了两个核心数据结构,(Fslmage和EditLog)。每个文件中各个块所在数据节点的位置信息。
FSlmage:用于维护文件系统数以及文件树中所有的文件和文件夹的元数据。
EditLog:操作日志文件,记录了所有针对文件的创建,删除,重命名的操作。
数据节点:从角色:DataNode:分布式文件系统HDFS的工作节点,负责数据的存储和读取。
为了提高数据的可靠性与系统的可用性,以及充分利用网络带宽,HDFS采用了以机架(Rack)为基础的数据存放策略。
HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自己所属的机架ID。当客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,可以调用API来确定客户端和这些数据节点所属的机架ID。
HDFS的数据复制采用了流水线复制的策略,大大提高了数据复制过程的效率。当客户端要往HDFS中写入一个文件时,这个文件会首先被写入本地,并被切分成若干个块,每个块的大小是由HDFS的设定值来决定的。每个块都向HDFS集群中的名称节点发起写请求,名称节点会根据系统中各个数据节点的使用情况,选择一个数据节点列表返回给客户端,然后客户端就把数据首先写入列表中的第一个数据节点,同时把列表传给第一个数据节点。
1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。
(2)NameNode返回是否可以上传。
(3)客户端请求第一个 Block上传到哪几个DataNode服务器上。
(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。
(5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
(6)dn1、dn2、dn3逐级应答客户端。
(7)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)
(1)客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。