大數據技術原理與應用——分散式文件系統HDFS

来源:https://www.cnblogs.com/baojianxin/archive/2018/07/14/9293847.html
-Advertisement-
Play Games

分散式文件系統概述 相對於傳統的本地文件系統而言,分散式文件系統(Distribute File System)是一種通過網路實現文件在多台主機上進行分散式存儲的文件系統。分散式文件系統的設計一般採用“客戶/服務機”模式,客戶端以特定的通信協議通過網路與伺服器建立連接,提出文件訪問請求,客戶端和服務 ...


分散式文件系統概述

  相對於傳統的本地文件系統而言,分散式文件系統(Distribute File System)是一種通過網路實現文件在多台主機上進行分散式存儲的文件系統。分散式文件系統的設計一般採用“客戶/服務機”模式,客戶端以特定的通信協議通過網路與伺服器建立連接,提出文件訪問請求,客戶端和伺服器可以通過設置訪問許可權來限制請求方對底層數據存儲塊的訪問。

  目前,已經得到廣泛應用的分散式文件系統主要包括GFS和HDFS等,後者是針對前者的開源實現。


電腦集群結構

  普通的文件系統只需要單個電腦節點就可以完成文件的存儲和處理,單個電腦節點由處理器、記憶體、高速緩存和本地磁碟構成。

  分散式文件系統把文件分佈存儲到多個電腦節點上,成千上萬的電腦節點構成電腦集群。與之前使用多個處理器和專用高級硬體的並行化處理裝置不同的是,目前分散式文件系統所採用的電腦集群都是由普通硬體構成的,這就大大降低了硬體上的開銷。

  集群中的電腦節點存放在機架(Rack)上,每個機架可以存放8~64個節點,同一個機架上的不同節點之間通過網路互連(常採用吉比特乙太網),多個不同機架之間採用另一級網路或交換機互連。


 分散式文件系統的結構  

  在我們熟悉的Windows、Linux等操作系統中,文件系統一般會把磁碟空間劃分為512位元組一組,稱為“磁碟塊”,它是文件系統讀寫操作的最小單位,文件系統的塊(Block)通常是磁碟塊的整數倍,即每次讀寫的數據必須是磁碟塊大小的整數倍。

  與普通文件系統類似,分散式文件系統也採用了塊的概念,文件被分成若幹個塊進行存儲,塊是數據讀寫的基本單元,只不過分散式文件系統的塊要比操作系統中的塊大很多。比如,HDFS預設的一個塊大小是64MB。與普通文件系統不同的是,在分散式文件系統中,如果一個文件小於一個數據塊的大小,它並不占用整個數據塊的存儲空間。

  分散式文件系統在物理結構上是由電腦集群中的多個節點構成的,這些節點分為兩類:一類叫“主節點”(Master Node),或者也被稱為“名稱節點”(NameNode);另一類叫“從節點”(Slave Node),或者也被稱為“數據節點”(DataNode)。名稱節點負責文件和目錄的創建、刪除和重命名等,同時管理著數據節點和文件塊之間的映射關係,因此客戶端只有訪問名稱節點才能找到請求的文件塊所在的位置,進而到相應的位置讀取所需文件塊。數據節點負責數據的存儲和讀取,在存儲時,由名稱節點分配存儲位置,然後由客戶端把數據直接寫入相應數據節點;在讀取時,客戶端從名稱節點獲得數據節點和文件塊的映射關係,然後就可以到響應位置訪問文件塊。數據節點也要根據名稱節點的命令創建、刪除數據塊和冗餘複製。

  電腦集群中的節點可能會發生故障,因此為了保證數據的完整性,分散式文件系統通常會採用多副本存儲。文件塊會被覆製為多個副本,存儲在不同的節點上,而且存儲同一文件塊的不同副本的各個節點會分佈在不同的機架上,這樣,在單個節點出現故障時,就可以快速調用副本重啟單個節點上的計算過程,而不用重啟整個計算過程,整個機架出現故障時也不會丟失所有文件塊。文件塊的大小和副本個數通常可以由用戶指定。

  分散式文件系統是針對大規模數據存儲而設計的,主要用於處理大規模文件,如TB級文件。處理過小的文件不僅無法充分發揮其優勢,而且會嚴重影響到系統的擴展和功能。


