一、简述
Hadoop分布式文件系统通常在通用硬件上运行,它和现有的其他分布式文件系统有很多相同之处,同时也有着明显的区别。HDFS具有高容错、高吞吐量、低廉价部署等特性,非常适合于大规模数据集的管理和存储。HDFS最开始是作为Apache Nutch搜索引擎项目基础框架而开发,它是Apache Hadoop Core项目的一部分。
二、HDFS设计基础
1、硬件故障
硬件故障是一种常态,而不是异常。一个HDFS集群由成百上千个服务器组成,它拥有非常巨大的组件数量,每一个组件都有可能发生错误。因此,故障的检测和快速的自动恢复能力是HDFS的设计基础之一。
2、流数据访问
运行在HDFS上的应用程序以流式方式访问数据集,不是普通应用程序访问文件系统的访问方式。HDFS适合批量处理,而不是交互式处理,首先集中于数据吞吐量,其次才是数据访问的响应速度。而POSIX标准的很多硬性需求对于HDFS都不是必须的,因此,去掉POSIX的部分语义可以得到更好的数据吞吐率。
3、大数据集
运行在HDFS上的应用程序需要处理巨量的数据,一个典型的HDFS文件大小从GB到TB级别不等。鉴于此,HDFS就需要支持大文件的存储与访问,一般一个集群支持数百个节点是比较常见的,同时也需要高聚合的数据带宽支持。
4、一致性模型
HDFS应用程序采用的是一写多读的操作模式,一个文件一旦创建、写入、关闭后就不允许修改,这使得数据一致性问题得以简化,也就可以实现高吞吐量的数据访问,其中MapReduce和爬虫程序就是这样的操作模式。不过,未来的计划中将会涉及数据扩展写入。
5、移动计算比移动数据更经济、更经济
处理巨量数据时,计算数据的存储位置若更靠近计算位置,计算效率将会得到大大提高。而HDFS提供了这样的接口,可以将应用程序移动到更靠近数据存储的地方。
6、软硬件平台的可移植性
HDFS设计为各平台间可移植,这就需要推动HDFS成为大数据集的管理与存储平台。
三、HDFS体系结构
HDFS集群采用主从(Master/Slave)结构模型,由一个NameNode和若干DataNode组成。
1、NameNode:所有HDFS文件元数据的管理者
(1)、管理HDFS命名空间,使用事务日志记录HDFS元数据的变化
(2)、记录HDFS数据块的索引位置(包括副本)
(3)、使用映像文件记录HDFS命名空间及其属性的变化
(4)、处理客户端对文件的访问需求,主要是映射DataNode位置
(5)、不进行DataNode数据的传输
2、DataNode:所有HDFS文件实际数据的存储者
(1)、管理数据存储
(2)、一写多读,创建-->写入-->关闭,不允许修改
(4)、数据散步分布到各个节点,数据块大小默认为64M
(5)、执行NameNode的统一调度命令(多为读出、写入、删除)
3、Client:所有HDFS文件数据的访问者(使用者)
(1)、请求从NameNode获取文件数据块位置列表
(2)、根据获取的位置列表在DataNode中找到所需数据块
(3)、读取,写入,删除数据...
四、HDFS读取写入
1、文件读取
(1)、Client向远程NameNode发起RPC请求
(2)、NameNode根据情况返回部分或全部数据块位置列表
(3)、Client会就近选取适合的DataNode读取数据块
(4)、读取完整数据块后,关闭相应DataNode连接,并为下一数据块的读取做准备
(5)、若开始获取的不是全部数据块位置列表,则再次获取数据块列表,再次读取......
(6)、在这个过程中,每读取完一个数据块都会惊醒checksum验证
(7)、如果验证出错,通知NameNode继续读取拥有相同数据的其他数据块......
2、文件写入
1、Client向远程NameNode发起RPC请求
2、检查Client是否有操作权限,NameNode新建文件是否存在,成功则创建文件,失败则抛出异常
3、开始写入文件的时候,根据文件大小切分成一个或多个Packets,并以数据队列“Data Queue”方式进行管理
4、向NameNode申请DataNode的数据块,NameNode返回合适的数据块列表,列表大小由NameNode中Replication决定
5、通过Pipeline将“Data Queue”中Packet以流的方式写入第一个DataNode,存储完成后该DataNode把Packet传到管道数据块列表对应的下一个DataNode......,直到所有的Packets写入完成。这就是数据的流式传输。
6、每个Packet存储到DataNode后,会返回一个ack包,通过管道传送至Client。由于Client内部维护有“ACK Queue”,因此在成功收到DataNode返回的ACK包后,要清除“ACK Queue”中相应“Data Queue”的Packet。
7、若在数据传输过程中DataNode发生故障,关闭Pipeline,移除Pipeline中故障的DataNode,继续剩下数据块的传输。与此同时NameNode收到故障信息后,会分配一个新的DataNode进行故障DataNode对应数据的传输。
最后,介绍一个有比较意思的链接:http://blog.csdn.net/netcoder/article/details/7442779