
《HDFS读写原理》由会员分享,可在线阅读,更多相关《HDFS读写原理(25页珍藏版)》请在文档大全上搜索。
1、北京北大方正电子有限公司Beijing Founder Electronics Co., L方正集团IT产业集信息产业之大成,提供IT服务、软件、硬件和数据运营在内的综合解决方案。Founder Groups IT sector is a leader in the information industry, providing comprehensive resolutions, including IT services, software, hardware, and data operation.Hadoop分布式文件系统(HDFS)读写原理剖析NameNodeNameNode管理两个
2、重要的表:pFilename block sequence(namespace)pBlock machine List(“inodes”)三种协议接口:pClientProtocol ClientspDatanodeProtocol DataNodespNamenodeProtocol SecondNameNode & rebalancing processes启动方式:p以-format方式启动-在最初时,对系统进行格式化p以集群方式启动-更新和创建当前文件系统的快照p以备份的方式启动-将集群的状态回滚到前一个状态启动两个进程:pRPCServerpHTTPServerDateNode储存一
3、系列named blocks允许客户端读blocks, 或者写new blockdelete blocks 或 copy blocks 听令于NameNode管理一个重要的表pblock- stream of bytespDataNode会定期向NameNode报告block的信息开启一个server socket,以便客户端读写,DataNode会把socket的ip/port报告给NameNode,NameNode会把ip/port发给请求读写的客户端构造一个NameNode的RPC代理报告心跳启动一个无线循环,向NameNode询问有什么事情可做心跳为了整个系统的稳定,数据服务器必须时刻
4、向主控服务器汇报,保持主控服务器对其的完全了解,这个机制,就是心跳消息。在HDFS中,主控服务器NameNode实现了DatanodeProtocol接口,数据服务器DataNode会在主循环中,不停的调用该协议中的sendHeartbeat方法,向NameNode汇报状况。在此调用中,DataNode会将其整体运行状况告知NameNode,比如:有多少可用空间、用了多大的空间,等等之类。NameNode会记住此DataNode的运行状况,作为新的数据块分配或是负载均衡的依据。当NameNode处理完成此消息后,会将相关的指令封装成一个DatanodeCommand对象,交还给DataNode
5、,告诉数据服务器什么数据块要删除什么数据块要新增等等之类,数据服务器以此为自己的行动依据。Block报告DatanodeProtocol定义的另一个方法,blockReport。DataNode也是在主循环中定时调用此方法,只是,其周期通常比调用sendHeartbeat的更长。它会提交本地的所有数据块状况给NameNode,NameNode会和本地保存的数据块信息比较,决定什么该删除什么该新增,并将相关结果缓存在本地对应的数据结构中,等待此服务器再发送sendHeartbeat消息过来的时候,依照这些数据结构中的内容,做出相应的DatanodeCommand指令。HDFS文件系统结构INod
6、e是对文件系统目录结构中一个节点的抽象,也叫元数据pINodeFile和INodeDirectory均继承自INode类,分别表示文件节点和目录节点pINodeFile类中最重要的数据结构是BlockInfo blocks,它记录了一个文件所包含的所有Block,成员方法的操作大都与Block相关pINodeDirectory的关键数据结构是Listchildren记录了目录下所有的子节点信息INodefileUnderConstruction表示正在建的文件INodeDirectoryWithQuota表示有配额限制的目录,根目录就是这种类型FSdirectory:存储整个文件系统的目录状态
7、,对整个目录结构的管理p通过调用fsimage和editLog的方法从namenode本地磁盘读取元数据信息和向本地磁盘写入元数据信息,并登记对目录结构所作的修改到日志文件。另外,FSDirectory保存了文件名和数据块的映射关系。HDFS文件系统结构fsimage :把文件和目录的元数据信息持久化地存储到fsimage文件中p每次启动时从中将元数据加载到内存中构建目录结构树,之后的操作记录在edits log中p定期将edits与fsimage合并刷到fsimage中loadFSImage(File curFile)用于从fsimage中读入Namenode持久化的信息。fsimage是一
8、个二进制文件,当中记录了HDFS中所有文件和目录的元数据信息,格式如下:fsimage和edits日志统称为此系统的镜像,当namenode宕机后,secondaryNamenode就是通过这个镜像恢复系统的。fsimage和edits加载过程namenodesecondaryNameNodecheckpoint步骤第一步:secondary namenode请求namenode停止使用edits,暂时记录在edits.new文件中第二步:secondary namenode从namenode复制fsimage、edits到本地第三步:secondary namenode合并fsimage、e
9、dits为fsimage.ckpt第四步:secondary namenode发送fsimage.ckpt到namenode第五步:namenode用新的fsimage覆盖旧的fsimage,用新的edits覆盖旧的edits第六步:更新checkpoint时间到这里fsimage更新完毕,即保证了primary正常服务,也完成了fsimage的更新GenerationStamp(1) GenerationStamp存在的两个原因p检测过期副本p当Dead Datanode在过了很长一段时间后又重新加入集群时,可以通过GenerationStamp检测pre-historic副本(2) 在以下
10、情形下需要生成GenerationStamp p创建一个新文件p当client append 或 truncate 一个已经存在的文件p当client在写入数据到Datanode(s)时碰到错误或异常时需要申请一个新的GenerationStamp pNamenode开始对一个文件进行lease recovery时SecondaryNameNode恢复机制镜像文件:pfsimage:保存HDFS的状态信息,每次启动时从fsimage将元数据加载到内存中构建目录结构树pedits日志:操作记录在edits log中,定期将edits与fsimage合并刷到fsimageNameNode启动时,会
11、读取fsimage和editsSecnamenode定期拷贝fsimage和edits合并后再传给namenode如果NameNode节点挂了,可以按照如下步骤来恢复:p在dfs.name.dir指定的位置建立一个空文件夹p从Secondary NameNode上把secondname的目录给scp到新的NameNode机器的fs.checkpoint.dir下p使用hadoop namenode importCheckpoint来启动NameNode,不要执行format命令p使用hadoop fsck 命令检查文件Block的完整性HDFS写文件客户端的操作pFileSystem hdfs
12、 = FileSystem.get(new Configuration();pFSDataOutputStream dos = hdfs.create(path);pdos.write(readBuf, 0, readBuf.length);HDFS写文件Step1:创建INodep检验路径是否存在p检验客户端是否有权限写p新建INode,并将其挂载到目录结构树上,此时INode代表当前目录p将INode标记为INodefileUnderConstructionp将此INode的租约赋给请求客户端p此过程中会将replications和blocksize等参数传给namenodeStep2:准
13、备数据p启动DataStreamer线程,dataQueue队列wait数据p客户端将文件分成若干个packet,放到dataQueue,并唤醒DataStreamer进程租约租约,就是当客户端需要占用某文件的时候,与主控服务器签订的一个短期合同。合同有一个期限,在这个期限内,客户端可以延长合同期限,一旦超过期限,主控服务器会强行终止此租约,将这个文件的享用权,分配给他人。客户端会启动DFSClient.LeaseChecker线程,定时轮询调用ClientProtocol的renewLease方法,续签租约。在Namenode一端,有一个LeaseManager.Monitor线程,始终在轮
14、询检查所有租约,查看是否有到期未续的租约。如果一切正常,该客户端完成写操作,会关闭文件,停止租约,一旦有所意外,比如文件被删除了,客户端宕机了,Namenode都会剥夺此租约,如此,来避免由于客户端停机带来的资源被长期霸占的问题。HDFS文件存储与传输构成一个文件由多个block构成(默认64M)HDFS在进行block读写的时候是以packet为单位进行的每一个packet由若干个chunk组成(一个packet默认是64K)Chunk是进行数据校验的基本单位,对每一个chunk生成一个校验和并将校验和进行存储(在默认情况下一个chunk的大小是512byte,生成的 校验和是4byte)H
15、DFS写文件Step3:申请blockp向namenode申请blockpNamenode选取备份个datanode组成管道p将新生成的block添加到blockMap中,将block,datanode,INode三者关联p将新生成的block和datanode列表发送给客户端Step4:建立双向流水线pClient向datanode列表中的第一个datanode发送请求头,开启ResponseProcessor进程,等待响应pDataNode建立DataXceiver来处理写消息,DataXceiver会依照包中传过来的其他服务器的信息,建立与下一个 服务器的连接,并生成类似的头,发送给它,
16、并等待回包。此流程依次延续,直到最后一级,它发送回包,反向着逐级传递,再次回到客户端。如果一切顺利,那么 此时,流水线建立成功,开始正式发送数据。Hadoop集群物理部署NameNode总是为第一份冗余优先选择本地节点作为存储空间,对于第二份冗余,则是优先选择另一个机架的节点。如果前两份冗余位于不同机架,第三份冗余偏向于选择与第一份冗余相同的机架,否则选择不同的机架。大于三份的冗余随机挑选节点了。HDFS文件系统映射关系表BlocksMap:pblock-datanode的信息没有持久化存储,而是namenode通过datanode的blockreport获取block-datanode li
17、stpBlocksMap负责维护了三种信息: nblock-datanode listnblock-INodeFilendatanode-blocks三元组的第一个元素表示该block所属的Datanode,类型是DatanodeDescriptor,通过它获得block-datanode list第二/三个元素表示该block所在Datanode上的前/后一个block(前驱和后继),类型是BlockInfo,通过它获得datanode-blocksblock-INodeFileHDFS写文件Step5:写数据pDataStreamer会时刻监听dataQueue队列,一旦不为空,则开始发送
18、,将dataQueue队首的包移到ackQueue队尾,表明已经发送,但未接收到ackpDatanode收到packet后,一边写本地,一边转发给下一个datanode,并开启ResponseProcessor监听pResponseProcessor线程监听ack,直到收到相应packet的ack,才将此packet从ackQueue中移除,此时才算发送成功错误恢复HDFS读文件Step1:定位blockpNamenode根据client提供的路径,获得INode对象p根据INode对象获得blocksp通过blockMap,根据blocks获得datanode列表p获得所有的block和bl
19、ock所在的datanode(包括副本)信息p计算每个datanode与client之间的距离(local,rack,随机)p将排好序的blockLocation信息返回给client,生成输入流DFSInputStreamStep2:读取Block信息pDFSInputStream 连 接 第 一 个 block 的DataNodepDatanode read block 数据,传回给 clientp当第一个 block 读完,DFSInputStream 关掉与这个 DataNode 的连接。然后开始第二个 block,以此类推p在读的过程中,如果 client 和一个 datanode 通讯时出错,他会连接副本所在的 datanode。