HDFS读写流程

1.写流程

详细流程:

  • 创建文件:

    • HDFS客户端向HDFS写数据,先调用DistributedFileSystem.create()方法,在HDFS创建新的空文件

    • RPC(ClientProtocol.create())远程过程调用NameNode(NameNodeRpcServer)的create(),首先在HDFS目录树指定路径添加新文件

    • 然后将创建新文件的操作记录在editslog中

    • NameNode.create方法执行完后,DistributedFileSystem.create()返回FSDataOutputStream,它本质是封装了一个DFSOutputStream对象

  • 建立数据流管道:

    • 客户端调用DFSOutputStream.write()写数据

    • DFSOutputStream调用ClientProtocol.addBlock(),首先向NameNode申请一个空的数据块

    • addBlock()返回LocatedBlock对象,对象包含当前数据块的所有datanode的位置信息

    • 根据位置信息,建立数据流管道

  • 向数据流管道pipeline中写当前块的数据:

    • 客户端向流管道中写数据,先将数据写入一个检验块chunk中,大小512Byte,写满后,计算chunk的检验和checksum值(4Byte)

    • 然后将chunk数据本身加上checksum,形成一个带checksum值的chunk(516Byte)

    • 保存到一个更大一些的结构packet数据包中,packet为64kB大小

  • packet写满后,先被写入一个dataQueue队列中

    • packet被从队列中取出,向pipeline中写入,先写入datanode1,再从datanoe1传到datanode2,再从datanode2传到datanode3中

  • 一个packet数据取完后,后被放入到ackQueue中等待pipeline关于该packet的ack的反馈

    • 每个packet都会有ack确认包,逆pipeline(dn3 -> dn2 -> dn1)传回输出流

  • 若packet的ack是SUCCESS成功的,则从ackQueue中,将packet删除;否则,将packet从ackQueue中取出,重新放入dataQueue,重新发送

    • 如果当前块写完后,文件还有其它块要写,那么再调用addBlock方法(流程同上

  • 文件最后一个block块数据写完后,会再发送一个空的packet,表示当前block写完了,然后关闭pipeline

    • 所有块写完,close()关闭流

  • ClientProtocol.complete()通知namenode当前文件所有块写完了

容错:

在写的过程中,pipeline中的datanode出现故障(如网络不通),输出流如何恢复

  • 输出流中ackQueue缓存的所有packet会被重新加入dataQueue

  • 输出流调用ClientProtocol.updateBlockForPipeline(),为block申请一个新的时间戳,namenode会记录新时间戳

  • 确保故障datanode即使恢复,但由于其上的block时间戳与namenode记录的新的时间戳不一致,故障datanode上的block进而被删除

  • 故障的datanode从pipeline中删除

  • 输出流调用ClientProtocol.getAdditionalDatanode()通知namenode分配新的datanode到数据流pipeline中,并使用新的时间戳建立pipeline

  • 新添加到pipeline中的datanode,目前还没有存储这个新的block,HDFS客户端通过DataTransferProtocol通知pipeline中的一个datanode复制这个block到新的datanode中

  • pipeline重建后,输出流调用ClientProtocol.updatePipeline(),更新namenode中的元数据

  • 故障恢复完毕,完成后续的写入流程

2.读流程

详细流程:

  • 1、client端读取HDFS文件,client调用文件系统对象DistributedFileSystem的open方法

  • 2、返回FSDataInputStream对象(对DFSInputStream的包装)

  • 3、构造DFSInputStream对象时,调用namenode的getBlockLocations方法,获得file的开始若干block(如blk1, blk2, blk3, blk4)的存储datanode(以下简称dn)列表;针对每个block的dn列表,会根据网络拓扑做排序,离client近的排在前;

  • 4、调用DFSInputStream的read方法,先读取blk1的数据,与client最近的datanode建立连接,读取数据

  • 5、读取完后,关闭与dn建立的流

  • 6、读取下一个block,如blk2的数据(重复步骤4、5、6)

  • 7、这一批block读取完后,再读取下一批block的数据(重复3、4、5、6、7)

  • 8、完成文件数据读取后,调用FSDataInputStream的close方法

容错:

  • 情况一:读取block过程中,client与datanode通信中断

    • client与存储此block的第二个datandoe建立连接,读取数据

    • 记录此有问题的datanode,不会再从它上读取数据

  • 情况二:client读取block,发现block数据有问题

    • client读取block数据时,同时会读取到block的校验和,若client针对读取过来的block数据,计算检验和,其值与读取过来的校验和不一样,说明block数据损坏

    • client从存储此block副本的其它datanode上读取block数据(也会计算校验和)

    • 同时,client会告知namenode此情况

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
HDFSHadoop Distributed File System)是Hadoop生态系统中的一部分,它是一个可伸缩的分布式文件系统,可以在大型集群中存储和处理超大型数据集。下面是HDFS读写流程和原理: 1. 写入流程 (1)客户端向NameNode请求写入文件,NameNode返回一个DataNode列表,客户端接收到后与DataNode进行数据通信。 (2)客户端将数据划分为一个个数据块,并与DataNode建立连接,将数据块写入DataNode。 (3)DataNode接收到数据块后,先将数据写入本地磁盘,然后将数据块复制到其他DataNode上,以实现数据备份。 (4)客户端在写入完数据后,向NameNode发送文件元数据,即文件名、数据块ID、数据块所在的DataNode等信息,NameNode将这些信息保存在内存中,并更新元数据信息。 2. 读取流程 (1)客户端向NameNode请求读取文件,NameNode返回一个DataNode列表和对应的数据块位置信息。 (2)客户端与DataNode建立连接,请求数据块,DataNode将数据块返回给客户端。 (3)客户端读取完所有数据块后,将数据块组合成完整的文件。 HDFS的主要原理是数据分片和复制。HDFS将大文件划分为多个数据块,每个数据块默认大小为128MB,每个数据块会复制到多个DataNode上,以实现数据备份和容错。NameNode负责管理文件系统的元数据,包括文件名、文件目录、数据块位置等信息,而DataNode则负责数据块的存储和读写。这种分布式存储方式可以实现高可用性和高可靠性,并且可以通过增加DataNode数量来提高存储和读写性能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值