HDFS读写

本文详细阐述了HDFS的文件访问机制,包括流式读写流程,特别是客户端如何通过RPC协议与NameNode和DataNode交互,以及DFSOutputStream在数据传输中的作用。同时介绍了RPC在Hadoop内部服务通信中的重要性。
摘要由CSDN通过智能技术生成

HDFS 的文件访问机制为流式访问机制:即通过 API 打开文件的某个数据块之后,可以顺序读取或者写入某个文件.
由于 HDFS 中存在多个角色,且对应的应用场景主要为一次写入、多次读取的场景,因此其读和写的方式有较大不同.
读、写操作都由客户端 Client 发起,并且由客户端进行整个流程的控制,NameNode 和 DataNode 都是被动式响应.

读取流程

  1. 客户端发起读取请求时,首先与 NameNode 进行连接;
  2. 建立连接完成后,客户端会请求读取某个文件的某一个数据块;
  3. NameNode 在内存中进行检索,查看是否有对应的文件及文件块;
    若没有则通知客户端对应文件或数据块不存在,
    若有则通知客户端对应的数据块存在哪些DataNode上;
  4. 客户端接收到信息之后,首先选择离它最近的一个DataNode 进行连接–[就近原则]
  5. 客户端与最近的 DataNode 连接后,开始进行数据传输–[客户端直接与存储数据的DataNode进行通信]

读取文件的具体过程如下图所示:
在这里插入图片描述

读取流程原理

  1. 客户端调用 DistributedFileSystem(分布式文件系统)的 Open() 方法打开文件;
  2. DistributedFileSystem 用 RPC 协议连接到 NameNode,请求获取文件的数据块的信息;
    NameNode 返回文件的部分或者全部数据块列表;
    对于每个数据块,NameNode 都会返回该数据块副本的所有 DataNode 地址;
    DistributedFileSystem 返回 FSDataInputStream(文件数据输入流)给客户端,用来读取数据.
  3. 客户端调用 FSDataInputStream 的 Read() 方法开始读取数据;
  4. FSInputStream 连接保存此文件第一个数据块的最近的 DataNode,并以数据流的形式读取数据;
    客户端多次调用 Read(),直到到达数据块结束位置.
  5. FSInputStream 连接保存此文件下一个数据块的最近的 DataNode,并读取数据;
  6. 当客户端读取完所有数据块的数据后,调用 FSDataInputStream 的 Close() 方法.
    在读取数据的过程中,如果客户端在与数据结点通信时出现错误,则尝试连接包含此数据块的下一个数据结点;失败的数据结点将被记录,并且以后不再连接.

写入流程

  1. 客户端向NameNode发出写文件请求.
  2. 检查是否已存在文件、检查权限;若通过检查,直接先将操作写入EditLog,并返回输出流对象.
    [WAL-write ahead log:先写Log,再写内存;
    因为EditLog记录的是最新的HDFS客户端执行所有的写操作,如果后续真实写操作失败了,
    由于在真实写操作之前,操作就被写入EditLog中了,故EditLog中仍会有记录,我们不用担心后续client读不到相应的数据块,
    因为在第5步中DataNode收到块后会有一返回确认信息,若没写成功,发送端没收到确认信息,会一直重试,直到成功]
  3. Client端按128MB的块切分文件.
  4. Client将NameNode返回的分配的可写的DataNode列表和Data数据一同发送给最近的第一个DataNode节点,
    此后Client端和NameNode分配的多个DataNode构成pipeline管道,Client端向输出流对象中写数据;
    Client每向第一个DataNode写入一个packet,这个packet便会直接在pipeline里传给第二个、第三个…DataNode.
    [注:并不是写好一个块或一整个文件后才向后分发]
  5. 每个DataNode写完一个块后,会返回确认信息.
    [注:并不是每写完一个packet后就返回确认信息,因为packet中的每个chunk都携带校验信息,没必要每写一个就汇报一下,
    这样效率太慢;正确的做法是写完一个block块后,对校验信息进行汇总分析,就能得出是否有块写错的情况发生]
  6. 写完数据,关闭输输出流.
  7. 发送完成信号给NameNode.
    [注:发送完成信号的时机取决于集群是强一致性还是最终一致性,强一致性则需要所有DataNode写完后才向NameNode汇报;
    最终一致性则其中任意一个DataNode写完后就能单独向NameNode汇报, HDFS一般情况下都是强调强一致性]

