记录一个比较典型的问题,先讲一下背景,有这么一个用java写的类
public class JavaClass0 implements Serializable {private static String name;public static JavaClass0 getName(String str) {if (name == null) {name=str;}return name;}...}然后在spark中使用的时候:
//driver端JavaClass0.getName("张三")//得到张三JavaClass0.getName("李四")//得到张三df.foreachPartition{//executor端m=>JavaClass0.getName("王五")//得到王五JavaClass0.getName("钱六")//得到王五}原因: scala的object对应的就是java的静态成员,可以反过来理解java的所有静态成员可被抽取成伴生对象(虽然现实中是scala最终编译成java)。以上面的JavaClass0 例子可理解为等价的scala代码为:
class JavaClass0 {...}//伴生对象object JavaClass0 {private var name:String = nullgetName(str:String) {if (name == null) {name=str}return name;}}可以看到,JavaClass0并没有被传到executor中,而是重新初始化了一遍。事实也是如此。
Objects, as singletons, are never shipped to executors. There initialized locally, whenever objects is accessed for the first time.
object是不会被传递到executor的,他们在首次被访问的时候,在executor本地做初始化。只要executor的jvm不消亡,就不会再次初始化。
参考Sharing objects in Spark Spark Object (singleton) serialization on executors Java中static作用及用法详解