数分-理论-大数据3-HDFS(分布式文件系统)
(数据分析系列)
文章目录
1知识点
- 背景
- 简介
- 体系结构
- 存储原理
- 数据读写过程
- 安装应用
2具体内容
2.1背景
大数据->高效存储->分布式文件系统->HDFS
- 分布式文件系统是管理网络中跨多台计算机存储的文件系统
- GFS的开源实现
- 容错能力强,用户在廉价服务器集群中存储大规模数据,实现大流量和大数据量读写
2.2简介
1.块
- “磁盘块”,每512字节一组,文件系统读写最小单位
- 普通文件系统:读写必须是磁盘块的整数倍
- 分布式文件系统:以块读写,但HDFS默认块是64M
- 一个文件小于一个数据快大小,不占用整个数据库存储空间
- 较大的块是为了最小化寻址开销
- 太大的块会导致MapReduce的Map任务一次只处理一个块数据,启动任务太少影响并行速度
2.分布式文件系统
-
客户机/服务器:C/S
-
C:以特定通信协议通过网络与服务器建立连接提出访问请求
-
S:设置访问权,限制请求方对底层数据存储块的访问
-
主节点,名称节点
- 负责文件和目录的创建、删除和重命名等
- 管理着数据节点和文件块的映射关系
- 客户端只有访问名称节点才能找到请求的文件块所在的位置,从而到相应位置读取所需的文件块;
-
数据节点
- 负责数据的存储和读取
- 存储时,由名称节点分配存储位置,然后由客户端把数据直接写入相应数据节点
- 读取时,客户端从名称节点获得数据节点和文件块的映射关系,然后就可以到相应位置访问文件块。
- 数据节点也要根据名称节点的命令创建、删除数据块和冗余复制。
-
-
保证数据完整,采用多副本存储。文件块会被复制为多个副本,存储在不同的节点上,而且存储同一文件块不同副本的各个节点会分布在不同的机器上。
-
针对大规模数据存储而设计,处理过小的文件不仅无法充分发挥其优势,而且会严重影响到系统的扩展和性能
3.HDFS
- 以分布式方式存储超大数据量文件,但它并不适合存储大量的小数据量文件
- Hadoop和其他组件的数据存储层
- 运行在价廉的商用集群上
- 采用多种机制保障数据完整性
优势:
- 兼容价廉设备
- 流数据读写(不支持随机读写),很高的数据吞吐率
- 大数据集:GB、TB以上
- 简单的文件模型:一次写入、多次读取
- 强大的跨平台兼容性:JAVA实现
局限:
- 不适合低延迟数据访问,可选HBase
- 无法高效存储大量小文件
- 名称节点管理文件系统,多个小文件检索效率低,耗内存大
- MapReduce处理大量小文件,现成开销过大
- 访问多个小文件,需要跳数据节点,影响性能
- 不支持多用户写入及任意修改文件
- 只允许一个写入者
- 只允许追加
2.3体系结构
1.主从(Master/Slave)结构模型,一个名称节点+若干数据节点
- 名称节点:中心服务器,负责管理文件系统的命名空间及客户端对文件的访问
- 数据节点:处理文件系统客户端的读/写请求,在名称节点的统一调度下进行数据块的创建、删除和复制等操作
- 心跳:数据节点按时报告状态,未按时发送“宕机”,不再分I/O请求
2.读文件流程
- 文件名发送给名称节点
- NameNode找到对应的数据块(一个文件可能包括多个数据块)
- 根据每个数据块信息找到实际存储在各个数据块的数据节点的位置
- 把数据节点位置发送给客户端
- 客户端直接访问这些数据节点获取数据
- NameNode不参与数据的传输
- 文件的数据能够在不同的数据节点上实现并发访问,大大提高了数据访问速度。
2.4存储原理
2.4.1数据冗余存储
多副本方式冗余存储,一个数据块的多个副本会被分布到不同数据节点
- 加快数据传输速度:让各个客户端分别从不同的数据块副本中读取数据,并行操作
- 容易检查数据错误:通过网络传输数据,采用多个副本可以很容易判断数据传输是否出错
- 保证数据的可靠性:即使某个数据节点出现故障失效,也不会造成数据丢失
2.4.2数据存储策略
数据存放、数据读取、数据复制
1.数据存放
-
机架(Rack)存放策略
-
不同机架通信需要经过交换机或路由器
-
同一机架不同机器数据通信不用交换机或路由器(带宽大)
-
默认,每个数据节点在不同机架上
- 缺点:写入数据时不能充分利用同一机架内部机器之间的带宽
- 优势:
- 获得很高的数据可靠性(一个机架故障其他机架副本仍可用)
- 多机架并行读数,数据读取速度max
- 易实现系统内部负载均衡和错误纠正
-
默认冗余复制因子是3,每个文件被同时保存到3个地方(两份副本放在同一个机架的不同机器上面,第三个副本放在不同机架的机器上面)
-
存放策略
- 集群发起写请求,第1副本房子发起请求的数据节点上,就近写入数据。若是来自外部的写操作,从集群内部挑一台磁盘空间充足,cpu不忙的数据节点,作为1副本存放地
- 第2个副本放与第1不同的机架的数据节点
- 第2个副本放与第1相同的机架的不同节点
2.数据读取
- 提供API,确定一个数据节点所属机架ID,客户端可调用API获取自己所属机架ID
- 客户端读取数据,名称节点获取位置列表(副本位置节点,可调用API确定客户端和数据节点所属机架ID)
- 当某数据块副本对应机架ID和客户端对应机架ID相同时,优先选择该副本读取。若无,随机选一个副本
3.数据复制
- 流水线复制
- 写入本地,切分多块,每块大小是HDFS设计好的
- 每块向集群发写请求,名称节点根据个数据节点情况,选择一个数据节点列表返回给客户端
- 客户端把数据写入列表中第1个数据节点,同时把列表传给第1个数据节点
- 第1个数据节点接到后写入本地,并向第2个数据节点发起连接请求 ,把数据和列表发给第2个数据节点
- 第2个数据节点接到后写入本地,并向第3个数据节点发起连接请求,依次类推,列表中多个数据节点形成一条数据复制的流水线。
- 文件写完后,数据复制完成
2.4.3数据错误与恢复
1.名称节点出错(2种机制)
- 名称节点上的元数据信息同步存储到其他文件系统
- 运行一个第二名称节点,当名称节点宕机,利用第二名称节点中的元数据信息进行系统恢复
- 会丢失部分数据
- 一般两种结合,名称节点宕机,首先到远程挂载的网络文件系统中获取备份元数据信息,放到第二名称节点上恢复,并把第二名称节点做名称节点使用
2.数据节点出错
- 数据节点定期向名称节点发送“心跳”,报告状态
- 故障后,名称节点无法收到“心跳”,该数据节点记为“宕机”,其数据记为“不可读”,名称节点不会发送I/O请求。
- 名称节点检查发现,某个数据的副本数量小于冗余因子,就会启动数据冗余复制,为它生成新的副本。
3.数据出错
网络传输和磁盘错误等因素都会造成数据错误。
- md5\sha1对数据块校验,确保读取正确数据
- 文件创建时,客户端对每个文件块进行信息摘录,并把信息写入同一路径的隐藏文件里
- 客户端读取文件时,先读取信息文件,利用信息文件对每个读取的数据块校验
- 校验出错,客户端就会请求到另外一个数据节点读取该文件块,并且向名称节点报告这个文件块有错误,名称节点会定期检查并且重新复制这个块。
2.5数据读写过程
1.读数据
- 创建输入流:client通过FileSystem.open()打开文件,在HDFS内DistributedFileSystem实现FileSystem。调用open()方法后,DistributedFileSystem会创建输入流FSDataInputStream,对于HDFS而言,具体的输入流就是DFSInputStream。
- 通过名称节点获取位置:在DFSInputStream的构造函数中,输入流通过ClientProtocal.getBlockLocations() 远程调用名称节点,获得文件开始部分的数据块保存位置。对于该数据块,名称节点返回保存该数据块的所有数据节点的地址,同时,根据距离客户端的远近对数据节点进行排序;然后,DistributedFileSystem会利用DFSInputStream来实例化FSDataInputStream,返回给客户端,同时返回了数据块的数据节点地址。
- 读:获得输入流FSDataInputStream后,客户端调用read()函数读取数据。输入流根据前面的排序结果,选择距离客户端最近的数据节点建立连接并读取数据。
- 读完后关链接:数据从该数据节点读到客户端;当该数据块读取完毕时,FSDataInputStream关闭与该数据节点的连接
- 下一个:输入流通过getBlockLocations()方法查找下一个数据块(如果客户端缓存中已经包含了该数据块的位置信息,就不需要调用该方法),找到该数据块的最佳数据节点,读取数据。
- 关闭数据流:当客户端读取完毕数据的时候,调用FSDataInputStream的close()函数,关闭输入流。需要注意的是,在读取数据的过程中,如果客户端与数据节点通信时出现错误,就会尝试连接包含此数据块的下一个数据节点。
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.故障+检测方法
-
故障(节点故障+通讯故障+数据损坏)
-
读写故障处理
-
数据节点故障
-
副本布局策略
2.6安装应用
- 安装部署java环境,完成hadoop部署
- 掌握HDFS使用+基本命令
3参考
- https://shenhao-stu.github.io/Big-Data/#/
- 翻译经典 HDFS原理讲解漫画