写入文件的过程比读取较为复杂,在不发生任何异常情况下,客户端向 HDFS 写入数据的流程如下图所示:
在这里插入图片描述

写入流程原理

  1. 客户端调用 DistribuedFileSystem 的 Create() 方法来创建文件.
  2. DistributedFileSystem 用 RPC 协议连接 NameNode,请求在文件系统的命名空间中创建一个新的文件;
    NameNode 首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件;
    DistributedFileSystem 返回 FSOutputStream 给客户端用于写数据.
  3. 客户端调用 FSOutputStream 的 Write() 函数,向对应的文件写入数据.
  4. 当客户端开始写入文件时,FSOutputStream 会将文件切分成多个分包(Packet),并写入其內部的数据队列;
    FSOutputStream 向 NameNode 申请用来保存文件和副本数据块的若干个 DataNode,这些 DataNode 形成一个数据流管道;
    队列中的分包被打包成数据包,发往数据流管道中的第一个 DataNode;
    第一个 DataNode 将数据包发送给第二个 DataNode,第二个 DataNode 将数据包发送到第三个 DataNode(复制过程)
    这样,数据包会流经管道上的各个 DataNode。
  5. 为了保证所有 DataNode 的数据都是准确的,接收到数据的 DataNode 要向发送者发送确认包(ACK Packet).
    确认包沿着数据流管道反向而上,从数据流管道依次经过各个 DataNode,并最终发往客户端;
    当客户端收到应答时,它将对应的分包从内部队列中移除。
  6. 不断执行第 (3)~(5)步,直到数据全部写完。
  7. 调用 FSOutputStream 的 Close() 方法,将所有的数据块写入数据流管道中的数据结点,并等待确认返回成功;
    最后通过 NameNode 完成写入.
/**
Question:客户端是怎么将数据传输给DataNode的呢? 
通过NIO! 
向HDFS上传文件时,主要是通过DistributedFileSystem里的DFSOutputStream实现。
DFSOutputStream 中有个 DataStreamer streamer(负责开启线程,通过nio的方式将Packet传输至hdfs) 对象 
DataStreamer 里有个 DataOutputStream blockStream (里面实现了SocketOutputStream接口,负责发送Packet)
文件数据的传输单位为Packet,一个Packet默认大小为64K,一个Packet中含有多个chunk,chunk为校验数据的单位,默认大小512byte。
*/
源码
void waitForIO(int ops) throws IOException {
    if(selector.select(channel,ops,timeout) == 0){
        throw new SocketTimeoutException(timeoutExceptionString(channel,timeout,ops));
    }
}

RPC 协议

RPC[Remote Procedure Call]—远程过程调用协议:是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.
RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。
RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
RPC采用客户机/服务器模式:请求程序就是一个客户机,而服务提供程序就是一个服务器。
过程:

  1. 首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。
  2. 在服务器端,进程保持睡眠状态直到调用信息到达为止。
    当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息。
  3. 最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
    对比HTTP协议:
    RPC的核心并不在于使用什么协议。
    RPC的目的是让你在本地调用远程的方法,而对你来说这个调用是透明的,你并不知道这个调用的方法是部署哪里。
    通过RPC能解耦服务,这才是使用RPC的真正目的;
    RPC主要用在内部服务间的通信。
    因为Hadoop服务器之间已经建立了互信(SSH)所以使用 RPC 比 HTTP 的请求与响应更快!
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
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数量来提高存储和读写性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早拾碗吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值