再上一篇文章Hadoop源码分析之DistributedFileSystem中说道:DistributedFileSystem的重点在于其成员变量DFSClient dfs,它执行了文件系统的具体的操作。所以现在就来学习一个DFSClient这个类。
再来看看这个图:
DFSClient就再HDFS客户端那里,DistributedFileSystem就是通过DFSClient来与NameNode和DataNode通信,由于这三类节点可能不在一台机器上面,所以其通信方式就使用了RPC机制进行通信,在Java中RPC可以使用RMI来实现,但是Hadoop没有使用Java RMI方式,而是重新实现了一种节点间通信的方法,称为Hadoop IPC(Inter-Process Communication,进程间通信),因为Java RMI方式进行进程间通信,开销较大,而Hadoop需要精确控制进程间通信,如连接,超时,缓存等通信细节,关于Hadoop IPC在后面的分析中会学习到,现在先来看看DFSClient对象的创建。
DFSClient对象创建
再DistributedFileSystem的initialize()方法中的代码this.dfs = new DFSClient(namenode, conf, statistics);是用于初始化dfs变量,其中namenode为NameNode节点的网络地址,conf为配置信息,statistics用于统计信息的记录。DFSClient有四个构造方法,但最终都是调用的同一个构造方法(参数最多的),代码如下:
public DFSClient(Configuration conf) throws IOException {
this(NameNode.getAddress(conf), conf);
}
public DFSClient(InetSocketAddress nameNodeAddr, Configuration conf
) throws IOException {
this(nameNodeAddr, conf, null);
}
public DFSClient(InetSocketAddress nameNodeAddr, Configuration conf,
FileSystem.Statistics stats)
throws IOException {
this(nameNodeAddr, null, conf, stats);
}
/**
* Create a new DFSClient connected to the given nameNodeAddr or rpcNamenode.
* Exactly one of nameNodeAddr or rpcNamenode must be null.
*/
DFSClient(InetSocketAddress nameNodeAddr, ClientProtocol rpcNamenode,
Configuration conf, FileSystem.Statistics stats)
throws IOException {
this.conf = conf;
this.stats = stats;
//和网络相关的一些参数
/**NameNode网络地址**/
this.nnAddress = nameNodeAddr;
/**socket连接超时时间**/
this.socketTimeout = conf.getInt("dfs.socket.timeout",
HdfsConstants.READ_TIMEOUT);
this.datanodeWriteTimeout = conf.getInt("dfs.datanode.socket.write.timeout",
HdfsConstants.WRITE_TIMEOUT);
this.timeoutValue = this.socketTimeout;
this.socketFactory = NetUtils.getSocketFactory(conf, ClientProtocol.class);
// dfs.write.packet.size is an internal config variable
/**往数据节点写数据