以前我們介紹的訪問HDFS的方法都是單線程的,Hadoop中有一個工具可以讓我們並行的拷貝大量資料檔案,這個工具就是distcp。
distcp的典型應用就是在兩個HDFS叢集中拷貝檔案,如果兩個叢集使用的Hadoop版本相同,可以使用hdfs標識符:
% hadoop distcp hdfs://namenode1/foo hdfs://namenode2/bar
這條命令會把第一個叢集(namenode為命令中指定的namenode1)中的/foo目錄拷貝到第二個叢集中的/bar目錄下,於是在第二個叢集中就得到了/bar/foo這樣的目錄結構,我們也可以指定多個拷貝源,但拷貝目的地只有一個。要注意的是,指定拷貝路徑的時候要使用絕對路徑。
distcp命令是以mapreduce作業的形式實現的,只不過此作業沒有reduce任務。每一個檔案是由一個map任務來拷貝的,distcp盡量把大小之和相同的各個檔案匯入到同一個map任務中。這樣可以每個map任務拷貝的資料量大致相同。
Map任務的個數是按如下方式決定的:
1)考慮到建立每個map任務的開銷,每個map任務至少應處理256MB大小的資料(如果總輸入檔案的大小小於256MB,則把這些輸入資料全部交給一個map任務執行)。例如,一個1GB大小的輸入資料會被分配四個map任務來拷貝。
2)如果待拷貝的資料實在很大,這時候就不能只按每個map任務256MB輸入資料的標準來劃分了,因為這樣可能需要建立很多map任務。這是可以按每個datanode20個map任務來劃分,例如如果有1000GB的輸入資料和100個節點,這是就會啟動100*20=2000個map任務來拷貝資料,每個map任務拷貝512MB資料。同時我們也可通過-m選項指定要使用的map數,例如-m 1000就會只啟動1000個map任務,每個map任務拷貝1GB資料。
預設情況下,如果在拷貝的目的地同名檔案已經存在,則會預設跳過這些檔案。可以通過-overwrite選項指定覆蓋掉同名檔案,或者通過-update選項來更新同名檔案。
關於distcp的更多用法,可以不加參數運行“hadoop distcp”命令來查看其用法。
如果兩個叢集的Hadoop版本不一致就不能使用hdfs標識符來拷貝檔案了,因為兩者的RPC系統是不相容的。這是可以使用唯讀基於HTTP的HFTP檔案系統來讀取來源資料,如下所示(注意此命令是在第二個叢集上執行的,以確保rpc版本相容):
% hadoop distcp hftp://namenode1:50070/foo hdfs://namenode2/bar
注意在上述命令中需要制定namenode1的網路連接埠,它是由dfs.http.address指定的,預設為50070.
另一種可選的方法是使用webhdfs協議(替換hftp協議),這樣在拷貝的源和目的地都可以使用http而不用擔心版本不相容的問題:
% hadoop distcp webhdfs://namenode1:50070/foo webhdfs://namenode2:50070/bar
我們還可以使用HDFS HTTP代理作為拷貝的源和目的地,這樣可以設定防火牆以及進行頻寬控制。
轉載請註明出處:http://www.cnblogs.com/beanmoon/archive/2012/12/18/2823581.html