MapReduce Job中全局共享數據的處理辦法


在編寫MapReduce程序時,經常會遇到這樣的問題,全局變量如何保存?如何讓每個處理都能獲取保存的這些全局變量?使用全局變量是不可避免的,但是 在MapRdeuce中直接使用代碼級別的全局變量是不現實的。主要是因為繼承Mapper基類的Map階段類的運行和繼承Reducer基類的 Reduce階段類的運行都是獨立的,並不共享一個Java虛擬機的資源,因此,下面介紹三種在MapReduce編程中相對有效的設置全局共享數據的方 法。

1,讀寫HDFS文件

在MapReduce框架中,Map Task和Reduce Task都運行在Hadoop集群的節點上,所以Map和Reduce Task、甚至不同的Job都可以通過讀寫HDFS中預定好的同一文件來實現全局共享數據。具體實現是利用Hadoop 的Java API來完成,需要注意的是,多個Map或Reduce的寫操作會產生沖突,覆蓋原有數據。

這種方法的優點是能夠實現讀寫,也比較直觀,但是缺點是需要共享一些很小的全局數據也需要使用IO,這將占用系統資源,增加作業完成的資源消耗。

2,配置Job屬性

在MapReduce執行過程中,task可以讀取Job的屬性。基於這個特性,我們可以在任務啟動之初利用Configuration類中的 set(String name,String value)將一些簡單的全局數據封裝到作業的配置屬性中,然后task再利用Configuration中的get(String name)獲取配置到屬性中的全局數據。

這種方法的優點是簡單,資源消耗小,但是對量比較大的共享數據顯得比較無力。(個人推薦這種)

3,使用DistributedCache

DistributedCache是MapReduce為應用提供緩存文件的只讀工具,它可以緩存文本文件,壓縮文件和jar文件等。在使用時,用戶可以 在作業配置中使用本地或HDFS文件的URL來將其設置成共享緩存文件。在作業啟動之后和task啟動之前,MapReduce框架會將可能需要的緩存文 件復制到執行任務節點的本地。

這種方法的優點是每個Job共享文件只會子啊啟動之后復制一次,並且它適用與大量的共享數據,而缺點是它是只讀的。

下面是一個簡單的使用DistributedCache的例子。

1)將要緩存的文件復制到HDFS上

1
bin/hadoop fs -copyFromLocal lookup /myapp/lookup

2)啟動作業的屬性配置,並設置待緩存文件

1
2
Configuration conf = new Configuration();
DistributedCache.addCacheFile( new URL( "/myapp/lookup #lookup" ),conf);

3)在Map函數中使用DistributedCache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static class Map extends Mapper<Object, Text, Text,Text>{
 
private Path[] localArchives;
 
private Pah[] localFiles;
 
public void setup(Context context) throws IOException,InterruptedException{
 
//獲取緩存文件
 
Configuration conf = new Configuration();
 
localArchives = DistributedCache.getLocalCacheArchives(conf);
 
localFiles = DistributedCache.getLocalCacheFiles(conf);
 
}
 
public void map(K key, V value, Context context) throws IOException{
 
//使用緩存文件中獲取的數據
 
...
 
Context.collect(k,v);
 
}
 
}
歡迎轉載,請注明出處: http://www.ming-yue.cn/solution-to-global-share-data-in-mapreduce-job/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM