在hadoop中作为后端存储的文件系统HDFS发挥中重要的作用,HDFS是一个分布式文件系统,按照Google File System的思想开发的,针对的场景是低端服务器、写操作少而读操作多的情况。在HDFS中为了保证数据的完整和可靠,使用了多种方式,比如采用检验和(checksum)和多副本放置的策略,在HDFS中很常用的检验和方式采用的是CRC(循环冗余校验码)。HDFS是一种基于块的文件系统,采用的基本思想和ext文件系统的基本思想类似,只不过这是一个分布式文件系统。

下面是几个关于HDFS中重要的基本概念:

1、Block: 在HDFS中,每个文件都是采用的分块的方式存储,每个block放在不同的datanode上,每个block的标识是一个三元组(block id, numBytes,generationStamp),其中block id是具有唯一性,具体分配是由namenode节点设置,然后再由datanode上建立block文件,同时建立对应block meta文件(其中的内容,大部分是对应数据的检验和内容)。

2、Chunk:对应的中文名字也可以称为块,但是为了与block区分,还是称之为chunk。在DFSClient与DataNode之间通信的过程中,由于文件采用的是基于块的方式来进行的,但是在发送数据的过程中是以packet的方式来进行的,每个packet包含了多个chunk,同时对于每个chunk进行checksum计算,生成checksum bytes。

3、Packet:在DFSclient与DataNode之间通信的过程中,发送和接受数据过程都是以一个packet为基础的方式进行。

 关于HDFS中进行通信的数据包(Packet)的格式如下:

+-----------------------------------------------------------------------+
   |    4 byte packet length(exclude packet header)            | 
  +------------------------------------------------------------------------+
   |   8 byte offset in the block | 8 byte sequence number   |
  +------------------------------------------------------------------------+
   |                 1 byte isLastPacketInBlock                           |
  +------------------------------------------------------------------------+
  |                 4 byte Length of actual data                           |
 +-------------------------------------------------------------------------+
  |           x byte checksum data. x is defined below            |
 +-------------------------------------------------------------------------+
  |           actual data .........                                                  |
 +--------------------------------------------------------------------------+

x = (length of data + BYTE_PER_CHECKSUM - 1) / BYTE_PER_CHECKSUM * CHECKSUM_SIZE

在DFSclient与DataNode进行通信,采用的是经典的C/S结构。在DFSClient从DataNode节点上读取数据的过程中,比较中的几个数据类是FSDataInputStream、DFSDataInputStream、DFSinputStream。下面为HDFS中read的过程:

1、文件系统读操作read,获取的类型对象为FSDataInputStream,通过fs.open操作获得,对于具体的HDFS文件系统,则采用的是通过DFSDataInputStream进行具体操作,每次获取一个DFSDataInputStream时,通过包含DFSInputStream 来进行具体的HDFS文件系统读read操作。

2、通过建立DFSInputStream对象,采用预取的方式,从NameNode中获得多个文件块的位置信息(LocatedBlocks),然后在DFSClient端缓存这些Block位置信息

3、对于DFSclient发出的每次read操作,统一转换成的格式为read(byte[ ] buffer, int offset, int len)这种DFSInputStream对象的系统调用,在read操作中比较重要的两个方法为blockSeekTo(long pos)和readBuffer(byte[ ] buffer, int offset, int len),所有具体的操作都转换成这两种操作。

4、方法blockSeekTo(long pos)作用是定位到具体的DataNode上去,同时建立具体的BlockReader对象,因为HDFS采用了ShortCircuitRead的优化措施,所以对于本地的DataNode节点上的读取操作则创建的为BlockReaderLocal对象,而对于远端的DataNode则建立RemoteBlockReader对象进行接下来的操作。接下来重点介绍的是RemoteBlockReader对象与DataNode的交互过程。

5、在建立具体的BlockReader对象之后,通过readbuffer操作,使用blockreader对象的read方法进行数据的读取操作。

下面是RemoteBlockReader建立与DataNode之间的通信过程:

RemoteBlockReader与DataNode之间通信的协议过程:

  1、RemoteBlockReader端的通信:

a、RemoteBlockReader请求通信,通信头部格式如下:

+------------------------------------------------------+
|  2 byte DATA_TRANSFER_VERSION     |
+------------------------------------------------------+
|          1 byte OP_READ_BLOCK              |
+------------------------------------------------------+
|                8 byte BLOCK_ID                      |
+------------------------------------------------------+
|  8 byte BLOCK_GENERATION_STAMP |
+------------------------------------------------------+
|                8 byte startOffset                       |
+------------------------------------------------------+
|                  8 byte length                            |
+------------------------------------------------------+
|              text client_name                          |
+------------------------------------------------------+
|                        accessToken                     |
+------------------------------------------------------+

b、DataNode受到RemoteBlockReader的读取数据请求之后,发送响应信息,如果成功,则为OP_STATUS_SUCCESS。

c、接下来就是获取相应的检验和的类型checksum,同时在本地建立相应的checksum。DataNode返回具体的firstChunkOffset信息。

d、执行具体的read(byte[ ] buffer, int offset, int len)时,使用的是RemoteBlockReader的借口FSInputChecker里面的方法,通过检查,如果发现相应的buffer里面的data不存在的时候,则执行具体的readchunk操作,从DataNode中的BlockSender中读取相应的chunk数据信息,同时读取检验和,DataNode使用的是packet数据格式发送数据,在RemoteBlockReader读取数据后,进行checksum检查,如果发现不一致的情况,则向NameNode报告这个Block出现了问题,如果没有什么问题,则向DataNode报告检验和正常,当一个block读取完成后,DataNode上的BlockScanner就可以不用扫描这个Block,检查Block的完整信息。

