Scala Spark-是否可以广播功能?
这可能是一个愚蠢的问题,但我想确定是否可以在Spark中广播函数,而不仅仅是数据 例如,我知道我可以广播数据Scala Spark-是否可以广播功能?,scala,apache-spark,parallel-processing,Scala,Apache Spark,Parallel Processing,这可能是一个愚蠢的问题,但我想确定是否可以在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
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
的作业。这是正确的吗?广播通常用于少量数据,这些数据可以很容易地保存在执行器的内存中。这样做的原因是为了缓存数据的副本,以便在实际任务发生时,不必跨执行器移动这些小数据。您可以在此处阅读更多内容:
现在,如果您的想法是编写自己的函数并将该函数用于一些并行计算,那么您应该看看UDFs() 是的可以在广播变量中传递完整的函数。
如果您的算法(函数)根据某个动作/事件/时间发生变化,您可以使用这种方法。新函数将与剩余数据一起执行
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**
您不需要广播函数。您在RDD中使用的每个函数都在其中序列化。@shay_uuuu所以如果我尝试类似于
sc.parallelize(Array(1,2,3,4,5)).map(I=>sum(I))
,是否意味着我的函数sum
将自动序列化,这样每个节点现在都有一个sum
的“副本”(粗略地说)?@antonioACR1是,闭包会自动序列化。对于列表之类的数据也是如此。只有当您的数据很大并且您希望避免为每个任务序列化此数据时,广播才是重要的。如果我想在数据帧上应用我自己的函数,我认为使用UDF,但是,我现在没有处理数据帧。当我尝试运行output1
时,我得到了错误java.io.IOException:com.esotericsoftware.kryo.KryoException:构造类实例时出错:
。你知道原因是什么吗?如果我收集RDD,那么它也能工作,你能告诉我你的代码中reduce(+\uu)
在做什么吗?我猜你是在纱线上运行代码。对于上面的例子,我使用了聚合函数。因此需要收取费用。我不完全确定Kyro例外reduce(+)
相当于reduce((a,b)=>a+b)
。所以它基本上是对所有的数字求和,但是以一种分布式的方式(spark)!我使用Cloudera虚拟机在spark shell中运行了您的代码,尽管在运行其他代码之前,我多次出现相同的错误。。。