HDFS数据的读写过程(重点)

HDFS数据的读写过程(重点),第1张

(1)客户端通过FileSystem.open()打开文件,相应地,在HDFS文件系统中DistributedFileSystem具体实现了FileSystem。因此,调用了open()方法后,DistributedFileSystem会创建输游卜入流FSDataInputStream,对于HDFS而言,具体的输入流就是DFSInputStream.

(2)DFSInputStream的构造函数中,输入流通过ClientProtocal.getBloackLocations()远程调誉誉用NameNode,获得文件开始部分数据块的保存位置。对于该数据块。名称节点返回保存该数据块的锁哟数据节点的地址,同时根据距离客户端的远近对数据节点进行排序,然后DistributedFileSystem会利用DFSInputStream来实例化FSDataInputStream返回给客户端,同时返回了数据块的数据节点的地址。

(3)获得输入流FSDataInputStream后,客户端调用read()函数开始读取数据。输入流根据前面的排序结果,选择距离客户端最近的数据节点建立连接,然后读取数据。

(4)读取完毕后,关闭流,如果还有下一个数据块,就与下一个DN建立连接,读取数据块。

(1)客户端发起创建文件请求

(2)DistributedFileSystem通过RPC远程调用名称节点,在文件系统的命名空间中创建一个新的文件。名称节点会执行一些检查,比如这个文件是否存在,客户端是否有权限等。通过检查,名称节点会狗仔一个新文件,并且添加文件信息。然后返回给客户端一个输出流,客户端通过这个输出流,用它来写入数据。

(3)获得输出流FSDataOutputStream以后,客户端调用输出流的write方法想HDFS中对应的文件写入数据

客户端向输出流FSDataOutputStream中写入的数据会首先被分成一个个的分包,这些分包被放入DFSOutputStream对象的内部队列。每个包64K,包中有数据块,块是512字节,这些包被放入DFSOutputStream对象的内部队列,FSDataOutputStream向名称节点申请保存文件和副本数据块的若干数据节点。这些数据节点形成一个数据流管道,队列中的分包最后被打包成数据包,发往数据流管道第一个节点,第一个节点又复制到第二、三个节点,采用流水线复制策略(在写入磁盘时候 是每次4k往磁盘写)

(5)为保证所有数据节点的数据准备DataNode返回确认包 Client收到应答,将对庆磨段应分宝从内部队列移除。开始下一个分包。

建立、关闭与HDFS连接:hdfsConnect()、hdfsConnectAsUser()、hdfsDisconnect()。hdfsConnect()实际上是直接调用hdfsConnectAsUser。

打开、关羡拿谨闭HDFS文件:hdfsOpenFile()、hdfsCloseFile()。当用hdfsOpenFile()创建文件时,可以指定replication和blocksize参数。写打开一个文件时,隐含O_TRUNC标志,文件会被截断,写入是从文件头开始的。

读HDFS文件:hdfsRead()、hdfsPread()。两个函数都有可能返回少于用户要求的字节数,此时可以再次调用这两个函数读入剩下的部分(类似兄基APUE中的readn实现);只有在两个函数返回零时,我们才能断定到了文件末尾。

写HDFS文件:hdfsWrite()。HDFS不支持随机写,只能是从文件头顺序写入。

查询HDFS文件信息:hdfsGetPathInfo()

查询和设置HDFS文件读写偏移量:hdfsSeek()、hdfsTell()

查询数据块所在节点信息:hdfsGetHosts()。返回一个或多个数据块所在数据节点的信息,一个数据块可能存在多个数据节点上。

libhdfs中的函数是通过jni调用JAVA虚拟机,在虚拟机中构造对应的敏神HDFS的JAVA类,然后反射调用该类的功能函数。总会发生JVM和程序之间内存拷贝的动作,性能方面值得注意。

HDFS不支持多个客户端同时写入的 *** 作,无文件或是记录锁的概念。

建议只有超大文件才应该考虑放在HDFS上,而且最好对文件的访问是写一次,读多次。小文件不应该考虑放在HDFS上,得不偿失!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8201476.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存