以下是我程序主要方法的代码:
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的值写入上下文时,我得到一个零值,这是变量len的默认值。
因此,我无法按照自己的意愿得到正确的结果。我很困惑为什么内部静态类RouteReducer无法访问外部类Route的静态变量。
答案 0 :(得分:2)
Hadoop是分布式系统。已编译的映射器和reducer实现类被复制到其他节点,它们在自己的JVM中工作。因此,主类和每个任务都会看到相同变量的不同实例。您需要手动将数据从主类传递到任务。
轻量级数据可以从主类传递到地图,并通过Configuration
减少任务:
// 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传输大量数据。