HDFS Client如何从Datanode读取block

2019-03-28 13:21|来源: 网络

Datanode中包含DataXceiverServer。DataXceiverServer是一个socket server,负责接收client发起的socket连接。DataXceiverServer接收到一个socket连接后,启动一个线程DataXceiver,由DataXceiver具体负责该scoket的处理。DataXceiver从client读取client想要进行操作的操作码。如果操作码是OP_READ_BLOCK,则DataXceiver负责读取该block,并将其发送给client。

读取block数据传输格式

Client为了从Datanode读取block,按照一定的格式向Datanode发送指令及其他一些数据,具体的格式如下:

Ø operator:byte Client所需要的操作,读取一个block、写入一个block等等Ø version:short Client所需要的数据与Datanode所提供数据的版本是否一致

Ø blockId:long 所要读取block的blockId

Ø generationStamp:long 所需要读取block的generationStamp

Ø startOffset:long 读取block的的起始位置

Ø length:long 读取block的长度

Ø clientName:String Client的名字

Ø accessToken:Token Client提供的验证信息,用户名密码等

读取过程

DataXceiver首先按照上面的数据格式依次读取各变量。读取完成后,如果需要进行访问控制,则根据Client提供的accessToken进行验证。验证通过后,产生一个BlockSender实例blockSender,通过blockSender进行数据的读取与传输。这里有一个需要注意的地方,HDFS在保存文件的时候有几个非常重要的概念:一个文件由多个block构成。HDFS在进行block读写的时候是以packet为单位进行的。每一个packet由若干个chunk组成。Chunk是进行数据校验的基本单位,对每一个chunk生成一个校验和并将校验和进行存储(在默认情况下一个chunk的大小是512byte,生成的校验和是4byte)。在读取一个block的时候,数据传输的基本单位是packet,每个packet由若干个chunk组成。

为了读取一个block,首先从block的.meta文件中读取block的版本号、校验类型等,并生成相应的校验工具类。Meta文件的格式如下所示:

Ø version:short 所保存block的版本号

Ø checksumType:int 校验码的类型,要么没有校验码,要么是CRC32校验码(CHECKSUM_NULL、CHECKSUM_CRC32)

Ø bytesPerChecksum:int 表示这么校验和是由多少byte的源数据计算而来

Ø checksum:每一个chunk的校验和

这里有一个需要注意的地方,当读取数据的时候读取的起始位置必行是一个chunk的起始位置,如果client读取的起始位置不是chunk的起始位置,那么必须回退到chunk的起始位置开始读取。确定好位置后,Datanode以packet为单位依次发送block的数据,packet的具体格式如下图所示:

Ø packetLen:int packet的长度,包括数据、数据的校验等等

Ø offset:long packet在block中的偏移量

Ø sequenceNum:long 该packet在这次block读取时的序号

Ø isLastPacket:byte packet是否是最后一个

Ø dataLen:int 该packet所包含block数据的长度,纯数据不包括校验和其他

Ø checksum:该packet每一个chunk的校验和,有多少个chunk就有多少个校验和

Ø data:该packet所包含的block数据

相关问答

更多
  • 你的hadoop参数配置正确了吗?在hdfs-site.xml中把以下属性修改为true才可以。 dfs.support.append true 下面有一段测试代码,你可以参考一下: package com.wyp; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io. ...
  • 您可能会混淆“连续”和“顺序”这两个术语。 我们有顺序读/写(从/到磁盘)和“连续”磁盘空间分配。 单个64 MB的HDFS块将按顺序写入磁盘。 因此,数据很可能被写入磁盘上的连续空间(由多个彼此相邻的块组成)。 因此,与随机磁盘写入相比,磁盘/块碎片会低得多。 此外,顺序读/写比使用多个磁盘搜索的随机写更快。 有关详细信息,请参阅顺序写入和随机写入之间的区别 You may be confusing the terms "contiguous" and "sequential". We have sequ ...
  • 看看这篇文章: http : //blog.cloudera.com/blog/2013/08/how-improved-short-circuit-local-reads-bring-better-performance-and-security-to-hadoop/ 文章摘要: 原始实施的一个主要缺点是它与安全隐患相关。 它必须让客户直接读取数据文件。 我想这对于kerberos启用hdfs是不利的。 相反,新的实现传递一个文件描述符,这应该是更安全,更快速的。 我想这个旧方法有一些缺点。 我不明白新方 ...
  • 我遇到了异常,必须从安全集群中的根启动数据节点。 I have got through the exception, data node has to be started from the root in a secure cluster.
  • 你不会看到-ls命令中的单个块。 这些是在Linux的ls或Windows资源管理器中没有显示的硬盘上逻辑块的逻辑等价物。 您可以在命令行上执行此操作,如hdfs fsck /user/me/someFile.avro -files -blocks -locations ,或者您可以使用NameNode UI查看哪些主机具有文件块以及每个块在哪些主机上复制。 当然。 你只需要做一些像hdfs dfs -get /user/me/someFile.avro或者使用HUE或NameNode UI下载文件。 所有 ...
  • 这完全取决于你想用它做什么; 如果您要重复使用文件内容,您也可以将其复制到本地以将重复查找保存到HDFS,但如果您只需要阅读一次,那么直接来自HDFS没有任何危害,因为复制到本地将涉及阅读无论如何它从那里。 It depends entirely what you want to do with it; if you will be reusing the file contents, you might as well just copy it to local to save the repeat lo ...
  • HDFS与附加到它的数据节点一样大......所以通过添加更多硬件,您可以指定大小。 它不像你可以分区的磁盘(至少,不是一般意义上为特定任务分配特定大小的磁盘)。 HDFS is as large as the datanodes attached to it... So by adding more hardware you are specifying the size. It's not like a disk that you can partition (at least, not in the ...
  • 正如第一个链接中提到的那样 许多管理HDFS命令需要作为“hdfs”操作系统用户运行,这是默认的HDFS超级用户 默认超级用户通常是hdfs ,但不一定。 ...... Hadoop没有固定的超级用户。 Hadoop的系统超级用户只是启动NameNode的操作系统用户。 HDFS超级用户不必是NameNode主机的root用户 HDFS中没有真正的“用户/组”。 默认情况下,它是来自本地操作系统用户的所有字符串。 任何用户都可以覆盖 。 没有Kerberos,Hadoop绝对没有真正的授权。 如果启用per ...
  • 可以使用前缀file:///从Spark引用本地文件系统 Eg: sparkContext.textFile("file:///<>") 此命令从本地文件系统读取文件。 注意:如果在多节点群集中执行,则此文件应在所有节点上可用。 Local filesystem can be referred from Spark with the prefix file:/// Eg: sparkContext.textFile("file:///<
  • 您可以使用以下格式进行编码: sc.textFile(hdfs://NamenodeIPAddress:Port/DirectoryLocation) example: sc.textFile(hdfs://127.0.0.1:8020/user/movies) 请根据您的位置更改您的名称节点IP地址和路径的IP地址。 希望这可以帮助!!!... You can code in the below format: sc.textFile(hdfs://NamenodeIPAddress:Port/Dir ...