Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala Spark-是否可以广播功能?_Scala_Apache Spark_Parallel Processing - Fatal编程技术网

Scala 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

这可能是一个愚蠢的问题,但我想确定是否可以在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
的作业。这是正确的吗?

广播通常用于少量数据,这些数据可以很容易地保存在执行器的内存中。这样做的原因是为了缓存数据的副本,以便在实际任务发生时,不必跨执行器移动这些小数据。您可以在此处阅读更多内容:


现在,如果您的想法是编写自己的函数并将该函数用于一些并行计算,那么您应该看看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中运行了您的代码,尽管在运行其他代码之前,我多次出现相同的错误。。。