1. 程式人生 > >第三章 第七節 使用distcp並行拷貝

第三章 第七節 使用distcp並行拷貝

        到現在為止我們看到的HDFS訪問模式都是單執行緒訪問。它可以操作一組檔案----例如定義file glob----

但是要高效並行處理這些檔案,你需要自己寫一個程式。HADOOP自帶了一個有用的程式叫distcp用來

並行拷貝檔案到/從HADOOP檔案系統。

        distcp的一個作用是有效代替hadoop fs -cp。例如,你可以拷貝一個檔案到另一檔案:

% hadoop distcp file1 file2
        你也可以拷貝一個目錄:
% hadoop distcp dir1 dir2
        如果dir2不存在,它會建立,並且把dir1下的內容拷貝進去。你可以定義多個原始檔路徑,它們都會被

拷貝到目標路徑。

        如果dir2已經存在,那麼dir1會被拷貝到它裡面,建立一個目錄結構dir2/dir1。如果這不是你想要的,你

可以提供一個-overwrite選項來保持同樣的目錄結構並強制覆蓋檔案。你也可以使用-update選項來只更新那

些改變了的檔案。這最好使用一個例子。如果我們改變dir1裡的一個檔案,我們可以通過執行如下命令來同步

改變dir2:

% hadoop distcp -update dir1 dir2
        distcp是通過MapReduce job來實現的,它的工作就是通過並行執行在叢集的map來拷貝。沒有reducer。

每一個檔案由一個單獨的map來拷貝,distcp把所有分成檔案大概相等的份來保證每一個map得到相近數量的

資料。預設只用20個map,可以通過定義-m引數來改變這個值。

        distcp最普遍的使用是在兩個HDFS叢集之間傳遞資料。例如,下面的命令會把第一個叢集下的/foo目錄

備份到第二個叢集下:

% hadoop distcp -update -delete -p hdfs://namenode1/foo hdfs://namenode2/foo

        -delete標記將導致distcp將源目錄中不存在的檔案或目錄從目標目錄中刪除,-p意味著檔案的狀態屬性如

許可權、block size及副本都將儲存。你可以無引數執行distcp來檢視詳細使用指導。

        如果這兩個叢集執行的HDFS版本不相容,你可以使用webhdfs協議來distcp他們:

% hadoop distcp webhdfs://namenode1:50070/foo webhdfs://namenode2:50070/foo

        另一個變形是使用一個HttpFs代理來作為distcp的源或目標(同樣使用webhdfs協議),它的優點是可以控制

防火牆及頻寬(見54頁“HTTP")。

保持HDFS叢集平衡

        在拷貝資料到HDFS時,考慮叢集的平衡是很重要的。HDFS在檔案block均勻分佈在叢集中時工作的最好,所以

你要確認distcp不會破壞這個。例如,如果你定義-m 1,只會有一個map來做拷貝----除了慢且沒有有效使用叢集的

資源不說----還意味著第一個副本的所有block會儲存在執行map的那個節點上(直到硬碟填滿)。第二個和第三個副本

可能儲存到整個叢集,但是這個節點將支是不平衡的。通過使用比叢集節點更多的map可以避免這個問題。基於這個

原因,最好執行distcp時使用預設的每個節點20個map。

        儘管這樣,並不總是可以避免叢集變得不平衡的。也許你想限制map的數量這樣其它的node可以用來做其它工作。

在這種情況下,你可以使用balancer工作(見329頁“Balancer“)來使block均勻分佈在叢集上。