【原創】DataNode源碼演繹 第一回

楔子

前幾天,筆者解決DataNode節點宕機過程當中,在初期並不知道是由於Centos網卡驅動不兼容形成的系統死機。故將Nodedata源碼翻出來所有看了一遍。有些心得,略寫一二,各位看官見笑了。java

第一回 混沌未分天地亂,茫茫渺渺無人見。  

筆者以源碼跟蹤的方式闡述了DataNode運行過程,若有偏頗之處實在是由於筆者水平過低,請看官留下真知灼見,做爲往後相見約守。筆者爲了闡述清晰只截取了部分相關代碼,完整的代碼請各位參考源碼。node

main函數是一個程序的入口,也是出口,全部的一切,從這裏開始,也從這裏結束。框架

public class      DataNode 
       extends    Configured 
       implements InterDatanodeProtocol, 
                  ClientDatanodeProtocol, 
                  FSConstants, 
                  Runnable, 
                  DataNodeMXBean 
{
  public static void main(String args[]) 
 {
   secureMain(args, null);
 } 
}

在代碼中,若是調用方法的所屬類不屬於DataNode,筆者會明確的標識出來,不然調用的方法都是在類DataNode中聲明和定義的。 函數

public static void secureMain(String [] args, SecureResources resources) 
{
  DataNode datanode = createDataNode(args, null, resources);
  if (datanode != null)    
    datanode.join();       
  System.exit(0);          
}

在靜態方法secureMain中,DataNode變量對象datanode被建立。話分兩頭,咱們先看datanode.join()方法,它作的就是靜靜的等待,等待線程終止,等待一切終止。oop

void join() 
{
  dataNodeThread.join();
}

話在說回來,繼續看createDataNode方法中發生的事情。this

DataNode createDataNode(String args[],Configuration conf,...) 
{
    DataNode dn = instantiateDataNode(args, conf, resources);
    runDatanodeDaemon(dn);  
    return dn;                                          
}

createDataNode方法中會實例化一個Datanode對象出來,事實上實例化一個對象還須要不少的步驟和準備,這些事件將在instantiateDataNode()方法中演繹。spa

public static DataNode instantiateDataNode(String             args[],
                                             Configuration      conf, 
                                             SecureResources    resources) 
throws IOException 
{
    DefaultMetricsSystem.initialize("DataNode");
    return makeInstance(dataDirs, conf, resources);
}
public static DataNode makeInstance(String[]        dataDirs, 
		                   Configuration   conf, 
                                     SecureResources resources) 
 throws IOException 
 {
    UserGroupInformation.setConfiguration(conf);
    LocalFileSystem localFS        = FileSystem.getLocal(conf);
    ArrayList<File> dirs           = new ArrayList<File>();
    return new DataNode(conf, dirs, resources);
    return null;
 }


在makeInstance()函數中,真正的new( )出一個DataNode類型的對象,而且馬上開始初始化DataNode類的成員變量和調用DataNode類的構造函數。其中在DataNode中比較重要的成員變量有如下幾個:線程

public FSDatasetInterface data = null;

在datanode類中成員變量data其實是FSDataset類型,FSDataset類型用來提供數據存儲功能,FSDataset實現了FSDatasetInterface接口 , 對於Block的全部操做都要通過data成員變量管理在這個datanode上存儲的block。 code

private DataStorage storage = null;

 Datanode節點利用DataStorage類型的storage對象對本身的全部存儲路徑進行統一管理。DataStorage主要在Datanode節點啓動時扮演重要的角色。orm

public Server ipcServer;

DataNode啓動的時候,會建立一個ipcServer這個ipcServerHadoopipc框架的Server實例,主要是在DataNodeDataNode之間recover block時使用,recover block會在兩個地方發生,一個是namenode返回的recover命令 ,  一個是DFSClient寫數據時遇到DataNode錯誤時觸發。

在成員變量初始化完成以後調用DataNode的構造函數

DataNode(final Configuration conf,final  AbstractList<File> dataDirs,SecureResources resources)                                         
{
  startDataNode(conf, dataDirs,resources);                                   
}

在構造函數中,調用startDataNode方法 

void startDataNode(Configuration            conf, 
                      AbstractList<File>    dataDirs, 
                      SecureResources       resources  )                                                        

{  
  storage                = new DataStorage();                                 
  this.threadGroup       = new ThreadGrou("dataXceiverServer");              
  this.dataXceiverServer = new Daemon(threadGroup,  new DataXceiverServer(ss, conf, this));            
  this.threadGroup.setDaemon(true);
  storage.recoverTransitionRead(nsInfo, dataDirs, startOpt);                   
  this.dnRegistration.setStorageInfo(storage);                        
  this.data = new FSDataset(storage, conf);             
  this.infoServer.start(); 
  blockScanner = new DataBlockScanner(this, (FSDataset)data, conf);        
}

在startDataNode方法中還storage、data、dataXceiverServer、DataBlockScanner都有各自的任務。下次繼續說。

相關文章
相關標籤/搜索