1、概述
1、背景
HDFS(Hadoop Distributed File System)Hadoop分布式文件系统;
Hadoop内核包括:HDFS,Yarn,MapReduce;
HDFS源于Google的一篇论文:GFS
- 该论文发表与2003年10月;
- HDFS是GFS的克隆版;
HDFS是
- 一个易于扩展的分布式文件系统;
- 运行在大量廉价机器上,提供容错机制;
- 为大量用户提供性能不错的文件存取服务;
2、优点
- 扩展性
- 高容错性
HDFS保存多个副本;
副本丢失后,会自动恢复(保证每个文件维持一定的副本数,如果一个副本坏了,可以通过其他副本进行恢复);
- 适合批处理
移动计算而非数据的思想,提高大数据的性能;
将数据位置信息爆露给上层框架(上层框架可以根据位置进行作业调度--本地性,移动计算)
- 适合大数据处理
GB、TB、PB级别的数据;
百万规模以上的文件数量;
10k+节点规模;
- 流式文件访问
一次写入,多次读取;
保证数据一致性;
- 可构建在廉价的机器上
通过多副本提高可靠性;
提供容错和恢复机制;
3、缺点
不适合:
- 低延迟的数据访问
比如毫秒级;
- 小文件存取
1)会占用NameNode的大量内存(namenode上保存元数据信息--文件的块组成信息,块位置信息等,这些信息保存在内存中;当块多时,会消耗大量内存;);
2)寻道时间超过读取时间;
- 并发写入、文件随机修改
1) 一个文件只能有一个写者,不能通过多线程同时写入;
2) 仅支持append,不能对已有的文件内容进行修改;
2、基本原理
- 将文件切分为等大的数据块,存储在多个机器上;
- 将文件切分、容错、负载均衡等功能透明化;
- 可以将HDFS看成一个容量巨大的、具备高容错性的磁盘;
HDFS不适合存储小文件,原因分析?
- 元信息存储在namenode内存中,而一个节点的内存是有限的;
- 存取大量小文件会消耗大量的寻道时间;
- namenode存储block数是有限的;
一个文件大小不足一个block,会单独保存成一个block;
一个block的元信息大约消耗150byte内存;如果block数多,其元信息会消耗大量的内存,影响block数;
===》会通过对小文件进行合并再进行保存;
3、HDFS实现方式
问题:
存在大小不一的文件;多个机器;
目标:将文件存到机器上;
思考
- 方法1
文件1存在server1上;文件2存在server2;。。。;创建一个索引表-存放文件的位置;
存在的问题:可靠性低;
- 方法2
对于1),每个文件保存多分,每份在不同的server上;
存在的问题:很难负载均衡(文件大小不一);很难进行分布式处理(对于一个文件,不能并行处理);
- 方法3
将文件按大小进行切分,切分成等大的数据块,存放在不同的server上,每个块保存多分;
再创建2个索引表:一个保存数据块位置信息;一个保存文件的块组成(文件由哪些块组成);
==》这就是HDFS的设计思想;
4、HDFS架构
由6)得出
需要一个节点保存索引表;其他节点保存数据,所以HDFS架构Master/Slave结构;Master是namenode;Slave是datanode;
Master/Slave结构存在单点故障问题,所以准备namenode2个,一个主namenode,一个是backup;
5、HDFS中一些概念
1)数据块(block)
- 文件被切分成固定大小的数据块;
块大小默认为64MB,可配置;
如果一个文件不足64MB,则单独存成一个block; - 为什么一个block这么大?
linux中也有块的概念,但linux中一个块k单位;
使数据读取时间超过寻道时间;(高吞吐率) - 一个文件存储方式?
文件按大小被切分成多个block,存储在不同的节点上;
默认情况下,每个block有3个副本;
2)副本放置策略
每个block有3分,那么这3份如何存放?
拓扑
一个集群中有多个机架,一个机架有多个服务器,机架内部的服务器通过一个内部交换机;机架之间通过中央交换机;
同一机架内的服务器同时挂掉的可能性大,因为共用一个交换机;
- 基于上述考虑,Bolock副本存放策略:
副本1:同client的节点上;
副本2:不同机架上的节点上;
副本3:与副本2在同一机架上的节点上;
其他副本:随机选择(不同节点)
==》2个在同一机架内;另一个在不同机架上;
- 为什么不存放在3个机架上?
因为当前方案已经实现了机架级别的容灾;位于不同的机架上,容错性更好,但是写延迟增加;当前方案在性能和容错性之间折中;
3)可靠性策略
常见的3种错误情况,不同的情况采取不同的策略
1、文件损坏
CRC校验(每块有一个校验码,读取文件前先进行校验)
用其他副本替代损坏文件
2、网络或机器失败
如何判断datanode挂掉?datanode定时向namenode发送心跳信息,如果一定时间没有发送,则namenode会认为datanode挂掉;
datanode挂掉之后,会将该节点上的block在其他节点上重构;
3、namenode挂掉
namenode挂掉–元信息失效–情况比较严重
- 多分存储(定期写到磁盘上,元信息存储 在namenode内存中)
- FSImage Editlog
- 主备NameNode实时切换
6、HDFS读写流程
1、HDFS读
2、HDFS写
- HDFS client通过DistributedFileSystem向namenode询问文件文件是否已经存在,如果不存在,namenode通过可以写,并且返回3个要写的datanode地址(3个副本);
- HDFS client通过FSData OutputStream写;写是通过流式方式写的(不是通过启动3个线程并发写,因为这样的话,FSData OutputStream会成为瓶颈–比如更多的副本数)
- 流式写–FSData OutputStream向第一个datanode写,将一个数据块分成更小的单位-package,一个packge写完后,该datanode将该package传到第二个datanode,依次类推;
- 写完后,向上层通知;
- client关闭FSData OutputStream;