HDFS的读数据过程分析
我们继续在 FileSystem 类分析,读数据使用的是 open(…)方法,我们可以看到源码
FSDataInputStream in = fileSystem.open(new Path("/d100/f1"));
点击open
/**
* Opens an FSDataInputStream at the indicated Path.
* @param f the file to open
*/
public FSDataInputStream open(Path f) throws IOException {
return open(f, getConf().getInt("io.file.buffer.size", 4096));
}
在return open 的open按ctrl+t 选择第一个DistributedFileSystem
public FSDataInputStream open(Path f, int bufferSize) throws IOException {
statistics.incrementReadOps(1);
return new DFSClient.DFSDataInputStream(
dfs.open(getPathName(f), bufferSize, verifyChecksum, statistics));
}
返回的是 DFSClient 类中 DFSDataInputStream 类,显而易见,这是一个内部类。这个内部类的构造函数,有两个形参,第一个参数是 dfs.open(…)创建的对象。我们
看一下方法的源码,
/**
* Create an input stream that obtains a nodelist from the
* namenode, and then reads from all the right places. Creates
* inner subclass of InputStream that does the right out-of-band
* work.
*/
public DFSInputStream open(String src, int buffersize, boolean verifyChecksum,
FileSystem.Statistics stats
) throws IOException {
checkOpen();
// Get block info from namenode
return new DFSInputStream(src, buffersize, verifyChecksum);
}
返回的是一个 DFSInputStream 对象。该对象中含有 NameNode 中的数据块信息。我们看一下这个类的构造方法源码
DFSInputStream(String src, int buffersize, boolean verifyChecksum
) throws IOException {
this.verifyChecksum = verifyChecksum;
this.buffersize = buffersize;
this.src = src;
prefetchSize = conf.getLong("dfs.read.prefetch.size", prefetchSize);
openInfo();
}
openInfo()打开信息,openInfo()的源代码是获取数据块的信息的。我们查看这一行的源代码
/**
* Grab the open-file info from namenode
*/
synchronized void openInfo() throws IOException {
for (int retries = 3; retries > 0; retries--) {
if (fetchLocatedBlocks()) {
// fetch block success
return;
} else {
// Last block location unavailable. When a cluster restarts,
// DNs may not report immediately. At this time partial block
// locations will not be available with NN for getting the length.
// Lets retry a few times to get the length.
DFSClient.LOG.warn("Last block locations unavailable. "
+ "Datanodes might not have reported blocks completely."
+ " Will retry for " + retries + " times");
waitFor(4000);
}
}
throw new IOException("Could not obtain the last block locations.");
}
进去fetchLocatedBlocks()
private boolean fetchLocatedBlocks() throws IOException,
FileNotFoundException {
LocatedBlocks newInfo = callGetBlockLocations(namenode, src, 0,
prefetchSize);
if (newInfo == null) {
throw new FileNotFoundException("File does not exist: " + src);
}
if (locatedBlocks != null && !locatedBlocks.isUnderConstruction()
&& !newInfo.isUnderConstruction()) {
Iterator<LocatedBlock> oldIter = locatedBlocks.getLocatedBlocks()
.iterator();
Iterator<LocatedBlock> newIter = newInfo.getLocatedBlocks().iterator();
while (oldIter.hasNext() && newIter.hasNext()) {
if (!oldIter.next().getBlock().equals(newIter.next().getBlock())) {
throw new IOException("Blocklist for " + src + " has changed!");
}
}
}
boolean isBlkInfoUpdated = updateBlockInfo(newInfo);
this.locatedBlocks = newInfo;
this.currentNode = null;
return isBlkInfoUpdated;
}
进入:callGetBlockLocations(namenode, src, 0, prefetchSize);
static LocatedBlocks callGetBlockLocations(ClientProtocol namenode,
String src, long start, long length) throws IOException {
try {
return namenode.getBlockLocations(src, start, length);
} catch(RemoteException re) {
throw re.unwrapRemoteException(AccessControlException.class,
FileNotFoundException.class);
}
}
可以看到,获取数据块信息的方法也是通过调用 namenode 取得的。这里的 namenode 属性还是位于 DFSClient 中的。通过前面的分析,我们已经知道,在 DFSClient类中的 namenode 属性是 ClientProtocal。
可以参考上一篇文章 写数据的分析
HDFS的读数据过程分析的更多相关文章
- HDFS的写数据过程分析
HDFS的写数据过程分析 我们通过FileSystem类可以操控HDFS, 那我们就从这里开始分析写数据到HDFS的过程. 在我们向 HDFS 写文件的时候,调用的是 FileSystem.creat ...
- HDFS数据流——读数据流程
HDFS读数据流程 假设客户端请求下载文件/user/atguigu/ss.avi,HDFS读数据流程如下: 1)客户端向namenode请求下载文件,namenode通过查询元数据,找到文件所有文件 ...
- Hadoop日记Day11---主从节点接口分析
一.NameNode 的接口分析 1. NameNode本质 经过前面的学习,可以知道NameNode 本身就是一个java 进程.观察RPC.getServer()方法的第一个参数,发现是this, ...
- hadoop入门级总结一:HDFS
虽然hadoop经历了多年的发展,作为技术人员都或多或少的使用过或者了解过.这里还是做一个简单的总结,主要原因是之前主要是做hadoop的开发,对hadoop的运维知之甚少,但真正的接触到hadoop ...
- hadoop之HDFS学习笔记(一)
主要内容:hdfs的整体运行机制,DATANODE存储文件块的观察,hdfs集群的搭建与配置,hdfs命令行客户端常见命令:业务系统中日志生成机制,HDFS的java客户端api基本使用. 1.什么是 ...
- Hadoop(8)-HDFS的读写数据流程以及机架感知
1. HDFS的写数据流程 1.客户端通过fs模块向NameNode申请文件上传,NameNode检查请求是否合法,如用户权限,目标文件是否已存在,父目录是否存在等等 2.NameNode返回是否可以 ...
- HDFS HA架构以及源代码引导
HA体系架构 相关知识介绍 HDFS master/slave架构,HDFS节点分为NameNode节点和DataNode节点. NameNode存有HDFS的元数据:主要由FSImage和EditL ...
- Hadoop_08_客户端向HDFS读写(上传)数据流程
1.HDFS的工作机制: HDFS集群分为两大角色:NameNode.DataNode (Secondary Namenode) NameNode负责管理整个文件系统的元数据 DataNode 负责管 ...
- 大数据技术之Hadoop(HDFS)
第1章 HDFS概述 1.1 HDFS产出背景及定义 1.2 HDFS优缺点 1.3 HDFS组成架构 1.4 HDFS文件块大小(面试重点) 第2章 HDFS的Shell操作(开发重点) 1.基本语 ...
随机推荐
- 机器学习基石:06 Theory of Generalization
若H的断点为k,即k个数据点不能被H给shatter,那么k+1个数据点也不能被H给shatter,即k+1也是H的断点. 如果给定的样本数N是大于等于k的,易得mH(N)<2N,且随着N的增大 ...
- osx mitmproxy ssl 错误
记录一下,总是在这里折腾. cd ~ cd .mitmproxy cp mitmproxy-ca-cert.pem ~/ 然后到目录下双击mitmproxy-ca-cert.pem ,在钥匙串中的登录 ...
- 《C++ Primer》学习笔记:向vector对象添加元素蕴含的编程假定
练习<C++ Primer>中的3.14节时,当敲入: #include <iostream> #include <string> using namespace ...
- bzoj 2560: 串珠子
Description 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不 ...
- ●HDU 2871 Memory Control(Splay)
●赘述题目 四种操作: ○Reset:将整个内存序列清空. ○New a:在尽量靠左的位置新建一个长度为a的内存块,并输出改内存块起始位置.(各个内存块即使相邻也不会合并..) ○Free a:将a点 ...
- Uva 437 巴比伦塔 && UVA10003
要求底面严格小于它下方立方体的长宽,求出最高情况,一块石头可以多次使用 用结构体记录一块石头的三种放置情况,按面积排序. dp[i] = max(dp[i],dp[j] + block[i].high ...
- hdu 5391 (数论)
Zball in Tina Town Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Oth ...
- hdu5652 India and China Origins(并查集)
India and China Origins Accepts: 49 Submissions: 426 Time Limit: 2000/2000 MS (Java/Others) Memo ...
- 【NOIP2013货车运输】
描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多 ...
- splay模板(BZOJ3224)
用splay实现二叉搜索树的模板,支持插入,删除,找前缀后缀,x的排名以及第x名的数. #include <cstdio> #define l(x) t[x].s[0] #define r ...