Task 2
第三章 HDFS
3.1 概述
3.1.1 分布式文件系统简介
块的概念:普通文件系统 VS 分布式文件系统
普通文件系统:一般会把磁盘空间划分为每512字节一组,称为“磁盘块”,它是文件系统读写操作的最小单位,文件系统的块(Block)通常是磁盘块的整数倍,即每次读写的数据量必须是磁盘块大小的整数倍;
分布式文件系统:也采用了块的概念,文件被分成若干个块进行存储,块是数据读写的基本单元,只不过分布式文件系统的块要比普通文件系统中的块大很多。
分布式文件系统的设计一般采用“客户机/服务器”(Client/Server),客户端以特定的通信协议通过网络与服务器建立连接,提出文件访问请求,客户端和服务器可以通过设置访问权,来限制请求方对底层数据存储块的访问。
分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,如下图所示,这些节点分为两类:一类叫“主节点”(Master Node),或者也被称为“名称节点”(NameNode);另一类叫“从节点”(Worker Node),或者也被称为“数据节点”(DataNode):
名称节点:负责文件和目录的创建、删除和重命名等,同时管理着数据节点和文件块的映射关系,因此客户端只有访问名称节点才能找到请求的文件块所在的位置,从而到相应位置读取所需的文件块;
数据节点:负责数据的存储和读取。在存储时,由名称节点分配存储位置,然后由客户端把数据直接写入相应数据节点;在读取时,客户端从名称节点获得数据节点和文件块的映射关系,然后就可以到相应位置访问文件块。数据节点也要根据名称节点的命令创建、删除数据块和冗余复制。
3.1.2 HDFS简介
HDFS(Hadoop Distribute File System)是大数据领域一种非常可靠的存储系统,它以分布式方式存储超大数据量文件,但它并不适合存储大量的小数据量文件。同时HDFS是Hadoop和其他组件的数据存储层,运行在由价格廉价的商用机器组成的集群上的,而价格低廉的机器发生故障的几率比较高,因此HDFS在设计上采取了多种机制,在硬件故障的情况下保障数据的完整性。
优点:
- 兼容廉价的硬件设备
- 流数据读写
- 大数据集
- 简单的文件模型
- 强大的跨平台兼容性
缺点:
- 不适合低延迟数据访问
- 无法高效存储大量小文件
- 不支持多用户写入及任意修改文件
- HDFS的体系结构
HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群包括一个名称节点(NameNode)和若干个数据节点(DataNode)。(参考3.1中的图片)
1. 名称节点作为中心服务器,负责管理文件系统的命名空间及客户端对文件的访问。
2. 数据节点负责处理文件系统客户端的读/写请求,在名称节点的统一调度下进行数据块的创建、删除和复制等操作。
3. 每个数据节点会周期性地向名称节点发送“心跳”信息,报告自己的状态,没有按时发送心跳信息的数据节点会被标记为“宕机”,不会再给它分配任何I/O请求。
用户在使用HDFS时,仍然可以像在普通文件系统中那样,使用文件名去存储和访问文件。
-
- HDFS的存储原理
3.3.1数据的冗余存储
为了保证系统的容错性和可用性,HDFS采用了多副本方式对数据进行冗余存储,通常一个数据块的多个副本会被分布到不同的数据节点上。
优点:
- 加快数据传输速度:当多个客户端需要同时访问同一个文件时,可以让各个客户端分别从不同的数据块副本中读取数据,这就大大加快了数据传输速度,实现了并行操作。
- 容易检查数据错误:HDFS的数据节点之间通过网络传输数据,采用多个副本可以很容易判断数据传输是否出错。
- 保证数据的可靠性:即使某个数据节点出现故障失效,也不会造成数据丢失。
-
- 数据存放策略
-
数据存取策略包括数据存放,数据读取和数据复制
-
-
-
- 数据存放
-
-
HDFS采用了以机架(Rack)为基础的数据存放策略。一个HDFS集群通常包含多个机架,不同机架之间的数据通信需要经过交换机或路由器,同一机架的不同机器之间数据通信不需要交换机或路由器,因此同一机架中不同机器之间的通信要比不同机架之间机器的通信带宽大。
HDFS默认每个数据节点都是在不同机架上的,这样有一个缺点:写入数据的时候不能充分利用同一机架内部机器之间的带宽。这种方法同时也带来了更多显著的优点:
- 可以获得很高的数据可靠性,即使一个机架发生故障,位于其他机架上的数据副本仍然可用。
- 在读数据的时候,可以在多个机架上并行读取数据,大大提高了数据读取速度。
- 可以更容易实现系统内部负载均衡和错误纠正。
HDFS默认的冗余复制因子是 3,每一个文件会被同时保存到 3 个地方,其中两份副本放在同一个机架的不同机器上面,第三个副本放在不同机架的机器上面。
3.3.2.2 数据读取
HDFS提供了一个API,用于确定一个数据节点所属的机架的ID,客户端可以调用该API获取自己所属机架的ID。
当客户端读取数据时,从名称节点获取数据块不同副本的存放位置的列表,列表中包含了副本所在的数据节点,可以调用API确定客户端和这些数据节点所属的机架ID。当发现某个数据块副本对应的机架ID和客户端对应的机架的ID相同时,则优先选择该副本读取数据;如果没有发现,则随机选择一个副本读取数据。
3.3.2.3 数据复制
HDFS的数据复制采用了 流水线复制 的策略,大大提高了数据复制过程的效率。
3.4 HDFS的数据读写过程
3.4.1 读数据的过程
1. 客户端通过 FileSystem.open() 打开文件,相应地,在HDFS文件系统中,DistributedFileSystem具体实现了FileSystem。因此,调用open()方法后,DistributedFileSystem会创建输入流FSDataInputStream,对于HDFS而言,具体的输入流就是DFSInputStream。
2. 在DFSInputStream的构造函数中,输入流通过ClientProtocal.getBlockLocations() 远程调用名称节点,获得文件开始部分的数据块保存位置。对于该数据块,名称节点返回保存该数据块的所有数据节点的地址,同时,根据距离客户端的远近对数据节点进行排序;然后,DistributedFileSystem会利用DFSInputStream来实例化FSDataInputStream,返回给客户端,同时返回了数据块的数据节点地址。
3. 获得输入流FSDataInputStream后,客户端调用read()函数读取数据。输入流根据前面的排序结果,选择距离客户端最近的数据节点建立连接并读取数据。
4. 数据从该数据节点读到客户端;当该数据块读取完毕时,FSDataInputStream关闭与该数据节点的连接。
5. 输入流通过getBlockLocations()方法查找下一个数据块(如果客户端缓存中已经包含了该数据块的位置信息,就不需要调用该方法)。
6. 找到该数据块的最佳数据节点,读取数据。
7. 当客户端读取完毕数据的时候,调用FSDataInputStream的close()函数,关闭输入流。需要注意的是,在读取数据的过程中,如果客户端与数据节点通信时出现错误,就会尝试连接包含此数据块的下一个数据节点。
3.4.2 写数据的过程
- 客户端通过 FileSystem.create() 创建文件。相应地,在HDFS文件系统中, DistributedFile System具体实现了FileSystem。因此,调用create()方法后,DistributedFileSystem会创建输出流对象FSDataOutputStream,对于HDFS而言,具体的输出流就是DFSOutputStream。
- 然后,DistributedFileSystem通过RPC远程调用名称节点,在文件系统的命名空间中创建一个新的文件。名称节点会执行一些检查,比如文件是否已经存在,客户端是否有权限创建文件等。检查通过之后,名称节点会构造一个新文件,并添加文件信息。远程方法调用结束后,DistributedFileSystem会利用DFSOutputStream来实例化FSDataOutputStream,返回给客户端,客户端使用这个输出流写入数据。
- 获得输出流FSDataOutputStream以后,客户端调用输出流的write()方法向HDFS对应的文件写入数据。
- 客户端向输出流FSDataOutputStream中写入的数据,会首先被分成一个个的分包,这些分包被放入DFSOutputStream对象的内部队列。输出流FSDataOutputStream会向名称节点申请保存文件和副本数据块的若干个数据节点,这些数据节点形成一个数据流管道。队列中的分包最后被打包成数据包,发往数据流管道中的第一个数据节点,第一个数据节点将数据包发送给第二个数据节点,第二个数据节点将数据包发送给第三个数据节点,这样,数据包会流经管道上的各个数据节点(即流水线复制策略)。
- 因为各个数据节点位于不同机器上,数据需要通过网络发送,因此,为了保证所有数据节点的数据都是准确的,接收到数据的数据节点要向发送者发送“确认包”(ACK Packet)。确认包沿着数据流管道逆流而上,从数据流管道依次经过各个数据节点并最终发往客户端,当客户端收到应答时,它将对应的分包从内部队列移除。不断执行第3~5步,直到数据全部写完。
- 客户端调用close()方法关闭输出流,此时开始,客户端不会再向输出流中写入数据,所以,当DFSOutputStream对象内部队列中的分包都收到应答以后,就可以使用ClientProtocol.complete()方法通知名称节点关闭文件,完成一次正常的写文件过程。
3.4.3 HDFS故障类型和其检测方法
3.4.3.1 读写故障的处理
3.4.3.3 副本布局策略
3.5 实践
- Namenode启动失败,使用指令hadoop namenode -format将其格式化之后重新启动即可。
总结:本章难点在于namenode启动失败及原文章大量命令,其余还都好理解
—————————————————————————————————————————
笔记内容通过datawhale教学总结而来,侵告删。