1. 程式人生 > >hadoop檔案系統架構分析

hadoop檔案系統架構分析

(軟體體系結構的大作業,閱讀分析hadoop檔案系統)

寫在前面/後面

FileSystem = abstractFileSystem -》 面向檔案系統實現者

​ FileContext -》面向應用程式編寫者

FS中具體的檔案系統作為最基層的類,用於實現對對應的檔案系統的讀取,同一繼承自FileSystem/AbstarctFileSystem,HDFS是單獨的一套系統,對等於VFS,用於操作不同的檔案系統。HDFS雖然繼承於AbstractFileSystem,主體又DFSClient類實現,(借屍還魂),只是為了做一個檔案系統的樣子,內在的實現在另外一個HDFS的資料夾裡(有單獨的DFSInputStream),獨立於fs資料夾

FileSystem的結構:

extends Config(提供訪問配置檔案的功能)

​ 檔案建立,讀取,重新命名,拷貝,刪除等操作

GlobFilter

​ description:A class that could decide if a string matches the glob or not

Cache:

​ Caching FileSystem objects,內含有hashMap

Statistics:

statisticsTable是一個IdentityHashMap

BlockLocation:

包含一個檔案塊的詳細資訊(全部副本,主機埠,網路拓撲結構,塊檔案長度,偏移,塊長度等)

java
string[] {副本主機};
string[] {副本主機埠};
string[] {主機網路中的拓撲路徑};

FileStatus:

​ extends PathFilter,用來過濾檔案,或的想要的檔案。

​ 獲取檔案狀態,path.length,isdir,block_replocation等

Trash:

垃圾桶的功能

fs有用文章:

其他類:

DFSClinet:

​ DFSClient can connect to a Hadoop FileSystem and perform basic file tasks.It uses the ClientProtocol to commuicate with a NameNode daemon,and connects directly to DataNodes to read/write block data.HDFS users should obtain an instance of DistributedFileSystem,whith uses DFSClient to handle fileSystem tasks.

要求

  1. 閱讀教師提供的前期分析報告[3],並仔細閱讀與修正。

    ​ –

  2. 下載 JDK、Apache 的構建工具 Maven[4]、Eclipse[2],構建閱讀程式碼的環 境。

    ​ –

  3. 在詳細閱讀原始碼的基礎上,理解設計思想,並給出軟體架構圖。

這裡寫圖片描述

​ FS中具體的檔案系統作為最基層的類,用於實現對對應的檔案系統的讀取,同一繼承自FileSystem/AbstarctFileSystem,HDFS是單獨的一套系統,對等於VFS,用於操作不同的檔案系統。HDFS雖然繼承於AbstractFileSystem,主體又DFSClient類實現,(借屍還魂),只是為了做一個檔案系統的樣子,內在的實現在另外一個HDFS的資料夾裡(有單獨的DFSInputStream),獨立於fs資料夾

  1. 在軟體架構圖的基礎上,給出原始碼的詳細類圖和核心過程的順序圖, 說明原始碼的設計如何與設計思想呼應。

    • FS的架構
      這裡寫圖片描述

      可以看出類圖的繼承結構,FileSystem = abstractFileSystem + FileContext ,所以繼承自abstractFileSystem 的類基本與fileSystem的類的實現方式功能一樣,所以不再重複說明。

      我們可以把FS的有關類分為2部分,一個是工具類,一個是實現類。

      • 工具類:

      • FilterFileSystem

        FilterFileSystem繼承FileSystem,聲明瞭一個FileSystem的物件,自己做一些處理,交給FS處理

      • CheckSumFileSystem

        ChecksumFileSystem類繼承FilterFileSystem類,提供校驗CRC

      • LocalFilesystem

        繼承自ChecksumFileSystem,重寫父類的檔案複製的類,新增內部物件rfs,不過沒咋用,判斷為基本同父類一樣

      • 實現類:

      • NativeS3FileSystem

        實現具體功能的檔案系統子類與其父類FileSystem的差異顯而易見,除去父類中的抽象函式如append,Create,delete,getUri,getFileStatus,getWorkingDirectory等需要根據子類的情況實現重寫的函式之外,一些函式子類利用了其系統中獨有的類或者介面進行了自己的實現。

      • FTPFileSystem

        子類FTPFileSystem與父類FileSystem的函式實現差異很大,主要原因在於FTPFileSystem引入了Client物件並利用其完成了很多與父類不同的函式實現機制

      • KosmosFileSystem

        子類KosmosFileSystem與父類FileSystem的函式實現差異較大,主要原因在於KosmosFileSystem利用了KfsImpl介面

      • S3FileSystem

        子類S3FileSystem與父類FileSystem的函式實現差異較大,子類利用INode節點的特性對函式的實現方式進行重寫

      • RawLocalFileSytem

        自己重寫filesystem的大多數方法,去操作檔案,所依賴的流都是自己過載過的內部類流

      • HDFS

        檔案系統實現主體依靠DFSClient來實現,只是為了包裝一層filesystem

    • Stream流的架構

    這裡寫圖片描述

    流的結構類似與Fs的結構,FSInputStream/FSOutputStream是每一個具體(實際)檔案系統的父類,每一個檔案系統都有對應的流作為內部流,

    然後內部流最終需要作為引數被包裝為FSDataInputStream/FSDataOutputStream在HDFS上傳遞。

    (java流的一大特色,巢狀包裝)

    比如:new FSDataInputSteam(new S3InputStream(…))

    同時,流的結構也印證了上述的架構,fs只是為HDFS做同一的檔案系統介面,消除每一個檔案系統的差異

    • 介面的繼承
      這裡寫圖片描述

      這裡值得注意的就是writealbe是序列化的介面,繼承該結構的類可以將物件轉化為流的形式。

    • 操作/異常處理/config+shell![異常錯誤]
      這裡寫圖片描述
      這裡寫圖片描述

      無可奉告!

  2. 在明確詳細設計的基礎上,以原始碼中的相關程式碼為例證明自己的判斷。

    ​ 新建檔案系統的流程 -》

    1. 得到configuration的物件,
    2. 用filesystem.get(configuration)得到對應的檔案系統
    3. 對檔案進行操作
    4. 如果對檔案的讀寫,單獨用DataInput/OutputStream操作

    檔案系統的建立流程:

