現實環境中,常常遇到一個問題就是想使用多個Reduce,但是迫於setup和cleanup在每一個Reduce中會調用一次,只能設置一個Reduce,無法是實現負載均衡。
問題,如果要在reduce中輸出兩種文件,一種是標志,另一種是正常業務數據,實現方案有三種:
(1)設置一個reduce,在reduce中將數據封裝到一個集合中,在cleanup中將數據寫入到hdfs中,但是如果數據量巨大,一個reduce無法充分利用資源,實現負載均衡,但是如果數據量較小,可以使用
(2)設置多文件輸出,使用MultipleOutputs類
具體見代碼:
- private MultipleOutputs mos;
- @Override
- protected void setup(Context context)
- throws IOException, InterruptedException {
- mos=new MultipleOutputs(context);
- }
- @Override
- protected void reduce(Text key, Iterable<Text> values, Context context)
- throws IOException, InterruptedException {
- String key1=key.toString();
- for(Text t:values){
- if(key1.equals("a")){
- mos.write("a", key,t);
- } else if(key1.equals("b")){
- mos.write("b", key,t);
- } else if(key1.equals("c")){
- mos.write("c", key,t);
- }
- }
- }
- @Override
- protected void cleanup(
- Context context)
- throws IOException, InterruptedException {
- mos.close();
- }
- main方法中配置
- <pre name="code" class="java">MultipleOutputs.addNamedOutput(job, "a", TextOutputFormat.class, Text.class, Text.class);
- MultipleOutputs.addNamedOutput(job, "b", TextOutputFormat.class, Text.class, Text.class);
- MultipleOutputs.addNamedOutput(job, "c", TextOutputFormat.class, Text.class, Text.class);
- 結果文件為 a-r-0000,b-r-0000,c-r-0000,part-r-0000
(3)第三種方案是自己實現多文件輸出 詳見http://blog.csdn.net/qingmu0803/article/details/39665407