2、DataNode端的通信:

a、DataNode上启动DataXceiverServer对象,用于侦听来自DFSclient或者其他DataNode上的连接请求,当有一个连接请求的时候建立一个DataXceiver对象为之服务

b、DataXceiver对象接受来自DFSClient端的请求头部,首先进行数据头部报文的识别。如果不是DATA_TRANSFER_VERSION类型,报告类型不匹配错误。然后读取DFSClient发送的读取的操作类型信息,如果是OP_READ_BLOCK,则执行readBlock()。

c、在DataNode端建立具体的BlockSender类型对象,这个对象用于具体的数据block发送操作,在DataNode端,从disk上读读取整个Block内核中去。在BlockSender中读取Block中使用了内核优化措施,调用NativeIO方法。在发送数据的时候也使用了内核优化措施,不用经过内核态-》用户态-》内核态的过程,有效的减少了时间。

以上大致就是HDFS中涉及到的Read过程。

HDFS的Read过程分析的更多相关文章

  1. HDFS读文件过程分析:读取文件的Block数据

    转自http://shiyanjun.cn/archives/962.html 我们可以从java.io.InputStream类中看到,抽象出一个read方法,用来读取已经打开的InputStrea ...

  2. HDFS写文件过程分析

    转自http://shiyanjun.cn/archives/942.html HDFS是一个分布式文件系统,在HDFS上写文件的过程与我们平时使用的单机文件系统非常不同,从宏观上来看,在HDFS文件 ...

  3. hdfs架构详解(防脑裂fencing机制值得学习)

    HDFS(Hadoop Distributed File System)是一个分布式文件存储系统,几乎是离线存储领域的标准解决方案(有能力自研的大厂列外),业内应用非常广泛.近段抽时间,看一下 HDF ...

  4. Hadoop日记Day11---主从节点接口分析

    一.NameNode 的接口分析 1. NameNode本质 经过前面的学习,可以知道NameNode 本身就是一个java 进程.观察RPC.getServer()方法的第一个参数,发现是this, ...

  5. HDFS的写数据过程分析

    HDFS的写数据过程分析 我们通过FileSystem类可以操控HDFS, 那我们就从这里开始分析写数据到HDFS的过程. 在我们向 HDFS 写文件的时候,调用的是 FileSystem.creat ...

  6. [HDFS_add_1] HDFS 启动过程分析

    0. 说明 HDFS 文件概念 && HDFS 启动过程分析 1. HDFS 文件概念 [1.1 NameNode 职能] 存储文件类型.大小.权限.路径等等元数据 通过 edits( ...

  7. HDFS的读数据过程分析

    我们继续在 FileSystem 类分析,读数据使用的是 open(-)方法,我们可以看到源码 FSDataInputStream in = fileSystem.open(new Path(&quo ...

  8. hadoop2.2原理:分析HDFS的文件读写

    File Read 程序举例: public class FileRead { public static void main(Sting[] args) throws Exception { Con ...

  9. 深入浅出Hadoop实战开发(HDFS实战图片、MapReduce、HBase实战微博、Hive应用)

    Hadoop是什么,为什么要学习Hadoop?     Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运 ...

随机推荐

  1. DB2 Metadata

    http://www.devart.com/dotconnect/db2/docs/MetaData.html Instead of specifying the metadata collectio ...

  2. 转:在使用angularjs过程,ng-repeat中track by的作用

    转载:链接 <div ng-repeat="links in slides"> <div ng-repeat="link in links track ...

  3. JS之 if语句函数 对接事件动作 函数更改css css对接需要换妆的区id或class

      if 函数的实现步骤: function +名字() 指定id , 指定开关(display: none or block) if + else 构成逻辑 控制开关 决定在哪里安置一个灯泡, 指定 ...

  4. webpack+vue2实现旅游网小demo

    这两天自己练习做了一个webpack+vue2的旅游app小项目,涉及到的内容是vue组件.vue路由以及webpack打包.         目录文件设计: 有兴趣的可到我的百度网盘下载 链接: h ...

  5. Java设计模式—命令模式

    命令模式是一个高内聚的模式. 定义如下:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 通用类图如下: 角色说明: ● Re ...

  6. Python爬虫教程-08-post介绍(百度翻译)(下)

    Python爬虫教程-08-post介绍(下) 为了更多的设置请求信息,单纯的通过urlopen已经不太能满足需求,此时需要使用request.Request类 构造Request 实例 req = ...

  7. 代码整洁之道读书笔记(Ch4-Ch7)

    这几章从注释.程序格式.对象与数据结构的规范以及错误处理四个方面介绍了如何使代码变得简洁易懂.不同于上次摘抄的方法,这一次我会结合第一次个人作业的代码进行分析. 第四章  注释 这一章告诉我们,好的注 ...

  8. Python中的基础数据类型

    Python中基础数据类型 1.数字 整型a=12或者a=int(2),本质上各种数据类型都可看成是类,声明一个变量时候则是在实例化一个类. 整型具备的功能: class int(object): & ...

  9. 使用JSONP彻底解决Ajax跨域访问Cookie Session的方案

    最近做开发时要把图片文件放到另外一台服务器上(另外一个域名),因为这样分布式存放,网站打开速度会快很多.而我采用AJAX获取图片服务器上某用户的图片时遇到了问题,按照通常的方式无法获取信息,得到的Co ...

  10. C# 数据类型转换 显式转型、隐式转型、强制转型

    C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...