相关:
MapReduce小结
参考资料:
1、百度百科——Hadoop
2、初识HDFS(10分钟了解HDFS、NameNode和DataNode)
3、大牛笔记——【Hadoop】HDFS的运行原理
简介
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序,充分利用集群的威力进行高速运算和存储。Hadoop主要由HDFS、MapReduce和HBase组成。受启发于谷歌的三篇论文:分别关于GFS、MapReduce和BigTable,也可以说是这三种技术的一个实现。初衷是为了解决Nutch海量数据爬取和存储的需要,于2005年作为Lucene的子项目Nutch的一部分正式引入阿帕奇基金会。
HDFS概览
HDFS(Hadoop Distributed File System)即Hadoop的分布式文件存储系统,简单理解就是将数据/文件分块存在不同服务器的多个节点上,通过网络实现对文件不同块的访问,使其体验如同在本地访问整个文件一样。
HDFS会提前固定一个块的大小,叫做block,Hadoop1版本里默认为64M,Hadoop2版本里默认为128M。块中永远只存放一个文件,如果一个文件不能被块大小整除,那么最后一块就是一个装不满的块。为了可靠性,HDFS会将块创建多个副本(一般为3个),分散布置在服务器群的计算节点中。当然,所谓分散布置也不是随机放,还是有策略的:
- 第一个副本放在本地机架中的一个节点上,如果是集群外提交,就随机挑选一个磁盘不太满、cpu不太忙的一个节点;
- 第二个副本放置于与第一个副本不同机架的节点上;(因为同一个机架一般同一个电源,存在一起挂的情况)
- 第三个副本放置于与第二个副本相同机架的不同节点上;(如果相同机架的某个节点单挂,那么副本copy起来比较快)
- 若设置更多副本,那就随机放。
HDFS中block的大小和副本数量通过客户端上传文件的时候设置,文件上传成功后,副本数可以变化,但block size不能变化。
HDFS基本要素
fig.1 HDFS结构
从图1中可以看出,HDFS有三个关键要素:NameNode、SecondaryNameNode、DataNode。下面来一一介绍。
NameNode
NameNode中存的是元数据,何谓元数据,就是描述数据的数据,对数据及信息资源的描述性信息,包括文件的ownership、permissions、包含哪些块、这些块放在哪里等信息,简单来说NameNode不存数据本身,但保存数据的各种信息,起一个leader的作用。NameNode的功能是接收客户端的读写请求,然后利用自己的职务之便完成读写服务。
在运行过程中,NameNode是加载在内存中的,任何元数据的变动都会首先在内存中改变。既然说是“加载”在内存中,那么磁盘上肯定也有,否则重启都没了。存在磁盘上的两个关键文件是fsimage和edits。
fsimage文件保存了NameNode的目录信息,当NameNode启动时会首先读取这个文件,将元数据加载到内存中,但这其中并不包括block的位置信息。在启动时,DataNode会主动将位置上报至NameNode。
edits存储的是日志信息,在Namenode启动后所有对目录结构的增加,删除,修改等操作都会记录到edits文件中,并不会实时的同步至fsimage中。原因是NameNode太忙了,需要接收客户端请求,如果还要分心进行实时合并,那势必会影响客户端的响应速度。当NameNode启动过程中,会首先合并fsimage和edits文件,将最新信息更新至fsimage,然后启用新的edits文件。
在启动阶段,NameNode不仅需要接收DataNode的位置上报,还需要进行fsimage和edits文件的合并,这段时间称为“安全模式”,此时NameNode对客户端来说是只读的(显示目录、文件内容等,删、写都会失败)。在此阶段NameNode收集DataNode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的,当一定比例的数据块(可设置)被确认安全后,再过若干时间,安全模式退出。若某些块的副本没有到达最小副本数,那就会开始copy。
SecondaryNameNode
上面整个流程其实还有一点小问题,那就是当用户操作累计过多,edits将会变成一个很大的文件,那么启动时NameNode就会合并很久,导致启动时间变长,而且每次的时间完全不可控,这显然是不合理的,SecondaryNameNode就是为了解决这个问题。
SecondaryNameNode以一定的机制被唤醒,进行fsimage和edits文件的合并,更新fsimage、设置新的edits文件。唤醒机制有两个:
- 根据文件设置的时间间隔fs.checkpoint.period,默认为3600秒。
- 根据文件设置的edits log大小fs.checkpoint.size,默认为64M。
也就是说,超过3600秒或者日志文件超过64M都会自动被唤醒。SecondaryNameNode的合并流程为:从NameNode上 下载元数据信息(fsimage,edits),从NameNode上 下载元数据信息(fsimage,edits),然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode,同时重置NameNode的edits。然后把二者合并,生成新的fsimage,在本地保存,并将其推送到NameNode。
DataNode
DataNode中存放数据本身,数据以block的形式存在DataNode中。
首先解释块的概念:
- DataNode在存储数据的时候是按照block为单位读写数据的。block是hdfs读写数据的基本单位。
- 假设文件大小是100GB,从字节位置0开始,每128MB字节划分为一个block,依此类推,可以划分出很多的block。每个block就是128MB大小。
- block本质上是一个 逻辑概念,意味着block里面不会真正的存储数据,只是划分文件的。
- block里也会存副本,副本优点是安全,缺点是占空间
启动DataNode线程时会向NameNode汇报block信息。运行过程中DataNode通过向NameNode发送心跳保持与其联系(3s一次),如果NameNode10分钟没有收到心跳,则认为该DataNode已经lost。
HDFS的IO原理(转自“大牛笔记”的博客)
写操作
有一个文件FileA,100M大小。Client将FileA写入到HDFS上。
HDFS按默认配置。
HDFS分布在三个机架上Rack1,Rack2,Rack3。
- Client将FileA按64M分块。分成两块,block1和Block2
- Client向nameNode发送写数据请求,如图蓝色虚线①
- NameNode节点,记录block信息。并返回可用的DataNode,如粉色虚线②
Block1: host2,host1,host3
Block2: host7,host8,host4 - d. client向DataNode发送block1;发送过程是以流式写入。
流式写入过程:
- 将64M的block1按64k的package划分; 然后将第一个package发送给host2;
- host2接收完后,将第一个package发送给host1,同时client想host2发送第二个package;
- host1接收完第一个package后,发送给host3,同时接收host2发来的第二个package。
- 以此类推,如图红线实线所示,直到将block1发送完毕。
- host2,host1,host3向NameNode,host2向Client发送通知,说“消息发送完了”。如图粉红颜色实线所示。
- client收到host2发来的消息后,向namenode发送消息,说我写完了。这样就真完成了。如图黄色粗实线
- 发送完block1后,再向host7,host8,host4发送block2,如图蓝色实线所示。
- 发送完block2后,host7,host8,host4向NameNode,host7向Client发送通知,如图浅绿色实线所示。
- client向NameNode发送消息,说我写完了,如图黄色粗实线。。。这样就完毕了。
分析,通过写过程,我们可以了解到:
- 写1T文件,我们需要3T的存储,3T的网络流量贷款。
- 在执行读或写的过程中,NameNode和DataNode通过HeartBeat进行保存通信,确定DataNode活着。如果发现DataNode死掉了,就将死掉的DataNode上的数据,放到其他节点去。读取时,要读其他节点去。
- 挂掉一个节点,没关系,还有其他节点可以备份;甚至,挂掉某一个机架,也没关系;其他机架上,也有备份。
读操作
读操作就简单一些了,如图所示,client要从datanode上,读取FileA。而FileA由block1和block2组成。
那么,读操作流程为:
- client向namenode发送读请求。
- namenode查看Metadata信息,返回fileA的block的位置。
block1:host2,host1,host3
block2:host7,host8,host4 - block的位置是有先后顺序的,先读block1,再读block2。而且block1去host2上读取;然后block2,去host7上读取;
上面例子中,client位于机架外,那么如果client位于机架内某个DataNode上,例如,client是host6。那么读取的时候,遵循的规律是:优先读取本机架上的数据。
HDFS文件权限
与Linux文件权限类似:r-read w-write x-execute,权限x对于文件系统忽略,对于文件夹表示是否允许访问其内容。
如果Linux系统用户A使用hadoop命令创建一个文件,那么这个文件在hdfs中的owner就是A。HDFS权限的目的是阻止好人做错事,而不是阻止坏人做坏事,因为并没有密码校验,HDFS相信你告诉我是谁,你就是谁。
HDFS优缺点
hdfs优点:
- 容错性
- 适合批量处理
- 大规模数据
- 可构造在廉价机器上(因为容错性好)
hdfs缺点:
- 低延迟数据访问不行(因为数据量太大)
- 小文件不适合,会造成元数据很多。
- 并发写入、文件随机修改不适合。(例如很多网盘就是hadoop架构的,不能随意修改,只能删掉重传)