如何从spark设置和获取静态变量?
我有一个这样的课:
public class Test { private static String name;
public static String getName() {
return name;
}
public static void setName(String name) {
Test.name = name;
}
public static void print() {
System.out.println(name);
}
}
在我的Spark驱动程序中,我像这样设置名称并调用print()
命令:
public final class TestDriver{ public static void main(String[] args) throws Exception {
SparkConf sparkConf = new SparkConf().setAppName("TestApp");
// ...
// ...
Test.setName("TestName")
Test.print();
// ...
}
}
但是,我得到一个NullPointerException
。如何将值传递给全局变量并使用它?
回答:
好的,基本上有两种方法可以将执行者已知的值带给执行者:
- 将值放在闭包中,然后序列化到执行程序以执行任务。这是最常见的一种,非常简单/优雅。示例和文档 。
- 用数据创建一个广播变量。这对于大容量的不可变数据很有用,因此您要保证仅发送一次。如果反复使用相同的数据,也很好。示例和文档 。
两种情况下都无需使用静态变量。但是,如果您确实想在执行程序VM上使用静态值,则需要执行以下操作之一:
- 如果值是固定的,或者在执行程序节点上可用配置(位于jar内等),则可以有一个惰性val,仅保证一次初始化。
- 您可以使用上面两个选项之一使用代码调用mapPartitions(),然后将值存储在静态变量/对象中。保证mapPartitions对于每个分区仅运行一次(比每行一次好得多),并且对于这种情况(初始化数据库连接等)很有用。
希望这可以帮助!
PS:关于您的例外:我只是在该代码示例中看不到它,所以我敢保证它发生在其他地方。
编辑以进一步澄清:惰性val解决方案只是Scala,不涉及Spark …
object MyStaticObject{
lazy val MyStaticValue = {
// Call a database, read a file included in the Jar, do expensive initialization computation, etc
4
}
}
由于每个执行器都对应一个JVM,因此一旦加载了类,MyStaticObject
便会初始化。该lazy
关键字保证了MyStaticValue
变量将只在首次初始化它实际上是要求,并从此保持其价值。
以上是 如何从spark设置和获取静态变量? 的全部内容, 来源链接: utcz.com/qa/419766.html