Hadoop源生實用工具之distcp

雲上的聽者發表於2019-05-29

1 概覽

DistCp(Distributed Copy)是用於大規模叢集內部或者叢集之間的高效能拷貝工具。 它使用Map/Reduce實現檔案分發,錯誤處理和恢復,以及報告生成。 它把檔案和目錄的列表作為map任務的輸入,每個任務會完成源列表中部分檔案的拷貝

備註:在工作中遇到部門間資料合作,誇不同叢集版本或者同版本不同叢集的資料copy是不同的。

2 實用

總體來說分兩類:

1) 同版本叢集間資料copy ;

2) 誇叢集版本資料copy;

 同版本叢集間資料copy 

比如:拷貝A叢集(nn1的IP192.168.7.120)的A目錄到B叢集(nn2的IP192.168.8.120)的B1目錄

1 hadoop distcp  hdfs://192.168.7.120:8020/cluster/A/    hdfs://192.168.8.120:8020/cluster/B1/

小結

a) 使用hdfs協議,其中192.168.7.120是A叢集的namenode地址, 8020是A叢集的rpc埠(hdfs-site.xml中可檢視)。192.168.8.120是B叢集的namenode IP地址

b) 這條命令會將A叢集中的/A資料夾以及資料夾下的檔案複製到B叢集中的/B1目錄下,即在B叢集中會以/B1/A的目錄結構出現。如果/B1目錄不存在,則系統會新建一個。需要注意的是,源路徑必須是絕對路徑。包含前面的hdfs://ip:port

新增多個資料來源,指定多個源目錄 如:

1  hadoop distcp hdfs:
2 
3 //192.168.7.120:8020/cluster/A/a1 hdfs://192.168.7.120:8020/A/a2 hdfs://192.168.8.120:8020/cluster/B1/

或者使用-f選項,從檔案裡獲得多個源:

 hadoop distcp -f hdfs://192.168.7.120:8020/src_A_list hdfs://192.168.8.120:8020/cluster/B1/

其中src_A_list 的內容是

    hdfs://192.168.7.120:8020/cluster/A/a1

    hdfs://192.168.7.120:8020/cluster/A/a2

當從多個源拷貝時,如果兩個源衝突,distcp會停止拷貝並提示出錯資訊, 如果在目的位置發生衝突,會根據選項設定解決。 預設情況會跳過已經存在的目標檔案(c處說明;比如不用原始檔做替換操作)。每次操作結束時 都會報告跳過的檔案數目,但是如果某些拷貝操作失敗了,但在之後的嘗試成功了, 那麼報告的資訊可能不夠精確。

每個JobTracker必須都能夠與源端和目的端檔案系統進行訪問和互動。

拷貝完成後,建議生成源端和目的端檔案的列表,並交叉檢查,來確認拷貝真正成功。 因為distcp使用Map/Reduce和檔案系統API進行操作,所以這三者或它們之間有任何問題 可能影響拷貝。

值得注意的是,當另一個客戶端同時在向原始檔寫入時,拷貝很有可能會失敗。 嘗試覆蓋HDFS上正在被寫入的檔案的操作也會失敗。 如果一個原始檔在拷貝之前被移動或刪除了,拷貝失敗同時輸出異常 FileNotFoundException。

c) 預設情況下,雖然distcp會跳過在目標路徑上已經存在的檔案,但是通過-overwirte選項可以選擇對這些檔案進行覆蓋重寫,也可以使用,-update選項僅對更新過的檔案進行重寫。

實戰案例:

案例要求 從/cluster/A1/ 和 /cluster/A2/ 到 /cluster/B1的拷貝,源路徑包括:

    hdfs://192.168.7.120:8020/cluster/A1
    hdfs://192.168.7.120:8020/cluster/A1/a1
    hdfs://192.168.7.120:8020/cluster/A1/a2
    hdfs://192.168.7.120:8020/cluster/A2
    hdfs://192.168.7.120:8020/cluster/A2/a3
    hdfs://192.168.7.120:8020/cluster/A2/a1

如果沒設定-update或 -overwrite選項, 那麼兩個源都會對映到目標端的 /cluster/B1/A1A2。 如果設定了這兩個選項,每個源目錄的內容都會和目標目錄的 內容 做比較。distcp碰到這類衝突的情況會終止操作並退出。

