HDFS的Read过程分析
在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过程分析的更多相关文章
- HDFS读文件过程分析:读取文件的Block数据
转自http://shiyanjun.cn/archives/962.html 我们可以从java.io.InputStream类中看到,抽象出一个read方法,用来读取已经打开的InputStrea ...
- HDFS写文件过程分析
转自http://shiyanjun.cn/archives/942.html HDFS是一个分布式文件系统,在HDFS上写文件的过程与我们平时使用的单机文件系统非常不同,从宏观上来看,在HDFS文件 ...
- hdfs架构详解(防脑裂fencing机制值得学习)
HDFS(Hadoop Distributed File System)是一个分布式文件存储系统,几乎是离线存储领域的标准解决方案(有能力自研的大厂列外),业内应用非常广泛.近段抽时间,看一下 HDF ...
- Hadoop日记Day11---主从节点接口分析
一.NameNode 的接口分析 1. NameNode本质 经过前面的学习,可以知道NameNode 本身就是一个java 进程.观察RPC.getServer()方法的第一个参数,发现是this, ...
- HDFS的写数据过程分析
HDFS的写数据过程分析 我们通过FileSystem类可以操控HDFS, 那我们就从这里开始分析写数据到HDFS的过程. 在我们向 HDFS 写文件的时候,调用的是 FileSystem.creat ...
- [HDFS_add_1] HDFS 启动过程分析
0. 说明 HDFS 文件概念 && HDFS 启动过程分析 1. HDFS 文件概念 [1.1 NameNode 职能] 存储文件类型.大小.权限.路径等等元数据 通过 edits( ...
- HDFS的读数据过程分析
我们继续在 FileSystem 类分析,读数据使用的是 open(-)方法,我们可以看到源码 FSDataInputStream in = fileSystem.open(new Path(&quo ...
- hadoop2.2原理:分析HDFS的文件读写
File Read 程序举例: public class FileRead { public static void main(Sting[] args) throws Exception { Con ...
- 深入浅出Hadoop实战开发(HDFS实战图片、MapReduce、HBase实战微博、Hive应用)
Hadoop是什么,为什么要学习Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运 ...
随机推荐
- git 学习笔记 Git实践
网上有很多教程,这里我自己做下整理,省得有时忘记,有道是好记性不如烂博客! 先大概描述下Git的各种命令: git init #初始化 git clone ...
- Java中返回值的详解
package com.company; //java中main()函数中调用其他方法的两种方式//1.实例化对象 public class returnDemo { public static vo ...
- UOJ#316. 【NOI2017】泳池
传送门 一道 \(DP\) 好题 设 \(q\) 为一个块合法的概率 套路一恰好为 \(k\) 的概率不好算,算小于等于 \(k\) 的减去小于等于 \(k-1\) 的 那么设 \(f_i\) 表示宽 ...
- bootStrap下拉菜单 点击下拉列表某个元素,列表不隐藏
html: <a class="dropdown-toggle bgImg-priceWran " id="dropdownMenu1" data-tog ...
- 关于webpack 配置文件找不到
运行命令 npm run eject 将配置文件解压出来 如果运行这个命令有错的时候,很可能与 git 有关 这时候,打开项目文件夹,显示所有隐藏的文件夹(工具),如果显示了git 的文件夹 删掉 ...
- CentOS6.5(4)----宿主机无法访问虚拟机中的web服务解决方案
宿主机无法访问虚拟机中的web服务 在Windows7宿主机中的VMware虚拟机中安装了CentOS6.5操作系统,并且基于Nginx搭建了Web服务器,网页刚刚搭建好的时候,通过宿主机的浏览器可以 ...
- 【转】怎么用PHP发送HTTP请求(POST请求、GET请求)?
file_get_contents版本: /** * 发送post请求 * @param string $url 请求地址 * @param array $post_data post键值对数据 * ...
- 【疑难杂症01】TypeError: alert is not a function
一.背景 话说今天在调试js的时候,碰到一个很奇怪的问题,现记录一下.当使用alert()函数弹出提示时,总是报错,你没看错,alert函数报错了. 二.详细说明 当时正在做一个关于告警的页面展示功能 ...
- jekyll开发静态网站
一.Ruby环境安装配置 首先下载ruby安装ruby download ,安装完ruby后,再安装rubyGems:运行gem update --system即可. 然后下载DevKit-mingw ...
- UltraISO制作U盘启动盘教程
Step 1: 首先需要安装UltraISO,完成安装后打开软碟通,文件->打开,打开我们的iso镜像 安装包可以百度搜索 Step 2:然后选择我们的U盘 Step 3:然后点击启动-> ...