hadoop全局變量與數據傳遞


首先明確:

1.Hadoop不支持全局變量,也不建議使用全局變量。

   我的理解是,這是因為hadoop具有map類和reducer類,並且不同的task一般執行的是不同的map或reduce。所以全局變量是無法傳遞的。(但是一般情況下,我們也許會需要一個對於所有map和reduce都能訪問的全局變量),暫時我知道的解決方法如下:

2.如果Mapper類和Reducer類都是主類的內部類,可以在主類中使用 private static string  global = "global variable";

   但是這種方法不通用,因為Mapper類和Reducer類在概念上是與主類無關的。很多情況下,他們不是主類的內部類。所以該task所擁有的信息,只能從context上下文中獲得,這也正體現了常說的:充足的上下文信息才是關鍵!

   修正:Mapper類(或Reducer類) 使用 主類名.global 也可以獲取全局變量。。

3.設置xml文件,然后在map函數中讀取即可;

  這種方法有一個缺點,值只能從客戶端傳遞到Mapper中,reduce不能讀出來。實際上reducer所知道的只有context信息。

4.直接在Configuration中設置屬性值,然后讀取這個屬性值,在Mapper或Reducer中使用變量來存儲這個值即可。

  可以看出這種方式最為麻煩。可以將各個屬性值放入文件中,然后在文件讀取即可。

   關鍵代碼如下:

//初始化configuration后,使用
conf.set("propertyName“,properyValue);

 //在mapper或reducer中,
 Configuration conf = context.getConfiguration();
 String g = conf.get("propertyName");

   //g作為可以使用的全局變量即可;

這里的文章講述了hadoop下數據的傳遞:http://blog.csdn.net/jackydai987/article/details/6441241

代碼如下

public class xml_test {  
    public static int getFileInt(String filename) //從文件中讀取預設值  
    {  
        int temp = 0;  
        Configuration config = new Configuration();  
        FSDataInputStream dis = null;  
        try {  
                ByteArrayOutputStream baos = new ByteArrayOutputStream();   
                FileSystem hdfs = FileSystem.get(config);  
                dis = hdfs.open(new Path(filename));  
                IOUtils.copyBytes(dis, baos, 4096, false); //寫入ByteArrayOutputStream  
                String str = baos.toString();  //這里我假定只有一行,多行可以使用循環。  
                str = str.substring(0, str.length() - 1); //最后一個是回車,需要過濾掉,不然在整形轉換時會出錯  
                temp = Integer.parseInt(str);  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }     
            finally{  
                IOUtils.closeStream(dis);  
            }  
        return temp;  
}  
    public static  class wordcountMapper extends  
        Mapper<LongWritable, Text, Text, IntWritable>{  
        int temp2 = getFileInt("/user/jackydai/int"); //從文件中讀取預設的值  
        //這里也可以通過args參數傳一個文件進來,這樣更靈活  
        private Text word = new Text();  
        public void map(LongWritable key, Text value, Context context)throws IOException, InterruptedException{  
            int temp1 = 0;  
            Configuration mapconf = context.getConfiguration();  
            temp1 = mapconf.getInt("count", 0); //map讀取值  
            IntWritable one = new IntWritable(temp1 + temp2); //求和后輸出,檢測是否正確  
            String line = value.toString();  
            StringTokenizer itr = new StringTokenizer(line);  
            while(itr.hasMoreElements()){  
                word.set(itr.nextToken());  
                context.write(word, one);  
            }  
        }  
    }  
    public static  class wordcountReduce extends  
        Reducer<Text, IntWritable, Text, IntWritable>{  
        public void reduce(Text key, Iterable<IntWritable>values, Context context)throws IOException, InterruptedException{  
            int sum = 0;  
            for (IntWritable str : values){  
                sum += str.get();  
            }  
            context.write(key, new IntWritable(sum));  
        }  
    }  
    public static  void main(String args[])throws Exception{  
          
        Configuration conf = new Configuration();  
          
        conf.setInt("count", 2); //設置值為2,需要注意的是設置值需要在new job之前  
          
        Job job = new Job(conf, "xml_test");  
          
        job.setJarByClass(xml_test.class);  
          
        job.setInputFormatClass(TextInputFormat.class);  
          
        job.setOutputKeyClass(Text.class);  
        job.setOutputValueClass(IntWritable.class);  
          
        job.setMapperClass(wordcountMapper.class);  
        job.setReducerClass(wordcountReduce.class);  
        job.setCombinerClass(wordcountReduce.class);  
          
        FileInputFormat.setInputPaths(job, new Path(args[1]));  
        FileOutputFormat.setOutputPath(job, new Path(args[2]));  
          
        job.waitForCompletion(true);  
    }  
}


免責聲明!

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



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