當前位置:
首頁 > 知識 > Hadoop數據傳輸:如何將數據移入和移出Hadoop?

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

企業在項目中完全使用Hadoop之前,數據移動是必須解決的事情之一。如何將數千台主機日誌數據放入Hadoop?從關係型或者No/NewSQL系統以及Hadoop中獲取數據的最有效方法是什麼?如何將Hadoop中生成的Lucene索引輸出到伺服器?這些流程如何實現自動化?

本文是《Hadoop從入門到精通》大型專題的第5章,將完全解答上述問題,讓企業走上無憂數據移動之路。本章,我們將首先介紹如何將不同位置和不同格式的數據移動到Hadoop,之後將講解如何將數據移出Hadoop。

5.1 數據移動的關鍵要素

將大量數據移入和移出Hadoop面臨很多挑戰,包括數據一致性和資源對數據源和目標的影響。然而,在深入研究這些技術之前,我們需要討論在處理數據移動時應該注意的因素。

冪等

在編程中,一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。換句話說,冪等操作無論執行多少次都會產生相同的結果。在關係資料庫中,插入通常不是冪等的,因為多次執行不會產生相同的結果資料庫狀態。或者,更新通常是冪等的,因為它們將產生相同的最終結果。

無論何時寫入數據,都應該考慮冪等性,Hadoop中的數據入口和出口沒有很大區別。分散式日誌收集框架如何處理數據重傳?如何在多個任務並行插入資料庫的MapReduce作業中確保冪等行為?

聚合

數據聚合過程組合了多個數據元素。在數據入口的上下文中,這將大量小文件移動到HDFS。在實際操作中,我們可能會面臨NameNode內存以及MapReduce執行時間慢等問題,將文件或數據聚合在一起可以緩解此類問題,這是一個需要考慮的功能。

數據格式轉換

數據格式轉換將一種數據轉換為另一種格式的操作。通常,源數據格式不適合在MapReduce等工具中進行處理。例如,如果源數據採用多行XML或JSON格式,則可能需要考慮預處理步驟。這會將數據轉換為可以拆分的形式,例如每行一個JSON或XML元素,或者將其轉換為Avro等格式。

數據壓縮

數據壓縮不僅有助於減少靜態數據的佔用空間,而且在讀取和寫入數據時也具有I/O優勢。

可用性和可恢復性

可恢復性允許入口或出口工具在操作失敗時重試。由於任何數據源,接收器或Hadoop本身都不可能100%可用,因此在發生故障時可重試非常重要。

可靠的數據傳輸和數據驗證

在數據傳輸中,檢查正確性的方法是驗證數據在傳輸過程中是否發生損壞。當使用異構系統(如Hadoop數據入口和出口)時,數據通過不同主機,網路和協議傳輸只會增加數據傳輸過程中出現問題的可能性。檢查原始數據(如存儲設備)正確性的常用方法是循環冗餘校驗(CRC),這是HDFS內部用於維護塊級完整性的常用方法。

此外,由於生成數據的軟體存在錯誤,源數據本身可能存在問題。在入口時執行數據驗證允許進行一次性檢查,而不是在發生問題時處理數據的所有下游消費者,強迫這些消費者必須更新以處理數據中的錯誤。

資源消耗和性能

資源消耗和性能分別是系統資源利用率和系統效率的度量。入口和出口工具通常不會對系統施加大量負載(資源消耗),除非有非常可觀的數據量。對於性能,要考慮的問題包括工具是否並行執行操作,如果是,提供了什麼機制來調整並行度。如果數據源是生產資料庫並且正在使用MapReduce提取該數據,請不要使用大量並發map任務來導入數據。

監控

監控確保功能在自動化系統中按預期執行。對於數據入口和出口,監控分為兩部分:確保入口和出口中涉及的進程存活,並驗證源和目標數據是否按預期生成。監控還應包括驗證正在移動的數據量是否達到預期水平; 數據中意外的下降或高電流將提醒潛在的系統問題或軟體錯誤。

推測執行

MapReduce具有一個稱為推測(Speculative)執行的功能,可以在作業結束時為仍在執行的任務啟動備份,這有助於防止緩慢的硬體影響作業執行時間。但是,這種做法也可能有問題,如果使用map任務執行插入關係資料庫,你應該知道可以有兩個並行進程插入相同的數據。

