Java API等多種接口對HDFS通路模型都集中于單線程的存取,如果要對一個檔案集進行操作,就需要編寫一個程式來執行并行操作。HDFs提供了一個非常實用的程式——distcp ,用來在Hadoop檔案系統中并行地複制大資料量檔案。distcp一般适用于在兩個HDFS叢集間傳送資料的情況。如果兩個叢集都運作在同一個Hadoop版本上,那麼可以使用HDFS模式:
hadoop distcp hdfs://NameNode1/foo hdfs://NameNode2/bar
這條指令會将第一個叢集中的/foo檔案夾以及檔案央下的檔案複制到第二個叢集中的/bar目錄下,即在第二個叢集中會以/bar/foo的目錄結構出現。如果/bar目錄不存在,則系統會建立一個。也可以指定多個資料源,并且所有的内容都會被複制到目标路徑。需要注意的是,源路徑必須是絕對路徑。即 hdfs://NameNode1/foo
預設情況下,雖然distcp會跳過在目标路徑上已經存在的檔案,但是通過-overwirte選項可以選擇對這些檔案進行覆寫重寫,也可以使用,-update選項僅對更新過的檔案進行重寫。
distcp操作有很多選項可以設定,比如忽略失敗、限制檔案或者複制的資料量等。直接輸入指令或者不附加選項則可以檢視此操作的使用說明。即distcp。具體實作時,distcp操作會被解析為一個MapReduce操作來執行,當沒有Reducer操作時,複制操作被作為Map操作并行地在叢集節點中運作。是以,每個檔案都可被當做一個Map操作來執行複制操作。而distcp會通過執行多個檔案聚集捆綁操作,盡可能地保證每個Map操作執行相同數量的資料。那麼,執行distcp時,Map操作如何确定呢?由于系統需要保證每個Map操作執行的資料量是合理的,來最大化地減少Map執行的開銷,而按規定,每個Map最少要執行256MB的資料量(除非複制的全部資料量小于256MB)。比如要複制1GB的資料,那麼系統就會配置設定4個Map任務,當資料量非常大時,就需要限制執行的Map任務數,以限制網絡帶寬和叢集的使用率。預設情況下,每個叢集的一個節點最多執行20個Map任務。比如,要複制1000GB資料到100節點的叢集中,那麼系統就會配置設定2000個Map任務(每個節點20個),也就是說,每個節點會平均複制512MB。 還可以通過調整distcp的-m參數來減少Map任務量,比如-m 1000就意味着配置設定1000個Maps,每個節點配置設定1GB資料量。
如果嘗試使用distcp進行HDFS叢集間的複制,使用HDFS模式之後,HDFS運作在不同的Hadoop版本之上,複制将會因為RPC系統的不比對而失敗。為了糾正這個錯誤,可以使用基幹HTTP的HFTP進行通路。因為任務要在目标叢集中執行,是以HDFS的RPC版本需要比對,在HFTF模式下運作的代碼如下:
hadoop distcp hftp://NameNode1:50070/foo hdfs://NameNode2/bar
需要注憊的是,要定義通路源的URI中NameNode的網絡接口,這個接口會通過dfs.http.address的屬性值設定,預設值為50070.
distcp即dist分布式,cp複制。用于在叢集内部及叢集之間複制資料。即分布式複制!!!
本文轉自 yntmdr 51CTO部落格,原文連結:http://blog.51cto.com/yntmdr/1852034,如需轉載請自行聯系原作者