1HDFS的架构
•
一个
HDFS
文件系统包括一个主控
节点
NameNode
和一组
DataNode
从节点
。
–
NameNode
是
一个主服务器,用来管理整个文件系统的命名空间和元数据,以及处理来自外界的文件
访问
请求。
NameNode
保存了文件系统的三种元数据
:
•
1
)
命名空间, 即整个分布式文件系统
的目录
结构
;
•
2
)
数据块与文件名的映射表
;
•
3
)
每个数据块副本的位置信息,每一个数据块
默认
有
3
个副本
–
DataNode
用来实际存储和管理文件的数据
块
•
文件
中的每个数据块
默认
的大小为
64MB
;
同时为了防止数据丢失, 每个数据块默认有
3
个副本,且
3
个副本会
分别
复制在不同的节点上,以避免一个节点失效造成一个数据块的彻底丢失
。
•
每个
DataNode
的数据实际上是存储在每个节点的本地
Linux
文件系统中
hdfs是hadoop的分布式文件系统,可以创建,删除移动和重命名文件
需要hdfs的原因:hdfs具有大规模数据分布存储能力,高并发访问能力,顺序性文件访存,简单一致性模型,用流方式处理文件,在系统中都能找到他的映像,有强大的容错能力,数据冗余式存储,直接将多片的文件交给分片以后的存储器去校验
HDFS的配置是按照高数据吞吐量优化的,以高时间延时为代价,具有很高的弹性
2.元数据块
元数据是用于描述要素、数据集或数据集系列的内容、覆盖范围、质量、管理方式、数据的所有者、数据的提供方式等有关的信息。更简单的说,是关于数据的数据
3.数据块
•在传统的块存储介质中,块是读写的最小数据单位 (扇区)
•传统文件系统基于存储块进行操作
–为了节省文件分配表空间,会对物理存进行储块整般合,一般大小为4096字节
•HDFS也使用了块的概念,但是默认大小设为64M字节
–可针对每个文件配置,由客户端指定
–每个块有一个自己的全局ID
•HDFS将一个文件分为一个或数个块来存储
–每个块是一个独立的存储单位
–以块为单位在集群服务器上分配存储
•与传统文件系统不同的是,如果实际数据没有达到块大小,则并不实际占用磁盘空间
–如果一个文件是200M,则它会被分为4个块: 64+64+64+8
使用块的好处
–当一个文件大于集群中任意一个磁盘的时候,文件系统可以充分利用集群中所有的磁盘
–管理块使底层的存储子系统相对简单
–块更加适合备份,从而为容错和高可用性的实现带来方便
–最重要的是,采用块方式,实现了名字与位置的分离,实现了的存储位置的独立性
4.读写策略
数据读取
1.
客户端调用
FileSystem
实例的
open
方法,获得这个文件对应的输入流
InputStream
2.
通过
RPC
远程调用
NameNode
,获得
NameNode
中此文件对应的数据块保存位置,包括这个文件的副本的保存位置
(
主要是
各
DataNode
的
地址
)
。
3.
获得输入流
之后,客户端调用
read
方法读取数据
。选择
最近的
DataNode
建立连接并读取数据
。
4.
如果
客户端和其中一
个
DataNode
位于同一机器
(
比如
MapReduce
过程中的
mapper
和
reducer)
,那么就会直接从本地
读取
数据。
5.
到达
数据块
末端,关闭
与这个
DataNode
的连接,然后重新查找下一个
数据
块。
6.
不断执行第
2 - 5
步直到数据全部读
完
7.
客户端
调用
close
,关闭输入流
DF S
InputStream
数据写入
2222
1.
客户端
调用
Fi
leSystem
实例的
create
方法,创建文件。
NameNode
通过一些检查
,比如
文件是否存在,客户端是否拥有创建权限等
;
通过检查之后,在
NameNode
添加文件
信息
。注意,因为此时文件没有数据,所以
NameNode
上也没有文件数据块的信息
。
2.
创建结束之后
,
HDFS
会返回一个输出流
DFSDataOutputStream
给客户端。
3.
客户端
调用输出流
DFSDataOutputStream
的
write
方法向
HDFS
中对应的文件
写入数据。
4.
数据
首先会被分包,这些分包会写人一个输出流的内部队列
Data
队列中,接收完
数据
分包,输出流
DFSDataOutputStream
会向
NameNode
申请保存文件和副本数据块的若干
个
DataNode
, 这若干个
DataNode
会形成一个数据传输管道
。
DFSDataOutputStream
将
数据传输给距离上最短
的
DataNode
,这个
DataNode
接收到数据包之后会传给下一个
DataNode
。数据在各
DataNode
之间
通过管道流动,而不是全部由输出流分发
,以
减少传输开销
。
5.
因为各
DataNode
位于不同机器上,数据需要通过网络发送,所以,为了保证所有
DataNode
的数据都是准确的,接收到数据的
DataNode
要向发送者发送确认包
(ACK Packet )
。对于某个数据块,只有当
DFSDataOutputStream
收到了所有
DataNode
的正确
ACK.
才能确认传输结束。
DFSDataOutputStream
内部专门维护了一个等待
ACK
队列,这一队列保存已经进入管道传输数据、但是并未被完全确认的数据包。
6.
不断执行
第
3 - 5
步直到数据全部写完,客户端调用
close
关闭文件。
7.
DFSDataInputStream
继续等待直到所有数据写人完毕并被确认,调用
complete
方法通知
NameNode
文件写入完成
。
NameNode
接收到
complete
消息之后,等待相应数量的副本写入完毕后,告知
客户端
。