Hadoop資料傳輸:如何將資料移入和移出Hadoop?

大資料頻道發表於2018-10-08

企業在專案中完全使用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選項可以完成該工作:

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叢集上執行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):

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

圖5.1 解析WebHDFS URL路徑

從HDFS讀取檔案只需將OPEN指定為operation:

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

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

可以透過讀取檔案來驗證寫入是否成功:

WebHDFS支援可以使用常規命令列執行所有HDFS操作,它更有用,因為它可以訪問結構化JSON表單中的後設資料,從而更容易解析資料。

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

WebHDFS還與Hadoop的安全身份驗證整合,這意味著可以啟用Kerberos並在HTTP請求中使用委派令牌。此外,API將保持跨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所示。

圖5.2  HttpFS閘道器架構

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

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

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

$ sbin/httpfs.sh start

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

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

表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系統上,可以使用以下命令實現:

圖5.3 Hadoop NFS

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

$ sudo hadoop-daemon.sh start portmap

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

$ hadoop-daemon.sh start nfs3

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

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

現在,可以使用掛載的檔案系統直接操作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計數器來檢視跳過的檔案數:

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

忽略錯誤

當使用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:

可以透過執行以下命令來檢視此程式碼在實踐中的工作原理:

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

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

FileSystem fs = FileSystem.get(conf);

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

  • 自動發現內建檔案系統,並呼叫其getScheme方法以確定其方案。在HDFS示例中,實現類是org.apache.hadoop.hdfs.DistributedFileSystem,getScheme方法返回hdfs。

  • 可以透過使用fs.$ scheme.impl更新coresite .xml來識別未內建到Hadoop中的檔案系統,其中$ scheme將替換為URI中標識的方案。

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

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

相關文章:

1、《第一章:Hadoop生態系統及執行MapReduce任務介紹!》連結:       http://blog.itpub.net/31077337/viewspace-2213549/

2、《學習Hadoop生態第一步:Yarn基本原理和資源排程解析!》連結:       http://blog.itpub.net/31077337/viewspace-2213602/

3、《MapReduce如何作為Yarn應用程式執行?》連結:       http://blog.itpub.net/31077337/viewspace-2213676/

4、《Hadoop生態系統各元件與Yarn的相容性如何?》連結:       http://blog.itpub.net/31077337/viewspace-2213960/

5、《MapReduce資料序列化讀寫概念淺析!》連結:      http://blog.itpub.net/31077337/viewspace-2214151/

6、《MapReuce中對大資料處理最合適的資料格式是什麼?》連結:     http://blog.itpub.net/31077337/viewspace-2214325/

7、《如何在MapReduce中使用SequenceFile資料格式?》連結:    http://blog.itpub.net/31077337/viewspace-2214505/

8、《如何在MapReduce中使用Avro資料格式?》連結:   http://blog.itpub.net/31077337/viewspace-2214709/

9、《企業自有資料格式雜亂,MapReduce如何搞定?》連結: http://blog.itpub.net/31077337/viewspace-2214826/

10、《企業使用Hadoop的重大挑戰:如何在HDFS中組織和使用資料?》連結:  http://blog.itpub.net/31545816/viewspace-2215158/

11、《如何在HDFS中進行資料壓縮以實現高效儲存?》連結: http://blog.itpub.net/31545816/viewspace-2215281/

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31545816/viewspace-2215580/,如需轉載,請註明出處,否則將追究法律責任。

相關文章