HDFS簡介 

  HDFS開源實現了GFS的基本思想。和MapReduce一起成為Hadoop的核心組成部分。HDFS支持流數據讀取和超大規模文件,並能夠運行在廉價的普通電腦組成的集群上,這主要得益於HDFS在設計之初就充分考慮了實際應用環境的特點,那就是,硬體出錯在普通伺服器集群中是一種常態,而不是異常。因此,HDFS在設計上採取了多種機制保證在硬體出錯的環境中實現數據的完整性。總體而言,HDFS要實現以下目標:

  (1)相容廉價的硬體設備

  (2)流數據讀寫

  (3)大數據集

  (4)簡單的文件模型

  (5)強大的跨平臺相容性

  HDFS特殊的設計,在實現上述優良特性的同時,也是的自身具有一些應用局限性,主要包括以下幾個方面:

  (1)不適合低延遲數據訪問

  (2)無法高效存儲大量小文件

  (3)不支持多用戶寫入及任意修改文件


 HDFS的相關概念

  塊

  在傳統的文件系統中,為了提高磁碟讀寫效率,一般以數據塊為單位,而不是以位元組為單位。比如,機械式硬碟(磁碟的一種)包含了磁頭和轉動部件,在讀取數據時有一個尋道的過程,通過轉動碟片和移動磁頭的位置,來找到數據在機械式硬碟中額存儲位置,然後才能進行讀寫。在I/O開銷中,機械式硬碟的定址時間是最耗時的部分,一旦找到第一條記錄,剩下的順序讀取效率是非常高的。因此,以塊為單位寫數據,可以把磁碟尋道時間分攤到大量數據中。

  HDFS也同樣採用了塊的概念,預設一個塊大小是64MB。在HDFS中的文件會被拆分成多個塊,每個塊作為獨立的單元進行存儲。我們所熟悉的普通文件系統的一個塊一般只有幾千位元組,可以看出,HDFS在塊的大小的設計上明顯要大於普通文件系統。HDFS這麼做的原因,是為了最小化定址開銷。HDFS定址開銷不僅包括磁碟尋道開銷,還包括數據塊的定位開銷。當客戶端需要訪問一個文件時,首先從名稱節點獲得組成這個文件的數據塊的位置列表,然後根據位置列表獲取實際存儲各個數據塊的數據節點的位置,最後數據節點根據數據塊信息在本地Linux文件系統中找到對應的文件,並把數據返回給客戶端。設計一個比較大的塊,可以把上述定址開銷分攤到較多的數據中,降低了單位定址的開銷。因此,HDFS在文件塊大小的設置上要遠遠大於普通文件系統,以期在處理大規模文件時能夠獲得更好地性能。當然,塊的大小也不宜設置過大,因為,通常MapReduce中的Map任務一次只處理一個塊中的數據,如果啟動的任務太少,就會降低作業並行處理速度。

   HDFS採用抽象的塊的概念可以帶來以下幾個明顯的好處。

  (1)支持大規模文件存儲。文件以塊為單位進行存儲,一個大規模文件可以被拆分成若幹個文件塊,不同的文件塊可以被分發到不同的節點上,因此一個文件的大小不會受到單個節點的存儲容量的限制,可以遠遠大於網路中任意節點的存儲容量。

  (2)簡化系統設計。首先,大大簡化了存儲管理,因為文件塊大小是固定的,這樣就可以很容易計算出一個節點可以存出多少文件塊;其次,方便了元數據的管理,元數據不需要和文件塊一起存儲,可以由其他系統負責管理元數據。

  (3)適合數據備份。每個文件塊都可以冗餘存儲到多個節點上,大大提高了系統的容錯性和可用性。

  名稱節點和數據節點

  在HDFS中,名稱節點(NameNode)負責管理分散式文件系統的命名空間(NameSpace),保存了兩個核心的數據結構,即FsImage和EditLog,FsImage用於維護文件系統樹以及文件樹中所有文件和文件夾的元數據,操作日誌文件EditLog中記錄了所有針對文件的創建、刪除、重命名等操作。名稱節點記錄了每個文件中各個塊所在的節點的位置信息,但是並不持久化存儲這些信息,而是在系統每次啟動時掃描所有數據節點重構得到這些信息。

  名稱節點在啟動時,會將FsImage的內容載入到記憶體當中,然後執行EditLog文件中的各項操作,使得記憶體中的元數據保持最新。這個操作完成以後,就會創建一個新的FsImage文件和一個空的EditLog文件。名稱節點啟動成功併進入正常運行狀態以後,HDFS中的更新操作都被寫到EditLog,而不是直接寫入FsImage,這是因為對於分散式文件系統而言,FsImage文件通常都很龐大,如果所有的更新操作都直接往FsImage文件中添加,那麼系統就會變得非常緩慢。相對而言,EditLog通常都要遠遠小於FsImage,更新操作寫入到EditLog是非常高效的。名稱節點在啟動的過程中處於“安全模式”,只能對外提供讀操作,無法提供寫操作。在啟動結束後,系統就會退出安全模式,進入正常運行狀態,對外提供寫操作。

  數據節點(DataNode)是分散式文件系統HDFS的工作節點,負責數據的存儲和讀取,會根據客戶端或者名稱節點的調度來進行數據的存儲和檢索,並且向名稱節點定期發送自己所存儲的塊的列表。每個數據節點中的數據會被保存在各自節點的本地Linux文件系統中。

  第二名稱節點

  在名稱節點運行期間,HDFS會不斷發生更新操作,這些更新操作都是直接被寫入到EditLog文件,因此EditLog文件也會逐漸變大。在名稱節點運行期間,不斷變大的EditLog文件通常對於系統性能不會產生顯著影響,但是當名稱節點重啟時,需要將FsImage載入到記憶體中,然後逐條執行EditLog中的記錄,使得FsImage保持最新。可想而知,如果EditLog很大,就會導致整個過程變得非常緩慢,是的名稱節點在啟動過程中長期處於“安全模式”,無法正常對外提供寫操作,影響了用戶的使用。

  為了有效解決EditLog文件逐漸變大帶來的問題,HDFS在設計中採用了第二名稱節點(SecondaryNameNode)。第二名稱節點是HDFS架構的一個重要組成部分,具有兩方面的功能:首先,可以完成EditLog與FsImage的合併操作,減小EditLog文件大小,縮短名稱節點重啟時間;其次,可以作為名稱節點的“檢查點”,保存名稱節點中的元數據信息。具體如下:

  (1)EditLog與FsImage的合併操作。每隔一段時間,第二名稱節點會和名稱節點通信,請求其停止使用EditLog文件(這裡假設這個時刻為t1),暫時將新到達的寫操作添加到一個新的文件EditLog.new中。然後,第二名稱節點把名稱節點中的FsImage文件和EditLog文件拉回本地,再載入到記憶體中;對二者執行合併操作,即在記憶體中逐條執行EditLog中的操作,使得FsImage保持最新。合併結束後,第二名稱節點會把合併後得到的最新的FsImage文件發送到名稱節點。名稱節點收到後,會用最新的FsImage文件去替換舊的FsImage文件,同時用EditLog.new去替換EditLog文件(這裡假設這個時刻為t2),從而減小了EditLog文件的大小。

  (2)作為名稱節點的“檢查點”。從上面的合併過程可以看出,第二名稱節點會定期和名稱節點通信,從名稱節點獲取FsImage文件和EditLog文件,執行合併操作得到新的FsImage文件。從這個角度來講,第二名稱節點相當於為名稱節點設置了一個“檢查點”,周期性地備份名稱節點中的元數據信息,當名稱節點發生故障時,就可以用第二名稱節點中記錄的元數據信息進行系統恢復。但是,在第二名稱節點上合併操作得到的新的FsImage文件是合併操作發生時(即t1時刻)HDFS記錄的元數據信息,並沒有包含t1時刻和t2時刻期間發生的更新操作,如果名稱節點在t1時刻和t2時刻期間發生故障,系統就會丟失部分元數據信息,在HDFS的設計中,也並不支持把系統直接切換到第二名稱節點,因此從這個角度來講,第二名稱節點只是起到了名稱節點的“檢查點”作用,並不能起到“熱備份”作用。即使有了第二名稱節點的存在,當名稱節點發生故障時,系統還是可能會丟失部分元數據信息的。


