我正在努力了解spark闭包中的变量生命周期,以及spark如何序列化代码并将代码分发给执行者。
我列出了3种不同的场景,以提供对象进行地图变换。我从Spark Wiki Spark Closure了解到,当我在分布式模式下运行作业(master=yarn)
时,只有Scenerio 3可以正常工作,其余的会抛出异常。尽管Scenerio 1未使用Broadcast变量,但仍产生与Scenerio 2相同的结果。
我想了解的是Scenerio 1与2有何不同?
测试Bean类
public class TestBean implements Serializable {
String val;
public TestBean(String val) {
this.val = val;
}
public String message(Integer msg){
return String.format("%s==>%d",val,msg);
}
}
映射功能以添加邮件
public class Fn implements Function<Integer,String> {
TestBean obj;
public Fn(TestBean obj ){
this.obj=obj;
}
@Override
public String call(Integer param) throws Exception {
return "Fn:"+obj.message(param);
}
}
用5个数字创建RDD:
TestBean bean = new TestBean("Hello");
JavaRDD<Integer> rdd = context.parallelize(IntStream.range(0, 5).boxed().collect(Collectors.toList()));
将对象引用传递给地图转换的可能方法:
使用功能-
提供TestBean对象引用rdd.map(new Fn(bean)).collect();
使用Broadcast变量提供testBean:
Broadcast<TestBean> beanBroadCast = context.broadcast(bean);
rdd.map(obj -> beanBroadCast.getValue().message(obj)).collect();
直接使用lambda表达式进行引用:
rdd.map(obj -> bean.message(obj)).collect();