1. 程式人生 > 其它 >Yarn(MapReduce 2.0)下分散式快取(DistributedCache)的注意事項

Yarn(MapReduce 2.0)下分散式快取(DistributedCache)的注意事項

1、問題

最近公司的叢集從 Apache hadoop 0.20.203 升級到了 CDH 4,邁進了 Hadoop 2.0 的新時代,雖然新一代的 hadoop 努力做了架構、API 上的各種相容, 但總有“照顧不周”的地方,下面說的這個有關分散式快取的案例就是於此有關:一些 MR job 遷移到 Yarn 上後,發覺沒資料了,而且沒有報錯。 查了下資料來源和程式碼,發現是分散式快取(DistributedCache)的用法有點小變化。以前的老程式碼大致如下:

(1)在 main 函式中新增分散式快取檔案:

...
String cacheFilePath = "/dsap/rawdata/cmc_unitparameter/20140308/part-m-00000";
DistributedCache.addCacheFile(new Path(cacheFilePath).toUri(), job.getConfiguration());
...

(2)在 MR 初始化的時候讀取快取檔案做資料字典:

...
// 從當前作業中獲取要快取的檔案
Path[] paths = DistributedCache.getLocalCacheFiles(context.getConfiguration());
for (Path path : paths) {
    if (path.toString().contains("cmc_unitparameter")) {
        ...

(3)結果:

這兩段程式碼在 MR1 時代毫無問題,但是到了 MR2 時代 if 是永遠為 false 的。 特意對比了下 MR1 和 MR2 時代的 path 格式,可以看到在 MRv2 下,Path 中不包含原始路徑資訊了:

MR1 Path:   hdfs://host:fs_port/dsap/rawdata/cmc_unitparameter/20140308/part-m-00000
MR1 Path:   hdfs://host:fs_port/dsap/rawdata/cmc_unitparameter/20140308/part-m-00000


MR2 Path:   /data4/yarn/local/usercache/root/appcache/application_1394073762364_1884/container_1394073762364_1884_01_000006/part-m-00000
MR2 Path:   /data17/yarn/local/usercache/root/appcache/application_1394073762364_1884/container_1394073762364_1884_01_000002/part-m-00000
MR2 Path:   /data23/yarn/local/usercache/root/appcache/application_1394073762364_1884/container_1394073762364_1884_01_000005/part-m-00000

看了上面兩種差異我想你能明白為啥分散式快取在 MR2 下面“失效了”。。。

2、解決方案

解決這個問題不難:

其實在 MR1 時代我們上面的程式碼是不夠規範的,每次都遍歷了整個分散式快取,我們應該用到一個小技巧:createSymlink

(1)main 函式中為每個快取檔案新增符號連結:類似於 HTTP URL 的 # 錨點一樣

...
String cacheFilePath = "/dsap/rawdata/cmc_unitparameter/20140308/part-m-00000";
Path inPath = new Path(cacheFilePath);
// # 號之後的名稱是對上面檔案的連結,不同檔案的連結名不能相同,雖然由你自己隨便取
String inPathLink=inPath.toUri().toString()+"#"+"DIYFileName";
DistributedCache.addCacheFile(new URI(inPathLink), job.getConfiguration());
...

加了軟連結後,path 資訊的最後部分就是你剛才的 DIYFileName:

/data4/yarn/local/usercache/root/appcache/application_1394073762364_1966/container_1394073762364_1966_01_000005/cmcs_paracontrolvalues
/data4/yarn/local/usercache/root/appcache/application_1394073762364_1966/container_1394073762364_1966_01_000005/cmc_unitparameter

(2)在需要用快取檔案的地方直接根據你剛才 # 後面自定義的檔名讀取即可

BufferedReader br = null;
br = new BufferedReader(new InputStreamReader(new FileInputStream("DIYFileName")));

(3)其它地方的用法和程式碼與 MR1 無任何變化。

3、Refer:

1、Hadoop 多表 join:map side join 範例

http://my.oschina.net/leejun2005/blog/111963

2、Hadoop DistributedCache詳解

http://dongxicheng.org/mapreduce-nextgen/hadoop-distributedcache-details/

3、迭代式MapReduce解決方案(二) DistributedCache

http://hongweiyi.com/2012/02/iterative-mapred-distcache/

4、DistributedCache小記

http://www.cnblogs.com/xuxm2007/p/3344930.html