如何使用Hadoop捆綁的低階工具進行資料提取?
在之前的幾個章節,我們已經掌握瞭如何將資料從其他系統匯入Hadoop。一旦企業使用Hadoop執行某些關鍵功能,無論是資料探勘還是資料聚合,下一步通常是將該資料外部化到其他系統。例如,通常依靠Hadoop對從實時系統中提取的資料執行離線聚合,然後將派生資料反饋到實時系統中。
本節將介紹一些希望從Hadoop獲取資料的常見方案,以及可幫助完成這項工作的工具。我們首先看一下現有的低階工具,其中大多數工具都內建在Hadoop中,然後繼續研究如何將資料推送到關係資料庫和HBase。
首先,我們將介紹如何使用命令列從Hadoop中複製檔案。
5.3.1 Roll your own egress
本節介紹Hadoop中用於從HDFS複製資料的一些內建機制。這些技術可以手動執行,也可以使用Azkaban,Oozie甚至cron等排程系統自動執行。
實踐:使用CLI提取檔案
想象一下,你在Hadoop中執行一些工作來聚合資料,現在想要把它拿出來,可以使用的一種方法是HDFS命令列介面(CLI),用於將目錄和檔案提取到本地檔案系統。此技術涵蓋了一些可以幫助你的基本CLI命令。
問題
希望使用shell將檔案從HDFS複製到本地檔案系統。
解決方案
HDFS CLI可用於一次性移動,或者相同的命令可以合併到指令碼中,以便更頻繁地使用移動。
討論
通過hadoop命令可以將檔案從HDFS複製到本地磁碟:
$ hadoop fs -get hdfs-file.txt local-file.txt
Hadoop put命令的行為與Linux中的Linux cp命令不同,如果目標已存在,則被覆蓋; 在Hadoop中,副本失敗並顯示錯誤:
put: `hdfs-file.txt': File exists
必須新增-f選項以強制覆蓋檔案:
$ hadoop fs -get -f hdfs-file.txt local-file.txt
與Linux cp命令相似,可以使用相同的命令複製多個檔案。在這種情況下,最後一個引數必須是HDFS檔案複製到本地檔案系統的目錄:
$ hadoop fs -get hdfs-file1.txt hdfs-file2.txt /local/dest/
通常,一個是將大量檔案從HDFS複製到本地磁碟——例如,MapReduce作業輸出目錄包含每個任務的檔案。如果使用的是可以連線的檔案格式,則可以使用-getmerge命令組合多個檔案。預設情況下,在連線期間,在每個檔案的末尾新增換行符:
$ hdfs fs -getmerge hdfs-dir/part* /local/output.txt
fs命令支援更多操作——檢視完整列表,執行命令時沒有任何選項。
使用CLI的挑戰在於它非常低階,並且無法滿足自動化需求。當然,我們可以在shell指令碼中使用CLI,但是一旦升級到更復雜的程式語言,為每個HDFS命令分配程序並不理想。在這種情況下,可能希望檢視使用REST,Java或C HDFS API。下一個技術著眼於REST API。
實踐:使用REST提取檔案
使用CLI對於快速執行命令和編寫指令碼非常方便,但是會產生為每個命令分配單獨程序的開銷,這可能是希望避免的,特別是如果在程式設計中與HDFS連線。該技術涵蓋了使用Java以外的語言處理HDFS。
問題
如何讓沒有HDFS本機介面的程式語言與HDFS進行互動。
解決方案
使用Hadoop的WebHDFS介面,該介面為HDFS操作提供全功能的REST API。
討論
在開始之前,需要在叢集上啟用WebHDFS
讓我們首先使用CLI在HDFS中建立一個檔案:
$echo "the cat sat on the mat" | hadoop fs -put - /tmp/hdfs-file.txt
從HDFS讀取檔案是指定OPEN為operation:
實踐:在防火牆下實現HDFS讀取
生產Hadoop環境通常被鎖定以保護駐留在這些叢集中的資料。部分安全過程可能包括將叢集置於防火牆之後,如果Hadoop叢集的目標位於防火牆之外,這可能會造成麻煩。該技術著眼於使用HttpFS閘道器通過埠80提供HDFS訪問,埠80通常在防火牆上開啟。
問題
希望從HDFS中提取資料,但是正處於限制訪問HDFS的防火牆下。
解決方案
使用HttpFS閘道器,這是一個獨立伺服器,可通過HTTP提供對HDFS的訪問。因為它是一個單獨的服務而且是HTTP,所以可以配置為在任何可訪問Hadoop節點的主機上執行,並且可以開啟防火牆規則以允許流量到服務。
討論
HttpFS非常有用,不僅可以使用REST來訪問HDFS,還具有完整的Hadoop檔案系統實現,這意味著可以使用CLI和本機HDFS Java客戶端與HDFS進行通訊。
一旦執行,可以發出與之前使用WebHDFS技術相同的curl命令(唯一的區別是URL主機和埠,需要指向部署HttpFS的位置)。這是關於HttpFS閘道器的好處之一—語法完全相同。
要轉儲檔案/tmp/hdfs-file.txt的內容,需要執行以下操作:
實踐:使用NFS掛載Hadoop
通常,如果Hadoop資料可以作為檔案系統的常規安裝來訪問,那麼使用Hadoop資料要容易得多。這允許使用現有指令碼,工具和程式語言,並輕鬆地與HDFS中的資料進行互動。本節介紹如何使用NFS輕鬆地從HDFS複製資料。
問題
將HDFS視為常規Linux檔案系統,並使用標準Linux工具與HDFS進行互動。
解決方案
使用Hadoop的NFS實現來訪問HDFS中的資料。
討論
前文介紹了用於NFS訪問HDFS的設定指令。設定完成後,可以執行正常的檔案系統操作,例如將檔案從HDFS複製到本地檔案系統。以下示例顯示了這一點,假設HDFS安裝在/hdfs下:
$ cp /hdfs/tmp/foo.txt ~/
實踐:使用DistCp從Hadoop中複製資料
想象一下,希望從Hadoop中移出大量資料。對於本節中的大多數技術,有一個瓶頸,因為通過單個主機彙集資料,該主機是執行該程序的主機。要儘可能優化資料移動,需要利用MapReduce並行複製資料。這是DistCp發揮作用的地方,這種技術是一種可以將資料提取到NFS掛載的方法。
問題
希望有效地從Hadoop中提取資料並並行化副本。
解決方案
使用DistCp。
討論
前文詳細介紹了DistCp,幷包含有關如何在不同Hadoop叢集之間複製資料的詳細資訊,但DistCp不能用於將資料從Hadoop複製到本地檔案系統(反之亦然),因為DistCp作為MapReduce作業執行,並且叢集將無法訪問本地檔案系統。根據具體情況,有幾種選擇:
使用HDFS File Slurper複製本地檔案。
將檔案複製到NFS,該NFS也可用於叢集中的所有DataNode。
如果使用第二個選項,則可以使用DistCp並在每個DataNode上寫入本地安裝的NFS掛載,其示例如下:
請注意,NFS系統可能無法處理大量並行讀取或寫入,因此可能希望使用少於預設值20的mapper執行此命令——以下示例使用5個mapper執行:
使用Java提取檔案
假設已經在HDFS中生成了許多Lucene索引,並且希望將它們拉出到外部主機。也許你想用Java以某種方式操作檔案,此技術顯示瞭如何使用Java HDFS API讀取HDFS中的資料。
問題
希望將HDFS中的檔案複製到本地檔案系統。
解決方案
使用Hadoop的檔案系統API從HDFS複製資料。
討論
HDFS Java API與Java的I/O模型很好地整合,這意味著可以使用常規輸入流和I/O輸出流。
首先,需要使用命令列在HDFS中建立一個檔案:
$ echo "hello world" | hadoop fs -put - hdfs-file.txt
現在使用命令列將該檔案複製到本地檔案系統:
$ hadoop fs -get hdfs-file.txt local-file.txt
讓我們來探索如何在Java中複製此副本。編寫程式碼有兩個主要部分—第一部分是獲取FileSystem的控制代碼並建立檔案,第二部分是將資料從標準輸入複製到OutputStream:
可以通過執行以下命令來檢視此程式碼在實踐中的工作原理:
到目前為止,我們已經介紹了與Hadoop捆綁在一起的低階工具,以幫助提取資料。接下來,我們將介紹從HDFS到本地檔案系統的近乎連續的資料移動方法。
原文連結:https://blog.csdn.net/D55dffdh/article/details/82423831