第三章 第七節 使用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均勻分佈在叢集上。