这可能是一个愚蠢的问题,但我想确定是否可以在Spark中广播功能,而不仅仅是数据。
例如,我知道我可以广播数据
scala> val myList=List(1,2,3)
myList: List[Int] = List(1, 2, 3)
scala> sc.broadcast(myList)
res112: org.apache.spark.broadcast.Broadcast[List[Int]] = Broadcast(7)
但是函数呢?例如,
scala> def sum(a:Int):Int={
| val b=a+1
| b
| }
sum: (a: Int)Int
scala> sc.broadcast(sum(_))
res113: org.apache.spark.broadcast.Broadcast[Int => Int] = Broadcast(8)
这实际上是在广播我的方法sum
吗?不知何故,这意味着每个节点现在都有方法sum
的“副本”,也许我可以并行化一些使用方法sum
的作业,也许还可以广播一些数据。这是正确的吗?
答案 0 :(得分:0)
广播通常用于少量数据,这些数据可以很容易地存储在执行者的内存中。这样做的原因是为了缓存数据副本,以便每当实际任务发生时,都不必在执行程序之间移动这些小数据。您可以在这里阅读更多信息:https://spark.apache.org/docs/1.6.0/api/java/org/apache/spark/broadcast/Broadcast.html
现在,如果您的想法是编写自己的函数并将该函数用于并行计算,则应该查看UDF(https://medium.com/@mrpowers/spark-user-defined-functions-udfs-6c849e39443b)。
答案 1 :(得分:0)
是!可以在广播变量中传递完整功能。
如果您的算法(功能)基于某些操作/事件/时间而变化,则可以使用此方法。新功能将与剩余数据一起执行。
def doubleFunction(a: Int):Int={a*2} // function returns the double of input data
val broadcastFunction = sc.broadcast(doubleFunction(_))
val data = sc.parallelize(1 to 10000,4) // sample data
val output1 = data.map(x=>{
val localDoubleFunction = broadcastFunction.value
localDoubleFunction(x) // using function passed in broadcast variable
}).reduce(_+_)
//output1: Int = 100010000
**// Runtime: 78ms**
val output2 = data.map(x=>{
doubleFunction(x) //local broadcast function
}).reduce(_+_)
//output2: Int = 100010000
**//Runtime: 200 ms**