Filesystem.get() 
public static FileSystem get(URI uri, Configuration conf) throws IOException {
    String scheme = uri.getScheme();
    String authority = uri.getAuthority();

    if (scheme == null) {                       // no scheme:不知道是什麼檔案系統
      return get(conf);
    }

    if (authority == null) {                       // no authority
      URI defaultUri = getDefaultUri(conf);       //如果沒有許可權,從預設配置裡獲取URI
      if (scheme.equals(defaultUri.getScheme())    // if scheme matches default
          && defaultUri.getAuthority() != null) {  // & 有解碼許可權(不爽很懂)
        return get(defaultUri, conf);              // 返回預設的引數
      }
    }

    String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
    //是否可以從cache裡獲取
    if (conf.getBoolean(disableCacheName, false)) {
      return createFileSystem(uri, conf);
    }

    return CACHE.get(uri, conf);
  }
//FileSystem.createFileSystem()
  private static FileSystem createFileSystem(URI uri, Configuration conf
      ) throws IOException {
  Class<?> clazz = conf.getClass("fs." + uri.getScheme() + ".impl", null);  //really create filesystem,獲取對應檔案系統的名稱
if (clazz == null) {
  throw new IOException("No FileSystem for scheme: " + uri.getScheme());
}
FileSystem fs = (FileSystem)ReflectionUtils.newInstance(clazz, conf);//用反射的機制去構造類,提供類的位置,找檔案找類
fs.initialize(uri, conf);
return fs;
  }
     //Cache.get()

   獲取key()-》scheme,authority,username標識

   private FileSystem getInternal(URI uri, Configuration conf, Key key) throws IOException{

    FileSystem fs;
     synchronized (this) {
       fs = map.get(key);
     }
     if (fs != null) {
       return fs;
     }

     fs = createFileSystem(uri, conf);
 //以下涉及同步問題
     synchronized (this) { // refetch the lock again
       FileSystem oldfs = map.get(key);
       if (oldfs != null) { // 一樣的系統被建立當這個fs在建立的時候,比你早一步
         fs.close(); // close the new file system
         return oldfs;  // return the old file system
       }

       // now insert the new file system into the map
       if (map.isEmpty() && !clientFinalizer.isAlive()) {
         Runtime.getRuntime().addShutdownHook(clientFinalizer);
       }
       fs.key = key;
       map.put(key, fs);   //加入map中
       if (conf.getBoolean("fs.automatic.close", true)) {
         toAutoClose.add(key);       //自動關閉的連結串列,如果需要自動關閉
       }
       return fs;
     }
   }

這裡的檔案系統只是本地的檔案系統,HDFS的專門處理分散式的檔案系統,繼承於abstractFileSystem的目的是為了介面通訊。在完整的原始碼中,有hadoop-common-project /hadoop-hdfs-project,在這個版本里hdfs放在hdfs-project裡,而不是common裡,推測老師給的版本應該是過渡版本
這裡寫圖片描述

  1. 通過閱讀原始碼,深刻體會 Hadoop 雲端計算平臺與檔案系統之間的關係, 修正提供的分析報告,給出完整的分析過程與修訂後的報告

    ​ 雲端計算的主體的儲存部分又HDFS實現,而我們研究的fs為HDFS提供一個同一的介面,用來遮蔽每一種檔案系統內部具體的特性或者細節。使得HDFS可以將他們同一視為一種檔案系統而不用在意其他細節。

    ​ 在檔案系統的提供的服務上,為了實現雲端儲存,適合分散式儲存,又有nameNode和dataNode的結構。
    這裡寫圖片描述

    • dataNode作為儲存節點,具體負責儲存檔案資料,是檔案系統的工作節點,根據需要儲存並檢索資料塊(受客戶端或namenode排程),並且定期向namenode傳送它們所儲存的塊的列表。

    • nameNode負責儲存檔案的元資料, 管理檔案系統的名稱空間,主要作用是維護著檔案系統樹及整棵樹內所有的檔案和目錄、資料節點資訊,並將名稱空間映象檔案、編輯日誌檔案永久儲存在本地磁碟。雖然都是依賴與檔案系統,但是有一個主從的邏輯關係在裡面。

    這裡寫圖片描述

    1. dataNode多備份為資料儲存可靠性提供保障。

    2. 多備份同時對系統的吞吐量有一定提升,客戶端從namenode獲取需要的BlockLocation(參見上文),然後由HDFS去尋找對應的資料主機,返回

    3. 一個HDFS 叢集可能包含上千DataNode 節點,這些DataNode 定時和 NameNode通訊,接受NameNode的指令。為了減輕NameNode的負擔,NameNode不永久儲存資料塊的位置資訊,系統啟動時通過DataNode的上報,來重建NameNode上的對映表

    4. 通過Client的檔案讀寫分析:

      這裡寫圖片描述
      這裡寫圖片描述

      HDFS資料儲存:

這裡寫圖片描述