Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
一、HDFS(Hadoop Distributed File System)
Hadoop是一个以一种可靠、高效、可伸缩的方式进行处理的,能够对大量数据进行分布式处理的系统框架。
所以可以理解为hadoop是一个框架,HDFS是hadoop中的一个部件。
对外部客户机而言,HDFS 就像一个传统的分级文件系统。可以创建、删除、移动或重命名文件,等等
HDFS在hadoop中的地位如图
HDFS具有大规模数据分布存储能力、高并发访问能力、顺序式文件访问简单的一致性模型、强大的容错能力、数据块存储模式。
文件系统由三部分组成:与文件管理有关软件、被管理文件以及实施文件管理所需数据结构。HDFS以流处理访问模式来存储文件,一次写入,多次读取。每个文件在系统里都能找到它的本地化映像,所以对于用户来说,别管文件是什么格式,也不用在意被分到哪里,只管从DFS里取出就可以了。
HDFS利用分片冗余和本地校验解决数据被分布后的结构不完整,系统复杂度加大等问题。
因文件不在一个磁盘导致读取访问操作的延时是HDFS现在遇到的主要问题。现阶段,HDFS的配置是按照搞数据吞吐量优化的,可能会以高时间延时为代价。但万幸的是HDFS是具有高弹性的,可以针对具体应用再优化。
HDFS架构
一个HDFS文件系统包括一个主控节点NameNode和一组DataNode从节点。
NameNode是一个主服务器,用来管理整个文件系统的命名空间和元数据,以及
处理来自外界的文件访问请求。NameNode保存了文件系统的三种元数据:
1)命名空间,即整个分布式文件系统的目录结构;
2)数据块与文件名的映射表;
3)每个数据块副本的位置信息,每一个数据块默认有3个副本
DataNode用来实际存储和管理文件的数据块
1)文件中的每个数据块默认的大小为64MB;同时为了防止数据丢失,每个数据块默认有3个副本,且3个副本会分别复制在不同的节点上,以避免一个节点失效造成一个数据块的彻底丢失。
2)每个DataNode的数据实际上是存储在每个节点的本地Linux文件系统中。
3)每个快会在本地文件系统产生两个文件,一个是实际的数据文件,另一个是块的附加信息文件,其中包括数据的校验和,生成时间
4)DataNode通过心跳包(Heartbeat)与NameNode通讯
5)客户端读取/写入数据的时候直接与DataNode通信
NameNode上可以执行文件操作,比如打开、关闭、重命名等;而且NameNode也负责向DataNode分配数据块并建立数据块和DataNode的对应关系。
DataNode负责处理文件系统用户具体的数据读写请求,同时也可以处理NameNode对数据块的创建、删除副本的指令。
典型的部署模式采用NameNode单独运行于一台服务器节点上,其余的服务器节点,每一台运行一个DataNode
二、数据块
1)在传统的块存储介质中,块是读写的最小数据单位(扇区)
2)传统文件系统基于存储块进行操作
--为了节省文件分配表空间,会对物理存进行存储块整合,一般大小为4096字节
3)HDFS也使用了块的概念,但是默认大小设为64M字节
--可针对每个文件配置,由客户端指定
--每个快有一个自己的全局ID
4)HDFS将一个文件分为一个或数个块来存储
--每个快是一个独立的存储单位
--以块为单位在集群服务器上分配存储
5)与传统文件系统不同的是,如果实际数据没有达到块大小,则并不实际占用磁盘空间
--如果一个文件是200M,则它会被分为4个块:64+64+64+8
使用块的好处
1)当一个文件大于集群中任意一个磁盘的时候,文件系统可以充分利用集群中所有的磁盘
2)管理快使底层的存储子系统相对简单
3)块更加适合备份,从而为容错和高可用性的实现带来 方便
4)最重要的是,采用块方式实现了名字与位置的分离,实现了的存储位置的独立性。
块的冗余备份
1)每个快在集群上会存储多份(replica)
--默认复制份数为3
--可针对每个文件配置,由用户指定
--可动态修改
2)某个块的所有备份都是同一个ID
--系统无需记录“哪些块其实是同一份数据”
3)系统可以根据机架的配置自动分配备份位置
--第一份在集群的某个机架的某台机器上
--其他两份在另外的一个机架的两台机器上
此策略是性能与冗余性的平衡
三、元数据
元数据包括:
文件系统目录树信息; 文件名,目录名;
文件和目录的从属关系 ; 文件和目录的大小,创建及最后访问时间;
权限; 文件由哪些块组成;
机器名,块ID;
HDFS对元数据和实际数据采取分别存储的方法
--元数据存储在一台指定的服务器上(NameNode)以便快速查询
--实际数据存储在集群的其他机器的本地文件系统中(DataNode)
四、HDFS文件的读写操作
数据的读取过程
数据读取
1.客户端调用FileSystem实例的open 方法,获得这个文件对应的输入
流InputStream
数据写入