HDFS體繫結構

  HDFS採用了主從(Master/Slave)結構模型,一個HDFS集群包括一個名稱節點和若幹數據節點。名稱節點作為中心伺服器,負責管理文件系統的命名空間及客戶端對文件的訪問。集群中的數據節點一般是一個節點運行一個數據節點進程,負責處理文件系統客戶端的讀寫請求,在名稱節點的統一調度下進行數據塊的創建、刪除和複製等操作。每個數據節點的數據實際上是保存在本地Linux文件系統中的。每個數據節點會周期性地向名稱節點發送“心跳”信息,報告自己的狀態,沒有按時發送心跳信息的數據節點會被標記為“宕機”,不會再給它分配任何I/O請求。

  用戶在實際使用HDFS時,仍然可以像在普通文件系統中那樣,使用文件名去存儲和訪問文件。實際上,在系統內部,一個文件會被切分成若幹個數據塊,這些數據塊被分佈存儲到若幹個數據節點上。當客戶端需要訪問一個文件時,首先把文件名發送給名稱節點,名稱節點根據文件名找到對應的數據塊(一個文件名可能包括多個數據塊),再根據每個數據塊信息找到實際存儲各個數據塊的數據節點的位置,並把數據節點位置發送給客戶端,最後客戶端直接訪問這些數據節點獲取數據。在整個訪問過程中,名稱節點並不參與數據的傳輸。這種設計方式,使得一個文件的數據能夠在不同的數據節點上實現併發訪問,大大提高了數據訪問速度。

  HDFS採用Java語言開發,因此任何支持JVM的機器都可以部署名稱節點和數據節點。在實際部署時,通常在集群中選擇一臺性能較好地機器作為名稱節點,其他機器作為數據節點。當然,一臺機器可以運行任意多個數據節點,甚至名稱節點和數據節點也可以放在一臺機器上運行,不過,很少在正式部署中採用這種模式。HDFS集群中只有唯一一個名稱節點,該節點負責所有元數據的管理,這種設計大大簡化了分散式文件系統的結構,可以保證數據不會脫離名稱節點的控制,同時,用戶數據永遠不會經過名稱節點,這大大減輕了中心伺服器的負擔,方便了數據管理。

  HDFS命名空間管理

  HDFS的命名空間包含目錄、文件和塊。命名空間管理是指命名空間支持對HDFS中的目錄、文件和塊做類似文件系統的創建、修改、刪除等基本操作。在當前的HDFS體繫結構中,在整個HDFS集群中只有一個命名空間,並且只有唯一一個名稱節點,該節點負責對這個命名空間進行管理。

  HDFS使用的是傳統的分級文件體系,因此用戶可以像使用普通文件系統一樣,創建、刪除目錄和文件,在目錄間轉移文件、重命名文件等。但是,HDFS還沒有實現磁碟配額和文件訪問許可權等功能,也不支持文件的硬連接和軟連接(快捷方式)。

  通信協議

  HDFS是一個部署在集群上的分散式文件系統,因此很多數據需要通過網路進行傳輸。所有的HDFS通信協議都是構建在TCP/IP協議基礎上的。客戶端通過一個可配置的埠向名稱節點主動發起TCP連接,並使用客戶端協議與名稱節點進行交互。名稱節點和數據節點之間則使用數據節點協議進行交互。客戶端與數據節點的交互是通過RPC來實現的。在設計上,名稱節點不會主動發起RPC,而是響應來自客戶端和數據節點的RPC請求。

  客戶端

  客戶端是用戶操作HDFS最常用的方式,HDFS在部署時都提供了客戶端。不過需要說明的是,嚴格來說,客戶端並不算是HDFS的一部分。客戶端可以支持打開、讀取、寫入等常見的操作,並且提供了類似Shell的命令行方式來訪問HDFS中的數據。此外,HDFS也提供了JavaAPI,作為應用程式訪問文件系統的客戶端編程介面。

  HDFS體繫結構的局限性

  HDFS只設置唯一一個名稱節點,這樣做雖然大大簡化了系統設計,但也帶來了一些明顯的局限性,具體如下。

  (1)命名空間的限制。名稱節點是保存在記憶體中的,因此名稱節點能夠容納對象(文件、塊)的個數會受到記憶體空間大小的限制。

  (2)性能的瓶頸。整個分散式文件系統的吞吐量受限於單個名稱節點的吞吐量。

  (3)隔離問題。由於集群中只有一個名稱節點,只有一個命名空間,因此無法對不同的應用程式進行隔離。

  (4)集群的可用性。一旦這個唯一的名稱節點發生故障,會導致整個集群變得不可用。


 

