HDFS上傳與下載底層實現------>源碼分析

一 、 java實現下載回顧



二 、原理解析

1. FileSystem.get(conf)解析


FileSystem.get(conf)  //得到文件系統FileSystem的實例

------>
get(conf){
get(url,conf) //調用內部的get(url,conf)方法
}

------>
get(url,conf){
CACHE.get(url,conf) //調用內部的CACHE.get(url,conf)方法
}

------>
CACHE.get(url,conf) {
  getInternal(url,conf,key){
    fs = map.get(key)  //通過map中的key得到fs的實例,map是新建的集合,所以第一次肯定拿不到 
    fs = createFileSystem(url,conf) //於是自己創建了一個
  }
}

------>
createFileSystem(URL url,Configuration conf){
  clazz = getClazz() //拿到DistrubutedFileSystem的clazz
  Filesystem fs = (Filesystem)ReflectionUtils.newInstance(clazz,conf) //通過clazz反射得到Filesystem的實例
  fs.initialize(url,conf) //由於反射得到,所以成員變量還沒有進行初始化,所以調用initialize方法進行初始化
  return fs
}

------>
//來到了DistributeFileSystem這個類
DistributeFileSystem{
 DFSClient dfs;

 void initialize(URL url,Configuration conf){
  this.dfs = new DFSClient(url,conf,statistics)//調用initail方法進行初始化,new DFSClient,

                                                                         //將Dfsclient作爲distributFilesystem成員變量
 } 
}

------>
//來到了DFSClient這個類
DFSClient{
  ClientProtocal namenode;
  DFSClient(nameNodeuri,rocNamenode,conf,stats){
     proxyInfo = NameNodeProxies.createProxyWithLossyRetryHadler(conf,nameNodeuri,
                              ClientProtocal.class,nuResponseToDrop) //用RPC框架工具創建一個與NN通信用的客戶端代理對象

     this.namenode = proxyInfo.getProxy();  //將客戶端代理對象作爲DFSClient的成員變量
  }
}


2.DFSInuptStream fs = fs.open(new Path("/1.txt"));解析


//實際上調用DistributedFileSystem的open方法
DistributedFileSystem{
  DFSClient dfs;

  dfs.open(path){
    return new DFSInputStream(this,src,buffersize,verifyChecksum)  
  }
}

------>DFSInputStream給各種成員賦值
DFSInputStream(this,src,buffersize,verifyChecksum){
   private dfsClient = this
   private src = src
   .......
   private locateBlocks  //對locateBlocks的賦值在openInfo方法中完成
   private blockReader   //對blockReader的賦值在openInfo方法中完成
   openInfo(); //調用openInfo方法,對locatedBlocks賦值
}

------>
openInfo(){
  ......
  lastBlockBeingWrittenLength = fetchLocatedBlocksAndGetLastBlockLength();//得到塊的位置信息和最後一塊的大小,
                                                                          //並對locateBlocks進行賦值  
}

------>
fetchLocatedBlocksAndGetLastBlockLength(){
  final LocatedBlocks newInfo = dfsclient.getLocatedBlocks(src,0) //調用 getLocatedBlocks()方法,得到NN塊的信息
}
......
------>
static LocatedBlocks callGetBlockLocations(ClientProtocol namenode,String src,long start,long length){
  return namenode.getBlockLocations(src,start,length)  //得到NN塊的信息
}

3.

FileOutputStream out = new FileOutputStream("D:/hadoop_test/1"); //new FileOutputStream本地輸出流
4.
IOUtils.copyBytes(in,out,4096,true);  //進行下載操作


發佈了35 篇原創文章 · 獲贊 11 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章