如何访问在mapreduce中扩展reducer的静态内部类中的静态变量?

Posted

技术标签:

【中文标题】如何访问在mapreduce中扩展reducer的静态内部类中的静态变量?【英文标题】:How to access the static variable in the static inner class which extends reducer in mapreduce? 【发布时间】:2017-02-16 13:26:56 【问题描述】:

这是我的程序的主要方法的代码:

public class Path 
public static void main(String[] args) throws Exception 
    ArrayList<String> input = new ArrayList<String> ();
    input.add(args[0]);
    String output0="/output/path2";

    Route r1 =new Route(input,output0,2);
    r1.main(args);
    input.add(output0);
    String output1="/output/path3";

    Route r2 =new Route(input,output1,3);
    r2.main(args);

类路由包含一个静态内部类扩展映射器和一个静态内部类扩展reducer。 这是与我的问题相关的类路由定义的一部分:

public class Route 
public static int len;
public static String output;
public static ArrayList<String> input = new ArrayList<String> ();

public static class RouteMapper extends Mapper<Object, Text, Text, Text> 
    public void map(Object key,Text value,Context context) throws IOException,InterruptedException 
       //do map
    


public static class RouteReducer extends Reducer<Text, Text, Text, Text> 
    public void reduce(Text key, Iterable<Text> values, Context context) throws IOException,InterruptedException
       //do reduce
    


public Route(ArrayList<String> in,String out,int l)
    len = l;
    output = out;
    Iterator itr = in.iterator();
    while(itr.hasNext())
        input.add(itr.next().toString());
    


public static void main(String[] args) throws Exception 
    Configuration conf = new Configuration();
    //some configs of mapreduce

正如你在我的 main 方法中看到的,静态变量 len 的值在两个 map/reduce 短语中应该是 2 和 3。但是,当我尝试将 len 的值写入 reduce 短语中的上下文时,我得到的值为零,这是变量 len 的默认值。 因此,我无法得到我希望的正确结果。我很困惑为什么内部静态类RouteReducer不能访问外部类Route的静态变量。

【问题讨论】:

这是一个比什么都重要的观察,但我认为在 MapReduce 中使用静态类和静态变量只会使事情变得混乱。我猜标准 wordcount 示例使用它们,但我不会将其用作实际编写 MR 的模型。让您成为 Maps/Reducers 他们自己的(非静态)类,并使用配置将配置传递给它们,这就是它的用途。默认情况下,我不会做任何静态的。 【参考方案1】:

Hadoop 是分布式系统。已编译的映射器和缩减器实现类被复制到它们在自己的 JVM 中工作的其他节点。因此,主类和每个任务都会看到相同变量的不同实例。您需要手动将数据从主类传递给您的任务。

轻量级数据可以通过Configuration从主类传递给map和reduce任务:

// in main
public static final String CONF_LEN = "conf.len";
...
conf.setInt(CONF_LEN, 3);

// in mapper
@Override
protected void setup(Mapper<Object, Text, Text, Text>.Context context) throws IOException, InterruptedException 
  super.setup(context);
  this.len = context.getConfiguration().getInt(CONF_LEN, -1);

大量数据可以通过distributed cache进行传输。

【讨论】:

以上是关于如何访问在mapreduce中扩展reducer的静态内部类中的静态变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何将java类对象作为mapreduce中map函数的输入?

如何查看hadoop mapreduce 性能

如何自定义一个hadoop mapreducer中reducer输出的时候以csv文件输出。

如何使用 Map Reduce 改进聚合处理时间?

MapReduce的Shuffle机制

如何在 Hadoop Mapreduce 程序中使用机器学习算法?