預設情況下,/cluster/B1/A1 和 /cluster/B1/A2 目錄都會被建立,所以並不會有衝突。

現在講-update用法:
distcp -update hdfs://192.168.7.120:8020/cluster/A1 \ 
               hdfs://192.168.7.120:8020/cluster/A2 \ 
               hdfs://192.168.8.120:8020/cluster/B1

其中源路徑/大小:
    
    hdfs://192.168.7.120:8020/cluster/A1  
    hdfs://192.168.7.120:8020/cluster/A1/a1  32 
    hdfs://192.168.7.120:8020/cluster/A1/a2  64 
    hdfs://192.168.7.120:8020/cluster/A2  
    hdfs://192.168.7.120:8020/cluster/A2/a3  64 
    hdfs://192.168.7.120:8020/cluster/A2/a4  32

和目的路徑/大小:

     hdfs://192.168.8.120:8020/cluster/B1 
     hdfs://192.168.8.120:8020/cluster/B1/a1  32 
     hdfs://192.168.8.120:8020/cluster/B1/a2  32 
     hdfs://192.168.8.120:8020/cluster/B1/a3  128

會產生:

    hdfs://192.168.8.120:8020/cluster/B1 
    hdfs://192.168.8.120:8020/cluster/B1/a1  32 
    hdfs://192.168.8.120:8020/cluster/B1/a2  32 
    hdfs://192.168.8.120:8020/cluster/B1/a3  64
  hdfs://192.168.8.120:8020/cluster/A2/a4   32
   

發現部分192.168.8.120的a2檔案沒有被覆蓋(a3卻覆蓋)。如果指定了 -overwrite選項,所有檔案都會被覆蓋。

d) distcp操作有很多選項可以設定,比如忽略失敗、限制檔案或者複製的資料量等。直接輸入指令或者不附加選項則可以檢視此操作的使用說明。

附件distcp可以選配的引數:

誇叢集版本資料copy

 

hadoop distcp  hftp://192.168.7.120:50070/cluster/A/    hdfs://192.168.8.120:8020/cluster/B1

  

需要注意的是,要定義訪問源的URI中NameNode的網路介面,這個介面會通過dfs.namenode.http-address的屬性值設定,預設值為50070 ,參考hdfs-site.xml:

 

3 實戰出現的問題總結

a)ipc.StandbyException : //s.apache.org/sbnn-error

 

 

解決:

Dfs所連結的namenode的狀態不是active的 處於standby狀態不予連結,所以方法:換一個namenode, 保證新的namenode是active

 

b)   java.io.IOException:Check-sum mismatch 

分析:該問題很常見,能在網上查到,是因為不同版本hadoop 的checksum版本不同,老版本用crc32,新版本用crc32c;

解決:只要在distcp時增加兩個引數(-skipcrccheck -update),忽略crc檢查即可。注意-skipcrccheck引數要與-update同時使用才生效。

 c) java.net.UnknowHostException

 

原因分析:圖中可以看到,distcp job已經啟動了,map 0%,  但是報了UnknowHostException:pslaves55,可能的原因是在從datanode取資料時,用的是host pslave55, 而這個host是資料來源叢集特有的,目標叢集不識別,所以報UnknowHostException.

解決辦法:在目標叢集中配置hosts檔案,將資料來源叢集中所有的host和ip的對應關係追加到目標叢集中的hosts檔案中,使得目標叢集在訪問host名時(如pslave55)能成功對映到ip

4 總結

要實現跨叢集拷貝,如拷貝A叢集的資料到B叢集,需要確認以下事情:

(1)確認B叢集機器都能ping通A叢集所有ip。

(2) 用的port 響應在各自節點上放開 iptables 不要“攔住”

(3)如果部門間的埠防火牆已經開通,但還是telnet不同,請確認A叢集的iptables已經加入了B叢集ip。

(4)如果在B叢集有UnknowHostException,則需要將A叢集的host與ip對映關係追加到B叢集的hosts檔案中。

附上常用埠port 對照:

其他配置參考官方:

http://hadoop.apache.org/docs/r2.7.6/hadoop-distcp/DistCp.html

 

相關文章