我的spark应用程序中有一个全局配置对象。
Object Config {
var lambda = 0.01
}
我将根据用户的输入设置lambda的值。
Object MyApp {
def main(args: String[]) {
Config.lambda = args(0).toDouble
...
rdd.map(_ * Config.lambda)
}
}
我发现修改不会在执行者中生效。 lambda的值始终为0.01。我想驱动程序的jvm中的修改不会影响执行程序的。
你有其他解决方案吗?
我在stackoverflow中发现了一个类似的问题:
how to set and get static variables from spark?
但我想知道如何编写闭包以及如何将其序列化为执行程序,是否有人可以给我一些代码示例?
2.如果值已修复或配置在执行程序节点上可用(生活在jar内等),那么您可以使用延迟val,只保证初始化一次。
如果我将lambda声明为lazy val变量怎么办?驱动程序中的修改会在执行程序中生效吗?你能给我一些代码示例吗?
3.用数据创建广播变量。我知道这种方式,但它还需要一个包装Config对象的本地Broadcast []变量吗?例如:
val config = sc.broadcast(Config)
并在遗嘱执行人中使用config.value.lambda
,对吗?
答案 0 :(得分:4)
object Config {var lambda = 0.01}
object SOTest {
def main(args: Array[String]) {
val sc = new SparkContext(new SparkConf().setAppName("StaticVar"))
val r = sc.parallelize(1 to 10, 3)
Config.lambda = 0.02
mul(r).collect.foreach(println)
sc.stop()
}
def mul(rdd: RDD[Int]) = {
val l = Config.lambda
rdd.map(_ * l)
}
}
object SOTest {
def main(args: Array[String]) {
lazy val lambda = args(0).toDouble
val sc = new SparkContext(new SparkConf().setAppName("StaticVar"))
val r = sc.parallelize(1 to 10, 3)
r.map(_ * lambda).collect.foreach(println)
sc.stop()
}
}
object Config {var lambda = 0.01}
object SOTest {
def main(args: Array[String]) {
val sc = new SparkContext(new SparkConf().setAppName("StaticVar"))
val r = sc.parallelize(1 to 10, 3)
Config.lambda = 0.04
val bc = sc.broadcast(Config.lambda)
r.map(_ * bc.value).collect.foreach(println)
sc.stop()
}
}
注意:您不应直接将Config Object
传入sc.broadcast()
,它会将您的配置序列化,然后再将其传输给执行者,但是,您的配置不可序列化。另外需要提及的是:Broadcast variable
不适合您的情况,因为您只共享一个值。