版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/SunnyYoona/article/details/54668028
1.需求
我們項目中需要複制一個大檔案,最開始使用的是hadoop cp指令,但是随着檔案越來越大,拷貝的時間也水漲船高。下面進行hadoop cp與hadoop distcp拷貝時間上的一個對比。我們将11.9G的檔案從data_group/adv/day=20170116下所有檔案複制到tmp/data_group/adv/day=20170116/檔案下
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#11-%E6%9F%A5%E7%9C%8B%E6%96%87%E4%BB%B6%E5%A4%A7%E5%B0%8F 1.1 檢視檔案大小
hadoop fs -du -s -h data_group/adv/day=20170116
11.9 G data_group/adv/day=20170116
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#12-%E5%A4%8D%E5%88%B6 1.2 複制
hadoop distcp data_group/adv/day=20170116 \
tmp/data_group/adv/day=20170116
hadoop fs -cp data_group/adv/day=20170116 \
tmp/data_group/adv/day=2010116
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#13-%E5%AF%B9%E6%AF%94 1.3 對比
使用distcp指令 僅耗時1分鐘;而hadoop cp指令耗時14分鐘
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#2-%E6%A6%82%E8%BF%B0 2. 概述
DistCp(分布式拷貝)是用于大規模叢集内部和叢集之間拷貝的工具。 它使用Map/Reduce實作檔案分發,錯誤處理和恢複,以及報告生成。 它把檔案和目錄的清單作為map任務的輸入,每個任務會完成源清單中部分檔案的拷貝。 由于使用了Map/Reduce方法,這個工具在語義和執行上都會有特殊的地方。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#21-distcp%E5%91%BD%E4%BB%A4-%E8%BE%93%E5%87%BA 2.1 distcp指令 輸出
17/01/19 14:30:07 INFO tools.DistCp: Input Options: DistCpOptions{atomicCommit=false, syncFolder=false, deleteMissing=false, ignoreFailures=false, maxMaps=20, sslConfigurationFile='null', copyStrategy='uniformsize', sourceFileListing=null, sourcePaths=[data_group/adv/day=20170116], targetPath=tmp/data_group/adv/day=20170116}
...
17/01/19 14:30:17 INFO mapreduce.Job: map 0% reduce 0%
17/01/19 14:30:29 INFO mapreduce.Job: map 6% reduce 0%
17/01/19 14:30:34 INFO mapreduce.Job: map 41% reduce 0%
17/01/19 14:30:35 INFO mapreduce.Job: map 94% reduce 0%
17/01/19 14:30:36 INFO mapreduce.Job: map 100% reduce 0%
17/01/19 14:31:34 INFO mapreduce.Job: Job job_1472052053889_8081193 completed successfully
17/01/19 14:31:34 INFO mapreduce.Job: Counters: 30
File System Counters
FILE: Number of bytes read=0
FILE: Number of bytes written=1501420
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=12753350866
HDFS: Number of bytes written=12753339159
HDFS: Number of read operations=321
HDFS: Number of large read operations=0
HDFS: Number of write operations=69
Job Counters
Launched map tasks=17
Other local map tasks=17
Total time spent by all maps in occupied slots (ms)=485825
Total time spent by all reduces in occupied slots (ms)=0
Map-Reduce Framework
Map input records=17
Map output records=0
Input split bytes=2414
Spilled Records=0
Failed Shuffles=0
Merged Map outputs=0
GC time elapsed (ms)=1634
CPU time spent (ms)=156620
Physical memory (bytes) snapshot=5716221952
Virtual memory (bytes) snapshot=32341671936
Total committed heap usage (bytes)=12159811584
File Input Format Counters
Bytes Read=9293
File Output Format Counters
Bytes Written=0
org.apache.hadoop.tools.mapred.CopyMapper$Counter
BYTESCOPIED=12753339159
BYTESEXPECTED=12753339159
COPY=17
是不是很熟悉,這就是我們經常看見到的MapReduce任務的輸出資訊,這從側面說明了Distcp使用Map/Reduce實作。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#3-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95 3. 使用方法
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#31-%E9%9B%86%E7%BE%A4%E9%97%B4%E6%8B%B7%E8%B4%9D 3.1 叢集間拷貝
DistCp最常用在叢集之間的拷貝:
hadoop distcp hdfs://nn1:8020/foo/bar \
hdfs://nn2:8020/bar/foo
這條指令會把nn1叢集的/foo/bar目錄下的所有檔案以及bar本身目錄(預設情況下)存儲到一個臨時檔案中,這些檔案内容的拷貝工作被配置設定給多個map任務, 然後每個TaskTracker分别執行從nn1到nn2的拷貝操作。注意DistCp使用絕對路徑進行操作。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#32-%E9%9B%86%E7%BE%A4%E5%86%85%E9%83%A8%E6%8B%B7%E8%B4%9D 3.2 叢集内部拷貝
DistCp也可以叢集内部之間的拷貝:
hadoop distcp tmp/data_group/test/a
tmp/data_group/test/target
這條指令會把本叢集tmp/data_group/test/a目錄本身以及a目錄下的所有檔案拷貝到target目錄下,原理同叢集之間的拷貝一樣。
備注
hadoop distcp tmp/data_group/test/a
tmp/data_group/test/target
上述指令預設情況下是複制a目錄以及a目錄下所有檔案到target目錄下:
hadoop fs -ls -R tmp/data_group/test/target/
tmp/data_group/test/target/aa
tmp/data_group/test/target/aa/aa.txt
tmp/data_group/test/target/aa/ab.txt
而有時我們的需求是複制a目錄下的所有檔案而不包含a目錄,這時可以後面介紹的-update參數:
hadoop distcp -update tmp/data_group/test/aa tmp/data_group/test/target
...
hadoop fs -ls -R tmp/data_group/test/target/
tmp/data_group/test/target/aa/aa.txt
tmp/data_group/test/target/aa/ab.txt
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#33-%E5%A4%9A%E6%BA%90%E7%9B%AE%E5%BD%95 3.3 多源目錄
指令行中可以指定多個源目錄:
hadoop distcp hdfs://nn1:8020/foo/a
hdfs://nn1:8020/foo/b
hdfs://nn2:8020/bar/foo
或者使用-f選項,從檔案裡獲得多個源:
hadoop distcp -f hdfs://nn1:8020/srclist \
hdfs://nn2:8020/bar/foo
其中srclist 的内容是
hdfs://nn1:8020/foo/a
hdfs://nn1:8020/foo/b
當從多個源拷貝時,如果兩個源沖突,DistCp會停止拷貝并提示出錯資訊
Example:
hadoop distcp tmp/data_group/tes
t/source_new/aa.txt tmp/data_group/test/source_old/aa.txt tmp/data_group/test/target
我們分别複制source_new和source_old目錄下的aa.txt檔案到target檔案夾下,報錯如下:
17/01/21 15:15:05 ERROR tools.DistCp: Duplicate files in input path:
org.apache.hadoop.tools.CopyListing$DuplicateFileException: File hdfs://XXX/user/XXX/tmp/data_group/test/source_new/aa.txt and \
hdfs://XXX/user/XXX/tmp/data_group/test/source_old/aa.txt would cause duplicates. Aborting
at org.apache.hadoop.tools.CopyListing.checkForDuplicates(CopyListing.java:151)
at org.apache.hadoop.tools.CopyListing.buildListing(CopyListing.java:87)
at org.apache.hadoop.tools.GlobbedCopyListing.doBuildListing(GlobbedCopyListing.java:90)
at org.apache.hadoop.tools.CopyListing.buildListing(CopyListing.java:80)
at org.apache.hadoop.tools.DistCp.createInputFileListing(DistCp.java:327)
at org.apache.hadoop.tools.DistCp.execute(DistCp.java:151)
如果在目的位置發生沖突,會根據選項設定解決。 預設情況會跳過已經存在的目标檔案(比如不用源檔案做替換操作)。每次操作結束時 都會報告跳過的檔案數目,但是如果某些拷貝操作失敗了,但在之後的嘗試成功了, 那麼報告的資訊可能不夠精确(請參考附錄)。
每個TaskTracker必須都能夠與源端和目的端檔案系統進行通路和互動。 對于HDFS來說,源和目的端要運作相同版本的協定或者使用向下相容的協定。 (請參考不同版本間的拷貝 )。
拷貝完成後,建議生成源端和目的端檔案的清單,并交叉檢查,來确認拷貝真正成功。 因為DistCp使用Map/Reduce和檔案系統API進行操作,是以這三者或它們之間有任何問題 都會影響拷貝操作。一些Distcp指令的成功執行可以通過再次執行帶-update參數的該指令來完成, 但使用者在如此操作之前應該對該指令的文法很熟悉。
值得注意的是,當另一個用戶端同時在向源檔案寫入時,拷貝很有可能會失敗。 嘗試覆寫HDFS上正在被寫入的檔案的操作也會失敗。 如果一個源檔案在拷貝之前被移動或删除了,拷貝失敗同時輸出異常 FileNotFoundException。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#4-%E9%80%89%E9%A1%B9 4. 選項
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#41-i-%E5%BF%BD%E7%95%A5%E5%A4%B1%E8%B4%A5 4.1 -i 忽略失敗
這個選項會比預設情況提供關于拷貝的更精确的統計, 同時它還将保留失敗拷貝操作的日志,這些日志資訊可以用于調試。最後,如果一個map失敗了,但并沒完成所有分塊任務的嘗試,這不會導緻整個作業的失敗。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#42-log-logdir-%E8%AE%B0%E5%BD%95%E6%97%A5%E5%BF%97 4.2 -log <logdir> 記錄日志
DistCp為每個檔案的每次嘗試拷貝操作都記錄日志,并把日志作為map的輸出。 如果一個map失敗了,當重新執行時這個日志不會被保留。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#43-overwrite-%E8%A6%86%E7%9B%96%E7%9B%AE%E6%A0%87 4.3 -overwrite 覆寫目标
如果一個map失敗并且沒有使用-i選項,不僅僅那些拷貝失敗的檔案,這個分塊任務中的所有檔案都會被重新拷貝。 就像下面提到的,它會改變生成目标路徑的語義,是以 使用者要小心使用這個選項。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#44-update-%E6%BA%90%E5%92%8C%E7%9B%AE%E6%A0%87%E7%9A%84%E5%A4%A7%E5%B0%8F%E4%B8%8D%E4%B8%80%E6%A0%B7%E5%88%99%E8%BF%9B%E8%A1%8C%E8%A6%86%E7%9B%96 4.4 -update 源和目标的大小不一樣則進行覆寫
這不是"同步"操作。 執行覆寫的唯一标準是源檔案和目标檔案大小是否相同;如果不同,則源檔案替換目标檔案。 像 下面提到的,它也改變生成目标路徑的語義, 使用者使用要小心。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#5-%E6%9B%B4%E6%96%B0%E4%B8%8E%E8%A6%86%E7%9B%96 5. 更新與覆寫
這裡給出一些 -update和 -overwrite的例子。 考慮一個從/foo/a 和 /foo/b 到 /bar/foo的拷貝,源路徑包括:
hdfs://nn1:8020/foo/a
hdfs://nn1:8020/foo/a/aa
hdfs://nn1:8020/foo/a/ab
hdfs://nn1:8020/foo/b
hdfs://nn1:8020/foo/b/ba
hdfs://nn1:8020/foo/b/ab
如果沒設定-update或 -overwrite選項, 那麼兩個源都會映射到目标端的 /bar/foo/ab。 如果設定了這兩個選項,每個源目錄的内容都會和目标目錄的 内容 做比較。DistCp碰到這類沖突的情況會終止操作并退出。
預設情況下,/bar/foo/a 和 /bar/foo/b 目錄都會被建立,是以并不會有沖突。
現在考慮一個使用-update合法的操作:
hadoop distcp -update tmp/data_group/test/source/ \
tmp/data_group/test/target/
其中源路徑/大小:
11 tmp/data_group/test/source/aa.txt
23 tmp/data_group/test/source/ab.txt
34 tmp/data_group/test/source/ba.txt
和目的路徑/大小:
11 tmp/data_group/test/target/aa.txt
9 tmp/data_group/test/target/ba.txt
會産生:
11 tmp/data_group/test/target/aa.txt
23 tmp/data_group/test/target/ab.txt
34 tmp/data_group/test/target/ba.txt
隻有target目錄的aa.txt檔案沒有被覆寫。上面以及提到過,update不是"同步"操作。執行覆寫的唯一标準是源檔案和目标檔案大小是否相同;如果不同,則源檔案替換目标檔案。source中的aa.txt大小與target中的aa.txt大小一樣,是以不會覆寫。
實際測試的過程中,target目錄下的aa.txt也會被覆寫,不得其解。求解......
如果指定了 -overwrite選項,所有檔案都會被覆寫。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#6-map%E6%95%B0%E7%9B%AE 6. Map數目
DistCp會嘗試着均分需要拷貝的内容,這樣每個map拷貝差不多相等大小的内容。 但因為檔案是最小的拷貝粒度,是以配置增加同時拷貝(如map)的數目不一定會增加實際同時拷貝的數目以及總吞吐量。
如果沒使用-m選項,DistCp會嘗試在排程工作時指定map的數目 為 min (total_bytes / bytes.per.map, 20 * num_task_trackers), 其中bytes.per.map預設是256MB。
建議對于長時間運作或定期運作的作業,根據源和目标叢集大小、拷貝數量大小以及帶寬調整map的數目。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#7%E4%B8%8D%E5%90%8Chdfs%E7%89%88%E6%9C%AC%E9%97%B4%E7%9A%84%E6%8B%B7%E8%B4%9D 7.不同HDFS版本間的拷貝
對于不同Hadoop版本間的拷貝,使用者應該使用HftpFileSystem。 這是一個隻讀檔案系統,是以DistCp必須運作在目标端叢集上(更确切的說是在能夠寫入目标叢集的TaskTracker上)。 源的格式是 hftp://<dfs.http.address>/<path> (預設情況dfs.http.address是 <namenode>:50070)。
https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEBe5d7ebdffb4406b964a7c900fadc8cdc%3Fmethod%3Ddownload%26read%3Dtrue#8-mapreduce%E5%92%8C%E5%89%AF%E6%95%88%E5%BA%94 8. Map/Reduce和副效應
像前面提到的,map拷貝輸入檔案失敗時,會帶來一些副效應。
- 除非使用了-i,任務産生的日志會被新的嘗試替換掉。
- 除非使用了-overwrite,檔案被之前的map成功拷貝後當又一次執行拷貝時會被标記為 "被忽略"。
- 如果map失敗了mapred.map.max.attempts次,剩下的map任務會被終止(除非使用了-i)。
- 如果mapred.speculative.execution被設定為 final和true,則拷貝的結果是未定義的。