補充:推測執行(Speculative Execution)是指在集群環境下運行MapReduce,可能是程序Bug,負載不均或者其他的一些問題,導致在一個JOB下的多個TASK速度不一致,比如有的任務已經完成,有的卻只跑了10%,根據木桶原理,這些任務將成為整個JOB的短板,如果集群啟動了推測執行,這時為了最大限度的提高短板,Hadoop會為該task啟動備份任務,讓speculative task與原始task同時處理一份數據,哪個先運行完,則將哪個結果作為最終結果,並且在運行完成後Kill掉另外一個任務。

5.2 將數據移入Hadoop

在Hadoop中處理數據的第一步是將其提供給Hadoop。有兩種主要方法可用於將數據移入Hadoop:在HDFS層(數據推送)寫入外部數據,或在MapReduce層讀取外部數據(更像是拉取)。在MapReduce中讀取數據具有以下優點:操作可以輕鬆並行並具有容錯能力。然而,並非所有數據都可以使用MapReduce訪問,例如在日誌文件下,其他系統需要依賴傳輸,包括用於最終數據hop的HDFS。

本節,我們將介紹將源數據移動到Hadoop的方法,將使用上一節中的設計注意事項作為檢查和理解不同工具的標準。

5.2.1 HDFS命令行

Hadoop捆綁了許多方法來將數據導入HDFS。本節將介紹這些內置工具如何滿足數據移動中的各種需求,可以使用的第一個也是最簡單的工具是HDFS命令行。

為作業選擇正確的數據獲取工具

本節中的低級工具適用於一次性文件移動,或者處理基於文件的舊數據源和目標。但是,以這種方式移動數據很輕易就會被Flume和Kafka(本章稍後介紹)等工具所淘汰,這些工具提供了自動數據移動管道。

註:Kafka是一個更好的平台,用於從A到B(B可以是Hadoop集群)移動數據,而不是老式的「複製文件」。使用Kafka,只需將數據泵入其中,就擁有了實時(例如通過Storm)或離線/批量作業(例如通過Camus)消費數據。這種方法將在之後的章節中介紹。

使用CLI載入文件

如果需要手動執行,那麼HDFS命令行界面(CLI)就是最合適的工具。它允許執行在常規Linux文件系統上可執行的大多數操作。本節,我們將重點介紹如何將數據從本地文件系統複製到HDFS中。

問題

使用shell將文件複製到HDFS。

解決方案

HDFS命令行界面可用於一次性移動,或者可以將其合併到腳本中以進行一系列移動。

討論

使用hadoop命令將文件從本地磁碟複製到HDFS:

$ hadoop fs -put local-file.txt hdfs-file.txt

Hadoop -put命令的行為與Linux中的Linux cp命令不同,如果目標已存在,則會被覆蓋; 在Hadoop中,副本失敗並顯示錯誤:

put: `hdfs-file.txt": File exists

必須添加-f選項以強制覆蓋文件:

$ hadoop fs -put -f local-file.txt hdfs-file.txt

與Linux cp命令非常相似,可以使用相同的命令複製多個文件。在這種情況下,最後一個參數必須是HDFS中複製本地文件的目錄:

$ hadoop fs -put local-file1.txt local-file2.txt /hdfs/dest/

可以使用Linux管道將命令輸出傳遞到HDFS文件——使用相同的-put命令並在其後添加單獨的連字元,這告訴Hadoop從標準輸入讀取:

$ echo "the cat sat on the mat" | hadoop fs -put - hdfs-file.txt

要測試文件或目錄是否存在,請使用-test命令和-e或-d選項分別測試文件或目錄是否存在。如果文件或目錄存在,則命令的代碼為0;如果不存在,則為1:

$ hadoop fs -test -e hdfs-file.txt
$ echo $?
1
$ hadoop fs -touchz hdfs-file.txt
$ hadoop fs -test -e hdfs-file.txt
$ echo $?
$ hadoop fs -test -d hdfs-file.txt
$ echo $?
1

如果只想在HDFS中「touch」文件(創建一個新的空文件),那麼touchz選項可以完成該工作:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?


Hadoop數據傳輸:如何將數據移入和移出Hadoop?

CLI專為互動式HDFS活動而設計,它也可以合併到腳本中,以用於自動執行某些任務。CLI的缺點是級別較低,並且沒有內置任何自動化機制。它需要為每個命令分配一個fork,如果在bash腳本中使用可能沒問題,但如果試圖將HDFS功能集成到Python或Java應用程序中,可能就會出現問題。在這種情況下,為每個命令啟動外部進程的開銷可能也是想要避免的。

使用REST載入文件

CLI便於快速運行命令和編寫腳本。但是,它會產生為每個命令分配一個單獨進程的開銷,這可能是想要避免的,特別是編程語言與HDFS連接時。

問題

沒有HDFS本機介面的編程語言如何與HDFS交互。

解決方案

使用Hadoop的WebHDFS介面,該介面為HDFS操作提供全功能的REST API。

討論

在開始之前,需要確保在集群上啟用WebHDFS(默認不啟動),這由dfs.webhdfs.enabled屬性控制。如果未啟用,則需要更新hdfs-site.xml並添加以下內容:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

在這種技術中,我們將介紹在不安全的Hadoop集群上運行WebHDFS.3的情況。如果正在使用安全的Hadoop集群,則不會提供user.name參數。

相反,我們將在與WebHDFS交互之前使用kinit對Kerberos進行身份驗證,然後在curl命令行中提供-negotiate -u:youruser。

警告:如果為已經關閉了安全性的集群啟用WebHDFS,則可以輕鬆地將其用作集群中任意用戶命令(只需將URL中的用戶名更改為簇)。建議僅在打開安全性的情況下運行WebHDFS。

要想在此技術中使用HTTP與NameNode進行通信,需要知道運行NameNode RPC服務的主機和埠,這是使用dfs.namenode.http-address屬性配置的。在偽分散式設置中,這很可能設置為0.0.0.0:50070。我們假設其餘技術的偽分散式——替換適當的主機和埠進行設置。

首先使用CLI在HDFS中創建文件:

$ echo "the cat sat on the mat" | hadoop fs -put - /tmp/hdfs-file.txt

使用WebHDFS獲取有關該文件的各種有趣的元數據(用戶名替換為以下URL中的aholmes):

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

命令語法由兩部分組成:一是路徑;二是正在執行的操作。但是,需要提供執行操作的用戶名,否則HDFS將假定你是一個訪問受限的匿名用戶。

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

圖5.1 解析WebHDFS URL路徑

從HDFS讀取文件只需將OPEN指定為operation:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

使用WebHDFS編寫文件分為兩步:第一步通知NameNode創建新文件的意圖,可以使用HTTP PUT命令執行此操作:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

此時,文件尚未寫入。只是讓NameNode有機會確定要寫入哪個DataNode,這是在「Location」標頭中指定的。需要獲取該URL,然後發出第二個HTTP PUT執行實際寫入:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

可以通過讀取文件來驗證寫入是否成功:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

WebHDFS支持可以使用常規命令行執行所有HDFS操作,它更有用,因為它可以訪問結構化JSON表單中的元數據,從而更容易解析數據。

值得一提的是WebHDFS提供的一些附加功能。首先,文件的第一個塊存放數據位置。NameNode將客戶端重定向到承載第一個塊的DataNode,提供強大的數據位置。對於文件中的後續塊,DataNode充當代理,並將數據流入保存塊數據的節點或從中保存數據。

WebHDFS還與Hadoop的安全身份驗證集成,這意味著可以啟用Kerberos並在HTTP請求中使用委派令牌。此外,API將保持跨Hadoop版本的兼容性,這意味著目前發布的命令將適用於未來版本的Hadoop(反之亦然)。 這是一個有用的工具,用於訪問運行不同Hadoop版本的多個集群。

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

表5.1 WebHDFS庫

當客戶端可以訪問所有NameNode和DataNode時,WebHDFS非常有用。在鎖定環境中,情況可能並非如此,可能需要查看HttpFS。

從防火牆後面訪問HDFS

生產Hadoop環境通常被鎖定以保護這些集群中的數據。部分安全程序可能包括將集群置於防火牆之後,如果嘗試從防火牆外部讀取或寫入HDFS,這將是一件麻煩事。 這種技術著眼於HttpFS網關,它可以使用HTTP(通常在防火牆上打開)提供HDFS訪問。

問題

想要寫入HDFS,但有一個防火牆限制對NameNode或DataNode的訪問。

解決方案

使用HttpFS網關,它是一個獨立的伺服器,可通過HTTP提供對HDFS的訪問。因為它是一個單獨的服務而且是HTTP,所以可以配置為在任何可以訪問Hadoop節點的主機上運行,並且可以打開防火牆規則以允許流量到服務。

討論

HttpFS非常有用,因為它不僅允許使用REST訪問HDFS,而且具有完整的Hadoop文件系統實現,這意味著可以使用CLI和本機HDFS Java客戶端與HDFS進行通信,如圖5.2所示。

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

圖5.2 HttpFS網關架構

要啟動並運行HttpFS,必須指定代理用戶。這是將運行HttpFS進程的用戶,此用戶也將在Hadoop中配置為代理用戶。假設有一個名為foxyproxy的用戶,你將其指定為代理用戶。你用以下代碼更新core-site.xml:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

基本上,這表明Hadoop應該只接受來自主機localhost的代理請求,並且foxyproxy可以冒充任何用戶(你可以通過提供以逗號分隔的組列表來鎖定可以模擬的用戶集名)。更改用戶名,主機和組值,以便它們在環境中有意義。

在對core-site.xml進行更改後,我們需要啟動HttpFS進程:

$ sbin/httpfs.sh start

現在,可以使用WebHDFS發出與之前技術中相同的curl命令。這是關於HttpFS網關的好處之一 :語法完全相同。要在根目錄上執行目錄列表,需要執行以下操作:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

此curl命令與先前技術中使用的curl命令的唯一區別是埠號。默認情況下,HttpFS在埠14000上運行,但可以通過編輯httpfs-env.sh來更改。表5.2中顯示了可以在文件中更改的一些有趣屬性。

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

表5.2 HttpFS屬性

可以在httpfs-site.xml中配置其他Kerberos以及用戶和組級別設置。

WebHDFS和HttpFS之間的差異

WebHDFS和HttpFS之間的主要區別在於客戶端對所有數據節點的可訪問性。如果客戶端可以訪問所有數據節點,那麼WebHDFS將正常工作,因為讀取和寫入文件涉及客戶端直接與數據節點通信以進行數據傳輸。另一方面,如果位於防火牆之後,客戶端可能無法訪問所有數據節點,在這種情況下,HttpFS選項最適合。使用HttpFS,伺服器將與數據節點通信,客戶端只需要與單個HttpFS伺服器通信。

如果可以,請選擇WebHDFS,因為客戶端直接與數據節點通信具有固有的優勢:這允許輕鬆擴展多個主機並發客戶端數量,而不會遇到通過HttpFS流式傳輸數據的網路瓶頸。如果客戶端本身在數據節點上運行,則更是如此,因為將通過直接從本地文件系統而不是網路流式傳輸本地託管的HDFS數據塊來使用WebHDFS的優勢。

使用NFS掛載Hadoop

通常,如果Hadoop數據可以作為文件系統的常規安裝來訪問,那麼使用Hadoop數據要容易得多。這允許使用現有腳本,工具和編程語言,並與HDFS中的數據進行交互。本節介紹如何使用NFS掛載輕鬆地將數據複製到HDFS中和從HDFS複製數據。

問題

將HDFS視為常規Linux文件系統,並使用標準Linux工具與HDFS進行交互。

解決方案

使用Hadoop的NFS實現來訪問HDFS中的數據。

討論

在Hadoop 2.1之前,NFS安裝HDFS的唯一方法是使用FUSE。由於各種性能和可靠性問題,不建議將其用於一般用途。它還引入了額外的負擔,要求在任何客戶端計算機上安裝驅動程序(換句話說,它沒有提供NFS網關)。

Hadoop中的新NFS實現解決了舊的基於FUSE系統的所有缺點。這是一個合適的NFSv3實現,允許運行一個或多個NFS網關以提高可用性和吞吐量。

要啟動並運行NFS服務,首先需要停止在主機上運行的NFS服務。在Linux系統上,可以使用以下命令實現:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?


Hadoop數據傳輸:如何將數據移入和移出Hadoop?

圖5.3 Hadoop NFS

接下來,需要啟動Hadoop NFS服務。啟動的第一個服務是portmap,它為協議及其關聯的傳輸和埠提供註冊服務。在受限的埠上運行,因此需要以root用戶身份啟動:

$ sudo hadoop-daemon.sh start portmap

接下來,你需要啟動實際的NFS服務,運行此服務的用戶一定要與運行HDFS的用戶相同,這一點非常重要:

$ hadoop-daemon.sh start nfs3

通過運行rpcinfo和showmount來驗證服務是否正在運行,應該看到類似於以下的輸出:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

現在,需要在主機目錄上安裝HDFS。以下示例選擇/hdfs作為安裝目錄。第二個mount命令驗證是否已創建安裝:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

現在,可以使用掛載的文件系統直接操作HDFS。

使用NFS網關時需要考慮以下幾點:

  • HDFS是僅附加文件系統。可以附加到文件,但不能執行隨機寫入。如果需要使用支持隨機寫入的文件系統來使用Hadoop,那麼應該看看MapR的Hadoop distribution。
  • Hadoop 2.2版不支持Hadoop安全驗證(Kerberos),並且有一個添加該支持的開放票證。
  • 在Hadoop 2.4(或3.0)之前,不支持代理用戶。這實質上意味著以前版本的Hadoop將以超級用戶身份執行所有命令,因為要求NFS網關作為與HDFS本身相同的用戶運行。

由於這些限制,建議將NFS網關保留用於實驗用途,或者用於不考慮用戶級安全性的單租戶集群。

使用DistCp在集群內和集群間複製數據

如果移入或移出Hadoop的數據量很大,通過單個主機彙集數據,一定要儘可能優化數據移動。DistCp可以在Hadoop集群之間以及進出NFS安裝的數據之間高效複製數據。

問題

在Hadoop集群之間高效複製大量數據,並且進行增量複製。

解決方案

使用DistCp,一種內置於Hadoop中的並行文件複製工具。

討論

本節,我們將首先介紹DistCp的重要配置。之後,我們將繼續查看使用DistCp的特定方案,以及配置和運行DistCp的最佳方法。

此技術涵蓋了Hadoop 2中可用的DistCp新版本,名為DistCp 2。此代碼被反向移植到Hadoop 1.2.0中,可通過使用distcp2作為命令啟用Hadoop 2來替換現有的DistCp,然後就可以正常使用distcp命令。

DistCp 2支持與DistCp的舊版本相同的命令行參數集,並帶來了許多有用的優勢:

  • 使用大量文件時減少了設置和執行時間,因為驅動程序不再需要預處理所有輸入(現在這已推遲到mapper)。
  • 具有功能齊全的Java介面,無需Java客戶端將參數序列化為字元串。
  • 原子提交允許全部複製語義。
  • 使用-update跳過目標中已存在的文件,如果文件屬性與源文件不同,將導致文件屬性發生更改。
  • 作為副本的一部分,不再跳過空目錄。

DistCp使用僅map的MapReduce作業來執行複製。以下是一個非常簡單的示例,在單個Hadoop集群中用於將源目錄,/ hello,複製到目標目錄,/world:

$ hadoop distcp /hello /world

如果/ world目錄尚不存在,則此命令將創建/ world目錄,然後將/ hello(其所有文件和目錄遞歸)的內容複製到/ world。

處理已存在的目標文件

目標中已存在的文件和目錄保持不變(即使文件不同)。

可以通過查看作業完成時轉儲到標準輸出的SKIP計數器來查看跳過的文件數:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

-update和-overwrite參數巧妙地改變了複製內容的行為。如果沒有這些選項,如果源是目錄,則在目標目錄下創建該目錄。使用-update或-overwrite參數,僅複製文件和子目錄,而不複製源目錄。通過一個例子證明這一點:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

忽略錯誤

當使用DistCp複製大量文件時,使用-i標誌執行命令以忽略錯誤是明智的。這樣,單個錯誤不會導致整個複製過程失敗,可以通過使用-update選項重新發出相同的DistCp命令來再次嘗試複製失敗文件。

動態複製策略

DistCp的默認行為是通過均勻地傳播所有文件以使所有mapper複製大致相同的位元組數來為每個mapper預分配工作。從理論上講,這聽起來像是一種公平分配工作的好方法,但實際上,諸如硬體,硬體錯誤和配置不良等因素往往導致長尾工作執行,少數落後的mapper佔用時間比其他要長。

使用DistCp 2,可以使用替代策略,其中mapper直接接收工作而不是預先分配,這被稱為動態複製策略,使用-strategy動態參數激活,添加此參數的效果是改進複製時間。

原子提交

DistCp 2的另一個有用功能是原子提交。DistCp默認將每個文件寫入臨時文件,然後移動到最終目標。這意味著無法撤消在作業中遇到錯誤之前複製的文件。

因此,原子提交允許在複製所有文件時將實際的「提交」推遲到作業結束,這樣如果遇到錯誤,你將看不到任何部分寫入,可以使用-atomic參數啟用此功能。

並行性和mapper數量

目前,DistCp最細的工作單元是文件級別。因此,無論文件多大,都只使用一個mapper來複制,提高作業的mapper數量對提高複製速度沒有任何影響。

默認情況下,DistCp使用20個mapper運行,每個mapper副本對應的文件由選擇的複製策略確定。Hadoop開發人員考慮了mapper數量的默認設置,選擇正確的值是想要使用多少網路帶寬以及希望在複製期間佔用多少任務的函數,可以通過指定-m後跟的值來更改mapper的數量。

帶寬

最後一個考慮因素是複製期間使用的網路帶寬。大型副本可能會使集群之間的網路飽和。企業中網路運營人員保持運行良好的一種方法是使用-bandwidth參數來指定每個map任務在複製期間消耗的帶寬量上限。此參數的值以兆位元組/秒(MBps)為單位。

其他

到目前為止,我們已經看到了DistCp中一些更有趣的選項。要查看完整的選項列表,可以運行distcp命令,或者查看Hadoop文檔。

將數據從NFS安裝複製到HDFS

如果要將文件放在要複製到HDFS的文件管理器或NAS上,DistCp可能非常適合。這僅在所有DataNode都安裝了數據時才有效,因為在DataNode上運行DistCp的mapper需要訪問源和目標。以下示例顯示了如何執行複製。請注意用於告訴Hadoop應該將本地文件系統用作源的文件方案:

$ hadoop distcp file://my_filer/source /dest

在同一集群中複製數據

在什麼情況下使用DistCp代替常規hadoop fs -cp命令?常規cp命令是一種複製數據的單線程方法,它逐個文件傳輸,並將數據從伺服器傳輸到客戶端並返回到伺服器。將其與DistCp進行比較,後者使用多個mapper執行複製MapReduce作業。根據經驗,在處理數十GB數據時應使用常規複製過程,並在處理數百GB或更多GB時考慮DistCp。

當同一集群既是源也是目標時,不需要特殊限定源或目標:

$ hadoop distcp /source /dest

在運行相同Hadoop版本的兩個集群之間複製

這種方法通過使用Hadoop本機文件系統讀寫來強調數據局部性,從而優化了運行相同版本Hadoop的事實。不幸的是,Hadoop RPC對客戶端和伺服器版本相同的事實很敏感,因此如果版本不同,這將不起作用。

想像一下,你有兩個HDFS設置,一個在nn1上運行,另一個在nn2上運行,兩個NameNode都在默認的RPC埠上運行。通過以下命令將文件從/source複製到集群之間的/dest目錄:

$ hadoop distcp hdfs://nn1:8020/source hdfs://nn2:8020/dest

有兩個正在運行的集群,你可能想知道應該使用哪個集群來運行DistCp。如果集群之間有防火牆,埠只能在一個方向打開,那麼必須在對另一個具有讀取或寫入許可權的集群上運行作業。

接下來讓我們看看如何在不同的Hadoop版本的集群之間運行DistCp。

在運行不同Hadoop版本的集群之間進行複製

當集群運行不同版本的Hadoop時,以前的方法將無法運行。Hadoop的RPC沒有內置的向後或向前兼容性,因此較新版本的Hadoop客戶端無法與較舊版本的Hadoop集群通信,反之亦然。

使用最新版本的Hadoop,可以選擇兩種搭配:較舊的HFTP和較新的WebHDFS。我們先來看看傳統的方法,HFTP。

HFTP是HDFS上與版本無關的介面,它使用HTTP作為傳輸機制,提供了對HDFS的只讀視圖,因此根據定義,這意味著必須始終將其用作DistCp中的源。它通過NameNode URI中的hftp方案啟用,如下所示:

$ hadoop distcp hftp://nn1:50070/source hdfs://nn2:8020/dest

查看hdfs-site.xml(如果在hdfs-site.xml中沒有看到hdfs-default.xml),找出用於HFTP的主機和埠(特別是dfs.http.port或dfs)。 namenode .http-address如果沒有設置)。 如果保護傳輸中的數據很重要,請查看使用HTTPS進行傳輸的HFTPS方案(配置或檢查dfs.hftp.https.port,如果未設置,則默認為埠的dfs.https.port)。

使用HFTP(S),必須在目標集群上運行DistCp命令,以便HDFS使用與目標相同的Hadoop客戶端版本進行寫入。但是,如果這對環境來說太受限制,而且防火牆不允許在目標上運行DistCp,該怎麼辦?這就是WebHDFS發揮作用的地方。

WebHDFS具有優於HFTP的優點,即提供讀寫介面,可以將它用於DistCp中的源或目標,如下所示:

$ hadoop distcp hdfs://nn1:50070/source webhdfs://nn2:50070/dest

WebHDFS以數據局部性的形式具有額外的好處 - 在讀取和寫入數據時使用HTTP重定向,以便使用存儲數據的實際DataNode執行讀取和寫入。強烈建議使用WebHDFS而不是HFTP來處理其寫入能力和進行性能改進。

檢查dfs.namenode.http-address的值以確定應與WebHDFS一起使用的主機和埠。

總結

DistCp是一種用於將數據移入Hadoop文件系統和在Hadoop文件系統之間移動的強大工具,諸如增量副本之類的功能使其能夠以接近連續的方式用於同步兩個系統上的目錄。它在Hadoop版本之間複製數據的能力意味著它是跨多個Hadoop集群同步數據的一種非常流行的方式。

執行DistCp

當運行DistCp命令時,建議在屏幕會話中執行或至少使用nohup將輸出重定向到本地文件。

DistCp的限制是支持多個源目錄,但只支持一個目標目錄。 這意味著無法使用單個DistCp作業在集群之間執行單向同步(除非只需要同步單個目錄)。在這種情況下,我們可以運行多個DistCp作業,或者運行單個作業並同步到臨時目錄,然後使用fs -mv跟蹤副本以將暫存文件移動到最終目標。

使用Java載入文件

假設已經在HDFS中生成了許多Lucene索引,並且希望將它們拉出到外部主機。也許,作為拉出數據的一部分,希望使用Java以某種方式操作文件。此技術顯示了如何使用Java HDFS API在HDFS中讀取和寫入數據。

問題

將寫入HDFS的內容合併到Java應用程序中。

解決方案

使用Hadoop Java API訪問HDFS中的數據。

討論

HDFS Java API與Java的I/O模型很好得集成,這意味著可以使用常規InputStream和OutputStream來進行I/O。為了執行文件系統級操作,例如創建、打開和刪除文件,Hadoop有一個名為FileSystem的抽象類,它是為可在Hadoop中使用的特定文件系統擴展和實現的。

在之前的示例中,我們看到了如何使用CLI將數據從標準輸入流式傳輸到HDFS中的文件:

$ echo "hello world" | hadoop fs -put - hdfs-file.txt

編寫執行此操作的代碼有兩個主要部分:獲取FileSystem的句柄並創建文件,然後將數據從標準輸入複製到OutputStream:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

可以通過運行以下命令來查看此代碼在實踐中的工作原理:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

關鍵是傳遞給get方法的conf對象。FileSystem類檢查fs.defaultFS屬性的值,包含一個標識應該使用的文件系統URI。默認情況下,這被配置為本地文件系統(file:///),這就是為什麼如果嘗試在沒有任何配置的情況下開箱即用Hadoop,將使用本地文件系統而不是HDFS。

在類似於偽分散式設置中,要做的第一件事就是使用HDFS文件系統配置core-site.xml:

FileSystem fs = FileSystem.get(conf);

Hadoop從URL(前面示例中的hdfs)中獲取方案,並執行查找以發現具體的文件系統。 有兩種方法可以發現文件系統:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?


  • 自動發現內置文件系統,並調用其getScheme方法以確定其方案。在HDFS示例中,實現類是org.apache.hadoop.hdfs.DistributedFileSystem,getScheme方法返回hdfs。
  • 可以通過使用fs.$ scheme.impl更新coresite .xml來識別未內置到Hadoop中的文件系統,其中$ scheme將替換為URI中標識的方案。

FileSystem類有許多操作文件系統的方法,這裡列出了一些比較常用的:

Hadoop數據傳輸:如何將數據移入和移出Hadoop?

日誌數據在所有應用程序中一直很流行,Hadoop能夠處理生產系統生成的大量日誌數據。在下一篇文章中,我們將介紹如何將日誌文件和二進位文件連續移動到HDFS之中。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT168企業級 的精彩文章:

最新!SQL Server 2019將結合Spark創建統一數據平台!
2035年的宇宙時空隧道已向你開啟

TAG:IT168企業級 |