以前我們介紹的訪問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