HDFS的存儲原理

  數據的冗餘存儲

  作為一個分散式文件系統,為了保證系統的容錯性和可用性,HDFS採用了多副本方式對數據進行冗餘存儲,通常一個數據塊的多個副本會被分佈到不同的數據結點上。這種多副本的方式具有以下3個優點。

  (1)加快數據傳輸速度。當多個客戶端需要同時訪問一個文件時,可以讓各個客戶端分別從不同的數據副本中讀取數據,這就大大加快了數據傳輸速度。

  (2)容易檢查數據錯誤。HDFS的數據節點之間通過網路傳輸數據,採用多個副本可以很容易判斷數據傳輸是否出錯。

  (3)保證數據的可靠性。即使某個數據節點出現故障失效,也不會造成數據丟失。

  數據存取策略

  數據的存取策略包括數據存放、數據讀取和數據複製等方面,它在很大程度上會影響整個分散式文件系統的讀寫性能,是分散式文件系統的核心內容。

  1.數據存放

  為了提高數據的可靠性與系統的可用性,以及充分利用網路帶寬,HDFS採用了以機架(Rack)為基礎的數據存取策略。一個HDFS集群通常包含多個機架,不同機架之間的數據通信需要經過交換機或者路由器,同一個機架中不同機器之間的通信則不需要經過交換機和路由器,這意味著同一個機架中不同機器之間的通信要比不同機架之間的通信帶寬大。

  HDFS預設每個數據節點都是在不同的機架上,這種方法會存在一個缺點,那就是寫入數據的時候不能很充分利用同一機架內部機器之間的帶寬。但是,與這點缺點相比,這種方法也帶來了更多顯著的優點:首先,可以獲得很高的數據可靠性,即使一個機架發生故障,位於其他機架上的數據副本仍然是可用的;其次,在讀取數據的時候,可以在多個機架上並行讀取數據,大大提高了數據讀取速度;最後,可以更容易地實現系統內部負載均衡和錯誤處理。

  HDFS預設的冗餘因數是3,每一個文件塊都會被同時保存到3個地方,其中,有兩份副本放在同一個機架的不同機器上,第三個副本放在不同的機架上,這樣既可以保證機架發生異常時的數據恢復,也可以提高數據讀寫性能。一般而言,HDFS副本的放置策略如下:

  (1)如果是在集群內部發起寫操作請求,則把第一副本放置在發起寫操作請求的數據節點上,實現就近寫入數據。如果是來自集群外部的寫操作,則從集群內部挑選一臺磁碟不太滿、CPU不太忙的數據節點,作為第一副本的存放地。

  (2)第二副本會被放置在與第一副本不同的機架的數據節點上。

  (3)第三副本會被放置在與第一副本相同的機架的其他節點上。

  (4)如果還有更多的副本,則繼續從集群中隨機選擇數據節點進行存放。

  2.數據讀取

  HDFS提供了一個API可以確定一個數據節點所屬的機架ID,客戶端也可以調用API來獲取自己所屬的機架ID。當客戶端讀取數據時,從名稱節點獲得數據塊不同副本的存放位置列表,列表中包含了副本所在的數據節點,可以調用API來確定客戶端和這些數據節點所屬的機架ID。當發現某個數據塊副本對應的機架ID和客戶端對應的機架ID相同時,就優先選擇該副本讀取數據,如果沒有發現,就隨機選擇一個副本讀取數據。

  3.數據複製

  HDFS的數據複製採用了流水線複製的策略,大大提高了數據複製過程的效率。當客戶端要往HDFS中寫入一個文件時,這個文件會首先被寫入本地,並被切分成若幹塊,每個塊的大小是由HDFS的設定值來決定的。每個塊都向HDFS集群中的名稱節點發起寫請求,名稱節點會根據系統中各個數據節點的使用情況,選擇一個數據節點列表返回給客戶端,然後客戶端就把數據首先寫入列表中的第一個數據節點,同時把列表傳給第一個數據節點,當第一個數據節點接收到4KB數據的時候,寫入本地,並且向列表中的第二個數據節點發起連接請求,把自己已經收到的4KB數據和列表傳給第二個數據節點,當第二個數據節點接收到4KB數據的時候,寫入本地,並且向列表中的第三個數據節點發起連接請求,依次類推,列表中的多個數據節點行成一條數據複製的流水線。最後,當文件寫完的時候,數據複製也同時完成。

  數據錯誤與恢復

  HDFS具有較高的容錯性,可以相容廉價的硬體,它把硬體出錯看成一種常態,而不是異常,並設計了相應的機制檢測數據錯誤和進行自動恢復,主要包括以下3種情形。

  1.名稱節點出錯

  名稱節點保存了所有的元數據信息,其中最核心的兩大數據結構是FsImage和EditLog,如果這兩個文件發生損壞,那麼整個HDFS實例將失效。Hadoop採用兩種機制來確保名稱節點的安全:第一,把名稱節點上的元數據信息同步存儲到其他文件系統中(比如遠程掛載的網路文件系統NFS)中;第二,運行一個第二名稱節點,當名稱節點宕機以後,可以把第二名稱節點作為一種彌補措施,利用第二名稱節點中的元數據信息進行系統恢復,但是從前面對第二名稱節點的介紹中可以看出,這樣做仍然會丟失部分數據。因此,一般會把上述兩種方式結合使用,當名稱節點發生宕機時,首先到遠程掛載的網路文件系統中獲取備份的元數據信息,放到第二名稱節點上進行恢復,並把第二名稱節點作為名稱節點來使用。

  2.數據節點出錯

  每個數據節點都會定期向名稱節點發送“心跳”信息,向名稱節點報告自己的狀態。當數據節點發生故障,或者網路發生斷網時,名稱節點就無法收到來自一些數據節點的“心跳”信息,這時這些數據節點就會被標記為“宕機”,節點上面的所有數據都會被標記為“不可讀”,名稱節點不會再給它們發送任何I/O請求。這時,有可能會出現一種情形,即由於一些數據節點的不可用會導致一些數據塊的副本數量小於冗餘因數。名稱節點會定期檢查這種情況,一旦發現某個數據塊的副本數量小於冗餘因數,就會啟動數據冗餘複製,為它生成新的副本。HDFS與其他分散式文件系統的最大區別就是可以調整冗餘數據的位置。

  3.數據出錯

  網路傳輸和磁碟錯誤等因素都會造成數據錯誤。客戶端在讀取到數據後,會採用md5和sha1對數據塊進行校驗,以確定讀取到正確的數據。在文件被創建時,客戶端就會對每一個文件塊進行信息摘錄,並把這些信息寫入到同一個路徑的隱藏文件裡面。當客戶端讀取文件的時候,會先讀取該信息文件,然後利用該信息文件對每個讀取的文件塊進行校驗。如果校驗出錯,客戶端就會請求到另外一個數據節點讀取該文件塊,並且向名稱節點報告這個文件塊有錯誤,名稱節點會定期檢查並且重新複製這個塊。


 HDFS的數據讀寫過程

  在介紹HDFS的數據讀寫之前,需要簡單介紹一下相關的類。FileSystem是一個通用文件系統的抽象基類,可以被分散式文件系統繼承,所有可能使用Hadoop文件系統的代碼都要使用這個類。Hadoop為FileSystem這個抽象類提供了多種具體的實現,DistributedFileSystem就是FileSystem在HDFS文件系統中的實現。FileSystem的open()方法返回的是一個輸入流FSDataInputStream對象,在HDFS文件系統中具體的輸入流就是DFSInputStream;FileSystem中的create()方法返回的是一個輸出流FSDataOutputStream對象,在HDFS文件系統中具體的輸出流就是DFSOutputStream。

  讀數據的過程

  客戶端連續調用oepn()、read()、close()讀取數據時,HDFS內部的執行過程如下:

  (1)客戶端通過FileSystem.open()打開文件,相應地,在HDFS文件系統中DistributedFileSystem具體實現了FileSystem。因此,調用open()方法後,DistributeFileSystem會創建輸入流FSDataFileSystem,對於HDFS而言,具體的輸入流就是DFSInputStream。

  (2)在DFSInputStream的構造函數中,輸入流通過ClientProtocal.getBlockLocations()遠程調用名稱節點,獲得文件開始部分數據塊的保存位置,同時根據距離客戶端的遠近對數據節點進行排序;然後,DistributedFileSystem會利用DFSInputStream來實例化FSDataInputStream,返回給客戶端,同時返回了數據塊的數據節點地址。

  (3)獲得輸入流FSDataInputStream後,客戶端調用read()函數開始讀取數據。輸入流根據前面的排序結果,選擇距離客戶端最近的數據節點建立連接並讀取數據。

  (4)數據從該數據節點讀到客戶端;當該數據塊讀取完畢時,FSDataInputStream關閉和該數據節點的連接。

  (5)輸入流通過getBlockLocations()方法查找下一個數據塊(如果客戶端緩存中已經包含了該數據塊的位置信息,就不需要調用該方法)。

  (6)找到該數據塊的最佳數據節點,讀取數據。

  (7)當客戶端讀取完畢數據的時候,調用FSDataInputStream的close()函數,關閉輸入流。

  需要註意的是,在讀取數據的過程中,如果客戶端與數據節點通信時出現錯誤,就會嘗試連接包含此數據塊的下一個數據節點。

  寫數據的過程

  客戶端向HDFS寫數據是一個複雜的過程,這裡介紹一下在不發生異常的情況下,客戶端連續調用create()、write()、close()時,HDFS內部的執行過程。

  (1)客戶端通過FileSystem.create()創建文件,相應地,在HDFS文件系統中DistributedFileSystem具體實現了FileSystem。因此,在調用create()方法後,DistributeFileSystem會創建輸出流FSDataOutputStream,對於HDFS而言,具體的輸出流就是DFSOutputStream。

  (2)然後,DistributedFileSystem通過RPC遠程調用名稱節點,在文件系統的命名空間中創建一個新的文件。名稱節點會執行一些檢查,比如文件是否已經存在、客戶端是否有許可權創建文件等。檢查通過之後,名稱節點會構造一個新文件,並添加文件信息。遠程方法調用結束後,DistributedFileSystem會利用DFSOutputStream來實例化FSDataOutputStream,返回給客戶端,客戶端使用這個輸出流寫入數據。

  (3)獲得輸出流FSDataOutputStream以後,客戶端調用輸出流的write()方法向HDFS中對應的文件寫數據。

  (4)客戶端向輸出流FSDataOutputStream中寫入的數據會首先被分成一個個的分包,這些分包被放入DFSOutputStream對象的內部隊列。輸出流FSDataOutputStream會向名稱節點申請保存文件和副本數據塊的若幹個數據節點,這些數據節點形成一個數據流管道。隊列中的分包最後被打包成數據包,發往數據流管道中的第一個數據節點,第一個數據節點將數據包發送給第二個數據節點,第二個數據節點將數據包發送給第三個數據節點,這樣,數據包就會流經管道上的各個數據節點(流水線複製策略)。

  (5)因為各個數據節點位於不同的機器上,數據需要通過網路發送,因此,為了保證數據節點的數據都是準確的,接收到數據的數據節點要向發送者發送“確認包”。確認包沿著數據流管道逆流而上,從數據管道依次經過各個數據節點並最終發往客戶端,當客戶端收到應答時,它將對應的包從內部隊列中移除。不斷執行(3)~(5)步,直到數據全部寫完。

  (6)客戶端調用close()方法關閉數據流,此時開始,客戶端不會再向輸出流中寫入數據,所以,當DFSOutputStream對象內部隊列中的包都收到應答以後,就可以使用ClientProtocol.complete()方法通知名稱節點關閉文件,完成一次正常的寫文件過程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 命令 1.tty (查看登錄平臺數量及用戶) 2.who (查看當前平臺及用戶) -r(同3) 3.runlevel (查看當前運行級別) 4.whoami (當前登錄用戶) * 5.init3/5(切換字元/圖形界面) 0/6(關機/重啟“同16”) * 6.lsblk (查看磁碟,塊設備) 7. ...
  • MySQL基本簡單操作 學會了安裝 ,那麼就將它利用起來。(/滑稽臉) 之前想學習 (Windows下配置真麻煩),學會了 就方便了,直接使用 創建一個 服務豈不美滋滋。創建容器的步驟可以看一下 "分享04" 的 的創建過程。 首先檢查一下本地鏡像。 [root@promote ~] docker ...
  • 占座 ...
  • 轉自:http://www.maomao365.com/?p=6864 摘要: 下文講述採用sql腳本批量刪除所有存儲過程的方法,如下所示: 實驗環境:sqlserver 2008 R2 平常使用sql腳本,刪除存儲過程,我們只可以使用刪除命令一條一條的刪除存儲過程,下文介紹一種簡便方法,可以對系統 ...
  • 有三張百萬級數據表 知識點表(ex_subject_point)9,316條數據 試題表(ex_question_junior)2,159,519條數據 有45個欄位 知識點試題關係表(ex_question_r_knowledge)3,156,155條數據 測試資料庫為:mysql (5.... ...
  • 由於Oracle授權問題,Maven3不提供oracle JDBC driver 可以到maven中央倉庫去下載依賴,網址:http://repo.spring.io/plugins-release/com/oracle/ojdbc6/11.2.0.3/ 複製到本地倉庫對應目錄即可 ...
  • MySQL5.7下麵,誤操作導致的drop table db1.tb1; 的恢復方法: 0、停業務數據寫入。【iptables封禁】 1、從備份伺服器上拉取最新的一個全備文件,恢復到一個臨時的伺服器上,解壓並啟動mysqld。 2、在這台新的slave上執行如下命令: 2.1 先配置好複製關係, c ...
  • 資料庫崩潰恢復表結構的方法 如果資料庫發生崩潰,無法登陸資料庫,想要快速恢復表結構的話有一個很方便的方法。 通過mysqlfrm工具就可以快速解析.frm文件,找到create table 語句。 安裝mysqlfrm 安裝mysqlfrm的話,需要兩個安裝包。mysql-utilities和mys ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...