_00006 Hadoop FileSystem源码浅析(如何与NameNode通信)
来源:互联网 发布:iphone6splus自带软件 编辑:程序博客网 时间:2024/05/02 00:44
个性签名:世界上最遥远的距离不是天涯,也不是海角,而是我站在妳的面前,妳却感觉不到我的存在
技术方向:Flume+Kafka+Storm+Redis/Hbase+Hadoop+Hive+Mahout+Spark ... 云计算技术
转载声明:可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明,谢谢合作!
qq交流群:214293307 (期待与你一起学习,共同进步)
# FileSystem的create方法(主要是围绕下面这张原理图说的)
public FSDataOutputStream create(Pathf)throws IOException {
return create(f,true);
}
# 进入create(f, true);
public FSDataOutputStreamcreate(Path f,boolean overwrite)
throws IOException {
return create(f, overwrite,
getConf().getInt("io.file.buffer.size", 4096),
getDefaultReplication(),
getDefaultBlockSize());
}
# 进入create(一直点下去,这里省略一些重复的步骤),会看到create是一个接口
public abstract FSDataOutputStream create(Path f,
FsPermission permission,
boolean overwrite,
int bufferSize,
short replication,
long blockSize,
Progressable progress) throws IOException;
看到这里FielSystem的create方法是一个接口,子类肯定实现了,想要知道是什么子类,可以在FileSystem执行create的那里打个断点就知道了具体子类是什么了。具体子类就是DistributedFileSystem
# 看DistributedFileSystem中的create方法
public FSDataOutputStreamcreate(Path f,FsPermission permission,
boolean overwrite,
int bufferSize,short replication,long blockSize,
Progressable progress) throws IOException {
statistics.incrementWriteOps(1);
return new FSDataOutputStream
(dfs.create(getPathName(f), permission,
overwrite, true, replication,blockSize, progress, bufferSize),
statistics);
}
dfs是org.apache.hadoop.hdfs.DFSClient这个类
# 进入new FSDataOutputStream 看看FSDataOutputStream的构造方法
在类的注释中可以看到这么一句话Utility that wraps a {@link OutputStream} in a{@link DataOutputStream},说明这个类是对OutputStream的一个封装,我们就不需再看这个类了,因为它只是对OutputStream的一个封装,只需要看OutputStream就行了,返回到上一个步骤
# 进入dfs.create方法看看
LOG.debug(src + ": masked=" + masked);
final DFSOutputStream result = newDFSOutputStream(src, masked,
overwrite, createParent,replication, blockSize, progress, buffersize,
conf.getInt("io.bytes.per.checksum", 512));
beginFileLease(src, result);
return result;
# 进入new DFSOutputStream(src, masked…
/**
* Create a new output stream tothe given DataNode.
* @see ClientProtocol#create(String,FsPermission, String, boolean, short, long)
*/
DFSOutputStream(String src,FsPermission masked, boolean overwrite,
boolean createParent,short replication,long blockSize,Progressable progress,
int buffersize,int bytesPerChecksum)throws IOException {
this(src, blockSize, progress, bytesPerChecksum,replication);
computePacketChunkSize(writePacketSize,bytesPerChecksum);
try {
// Make sure the regular create() is done through the old create().
// This is done to ensure that newer clients (post-1.0) can talk to
// older clusters (pre-1.0). Older clusters lack the new create()
// method accepting createParent as one of the arguments.
if (createParent) {
namenode.create(
src, masked, clientName, overwrite,replication, blockSize);
} else {
namenode.create(
src, masked, clientName, overwrite,false, replication,blockSize);
}
} catch(RemoteException re) {
throwre.unwrapRemoteException(AccessControlException.class,
FileAlreadyExistsException.class,
FileNotFoundException.class,
NSQuotaExceededException.class,
DSQuotaExceededException.class);
}
streamer.start();
}该类的构造方法上说/**
* Create a new output stream to the givenDataNode.
* @see ClientProtocol#create(String,FsPermission, String, boolean, short, long)
*/(创建一个指向DataNode的输出流)
这个DFSOutputStream是DFSClient.的内部类
# 进入namenode.create方法
/**
* Create a new file entry in thenamespace.
*/
public void create(String src,
FsPermissionmasked,
StringclientName,
boolean overwrite,
short replication,
long blockSize
) throws IOException;
看注释说在namespace创建一个entry(namespace就是NameNode中维护的两张核心表之一
The NameNode controls twocritical tables:
* 1) filename->blocksequence(namespace))这就是namespace
# 回到上一步,这里的namenode是什么呢?
Namenode就是 public final ClientProtocolnamenode;是一个接口,说明了DFSClient是一个分布式文件系统的客户端,也就是RPC的客户端,就是说RPC客户端含有一个RPC服务端的代理对象。这个代理对象就是ClientProtocol接口,这个ClientProtocol就是NameNode的一个接口。结论就是这里看到的namenode是ClientProtocol,实质上就是NameNode的代理对象。文件创建好了,现在来看看流…
# 点击查看streamer.start();可以看到streamer是一个线程类,streamer的是DataStreamer,现在看看DataStreamer的源码,看看它的run方法
// The DataStreamer class is responsible for sending data packets to the
// datanodes in the pipeline. It retrieves a new blockid and blocklocations
// from the namenode, and starts streaming packets to the pipeline of
// Datanodes. Every packet has a sequence number associated with
// it. When all the packets for a block are sent out and acks for each
// if them are received, the DataStreamer closes the current block.
rivate classDataStreamer extends Daemon {
从注释上可以看出D啊他Streamer类负责发送数据包给datanode,它从namenode中渠道blockid跟blocklocations。每一个packet有一个它自身的序列号,当一个block的所有包发送并被确认之后,关闭当前block,实际上就是关闭指向当前快的输出流。
问题:
1. 谁发送这些包?------DataStreamer
2. 发送给谁?-------------DataNode
3. 谁发送确认?---------- DataNode(就是发送给DataStreamer一个确认的收到数据的信息)
4. 谁接收确认?----------- DataStreamer(接收DataNode发送的确认)
也就是把数据写到DataNode节点的block文件中(linux文件系统中的)
用户上传数据的时候是不是通过NameNode来转的?(只是向namenode申请了blockid跟blocklocation) 肯定不是的,要是都通过namenode来转,而且namenode又是单点的,namenode负担就太重了。数据是直接上传到datanode的。
# 总结
FileSystem的create方法其实就是把一个数据发送到linux文件系统中,但是HDFS的API封装的非常好,对于用户来说是透明的
妳那伊抹微笑
The you smile until forever 、、、、、、、、、、、、、、、、、、、、、- _00006 Hadoop FileSystem源码浅析(如何与NameNode通信)
- Hadoop之——FileSystem与NameNode通信示意图
- _00004 Hadoop NameNode源码浅析(RPC是基础)
- hadoop FileSystem源码分析
- hadoop源码之NameNode
- Hadoop源码分析之NameNode的启动与停止
- Hadoop源码分析之NameNode的启动与停止(续)
- 3.hadoop namenode -format脚本与源码分析
- hadoop 源码中NameNode与DataNode主要的类目录
- 客户端与NameNode通信过程(源码角度分析)
- Hadoop源码分析之FileSystem
- Hadoop源码分析:FileSystem类
- 《Hadoop 2.X HDFS源码剖析》读书笔记(NameNode)
- hadoop 2.7.3 源码分析(四):namenode启动流程
- hadoop源码阅读之FileSystem简记
- Hadoop源码分析之NameNode--Format
- 图说Hadoop源码-NameNode: NetworkTopology.InnerNode
- hadoop-2.2.0 NameNode启动源码注释
- hdu4768 二分
- Eclipse启动SDK Manager报错:[SDK Manager] 'xcopy' 不是内部或外部命令,也不是可运行的程序。
- git cannot work in windows cmd shell : try git-credential-winstore
- java逻辑运算符位运算符总结
- SpringMvc系列教程
- _00006 Hadoop FileSystem源码浅析(如何与NameNode通信)
- 一个简单的考勤签到程序
- JAVA程序员成长之路的总结
- 360怎么看腾讯
- 二分图最大匹配——匈牙利算法
- ubuntu 平台下QT+OpenCV的搭建
- leetcode:4Sum
- eclipse 在 Tomcat中 热部署 工程
- 《UI设计禁忌2.0》摘记(1):UI设计的基本原则