1. 程式人生 > >HDFS客戶端讀操作的詳細過程

HDFS客戶端讀操作的詳細過程

在HDFS客戶端實現中,最重要也是最複雜的一部分就是檔案的讀寫操作。

開啟檔案
當客戶端讀取一個HDFS檔案時,首先會呼叫DistributedFileSystem.open()方法開啟這個檔案,open方法首先會呼叫DFSCklient.open()方法建立HDFS檔案對應的DFSInputStream輸入流物件,然後構建一個HDFSDataInputSream物件包裝DFSInputStream,最後將這個HDFSDataInputStream物件返回給客戶端程式碼。

open()操作呼叫了兩個RPC方法,分別是ClientProtocol.getBlockLocations()方法, 用於獲取檔案對應的所有資料塊的位置資訊;CientDatanodeProtocol.getReplicaVisibleLength()方法,用於獲取Datanode上儲存的某個資料塊的真實長度。

讀操作—–DFSInputStream實現
HDFS目前實現的讀操作有三個層次,分別是網路讀、短路讀以及零拷貝讀,他們的效率依次遞增。
1.網路讀:網路讀是最基本的一種HDFS讀,DFSClient和Datanode通過建立Socket連線傳輸資料。
2.短路讀:當DFSClient和儲存目標資料塊的Datanode在同一個物理節點上時,DFSClient可以直接開啟資料塊副本檔案讀取資料,而不需要Datanode程序的轉發。
3.零拷貝讀:當DFSClient和快取目標資料塊的Datanode在同一個物理節點上時,DFSClient可以通過零拷貝的方式讀取該資料塊,大大提高了效率,而且即使在讀取過程中該資料塊被Datanode從快取中移除了,該操作還可以退化為本地短路讀,非常方便。

本地短路讀取
當客戶端和Datanode在同一個機器上時,客戶端就可以繞過Datanode程序,直接從本地磁碟上讀取資料。
當客戶端向Datanode請求資料時,Datanode會開啟檔案以及該檔案的元資料檔案,將這兩個檔案的檔案描述符通過domainSocket傳給客戶端,而不是將路徑傳給客戶端。客戶端拿到檔案描述符後構造輸入流,之後通過輸入流直接讀取磁碟上的塊檔案。通過這種方式直接繞過了Datanode程序的轉發,提供了更好的讀取效能。由於檔案描述符時只讀的,所以客戶端不能修改收到的檔案,同時由於客戶端自身無法訪問塊檔案所在的目錄,所以它也就無法訪問資料目錄的其他檔案了,從而提高了讀資料的安全性。

UNIX domain Socket時一種程序間的通訊方式,它使得同一臺機器上的兩個程序能夠以Socket的方式進行通訊。他帶來的一大好處就是,兩個程序除了可以傳遞普通資料外,還可以在程序間傳遞檔案描述符。

短路讀共享記憶體
瞭解了短路讀取的概念之後,下邊看看HDFS是如何實現這種模式的。在DFSClient中,使用ShortCircuitReplica類封裝可以進行短路讀取的副本。ShortCircuitReplica物件中包含了短路讀取副本的資料塊檔案的輸入流、校驗檔案輸入流、短路讀取副本在共享記憶體的槽位以及副本引用次數等資訊。
當DFSClient和Datanode在同一臺機器上時,需要一個共享記憶體段來維護所有的短路讀取副本的狀態,共享記憶體段中會有很多個槽位,每個槽位都記錄了一個短路讀取副本的資訊,例如當前副本是否有效、錨的次數(快取中的引用計數次數)等。
共享記憶體機制是由DFSClient和Datanode對同一個檔案執行記憶體對映操作實現的。
因為MappedByteBuffer物件能讓記憶體與物理檔案的資料實時同步,所以DFSClient和Datanode程序會通過中間檔案來交換資料,中間檔案使得這兩個程序的記憶體區域得到及時的同步。