Scala Spark:本地模式下的广播使用
我知道广播允许在每台机器上缓存一个只读副本,而不是将其副本与任务一起发送。 但是,我想知道广播在本地模式下使用时是否有巨大的影响,因为我没有节点集群。 或者在本地模式下不广播也可以使用吗?我只是想了解它的用法 Spark版本#2.0,Scala版本#2.10 本地模式-8核CPU 64GB RAM 我有以下几点:Scala Spark:本地模式下的广播使用,scala,apache-spark,apache-spark-sql,spark-dataframe,Scala,Apache Spark,Apache Spark Sql,Spark Dataframe,我知道广播允许在每台机器上缓存一个只读副本,而不是将其副本与任务一起发送。 但是,我想知道广播在本地模式下使用时是否有巨大的影响,因为我没有节点集群。 或者在本地模式下不广播也可以使用吗?我只是想了解它的用法 Spark版本#2.0,Scala版本#2.10 本地模式-8核CPU 64GB RAM 我有以下几点: case class EmpDim(name: String,age: Int) empDF +-----+-------+------+ |EmpId|EmpName|EmpAge
case class EmpDim(name: String,age: Int)
empDF
+-----+-------+------+
|EmpId|EmpName|EmpAge|
+-----+-------+------+
| 1| John| 32|
| 2| David| 45|
+-----+-------+------+
deptDF
+------+--------+-----+
|DeptID|DeptName|EmpID|
+------+--------+-----+
| 1| Admin| 1|
| 2| HR| 2|
| 3| Finance| 4|
+------+--------+-----+
val empRDD = empDF.rdd.map(x => (x.getInt(0), EmpDim(x.getString(1), x.getInt(2))))
val lookupMap = empRDD.collectAsMap() //Without Broadcast
val broadCastLookupMap: Broadcast[Map[Int,EmpDim]] = sc.broadcast(empRDD.collectAsMap()) //With Broadcast
def lookup(lookupMap:Map[Int,EmpDim]) = udf[Option[EmpDim],Int]((empID:Int) => lookupMap.lift(empID))
val combinedDF = deptDF.withColumn("lookupEmp",lookup(lookupMap)($"EmpID")) //Without Broadcast
.withColumn("broadCastLookupEmp",lookup(broadCastLookupMap.value)($"EmpID")) //With Broadcast
.withColumn("EmpName",coalesce($"lookupEmp.name",lit("Unknown - No Name to Lookup")))
.withColumn("EmpAge",coalesce($"lookupEmp.age",lit("Unknown - No Age to Lookup")))
.drop("lookupEmp")
.drop("broadCastLookupEmp")
+------+--------+-----+---------------------------+--------------------------+
|DeptID|DeptName|EmpID|EmpName |EmpAge |
+------+--------+-----+---------------------------+--------------------------+
|1 |Admin |1 |John |32 |
|2 |HR |2 |David |45 |
|3 |Finance |4 |Unknown - No Name to Lookup|Unknown - No Age to Lookup|
+------+--------+-----+---------------------------+--------------------------+
在上面的场景中,使用广播是明智的还是有点过分?请注意这样使用时,广播没有任何价值 当你打电话时:
lookup(broadCastLookupMap.value)($"EmpID")
broadCastLookupMap.value
将根据Scala替换模型在本地进行评估
正确的实施方法是:
def lookup(lookupMap: Broadcast[Map[Int, EmpDim]]) = udf[Option[EmpDim],Int](
(empID:Int) => lookupMap.value.lift(empID)
)
并呼吁:
lookup(broadCastLookupMap)($"EmpID")
这可能会产生一些积极影响,具体取决于实际执行计划。本地或非本地模式-适用相同的规则
- 如果数据在阶段之间重用(显式或隐式),则广播是有用的
- 如果数据在管道中只使用一次,那么标准的闭包/参数处理机制就足够了
def lookup(lookupMap: => Map[Int,EmpDim]) = udf[Option[EmpDim],Int](
(empID:Int) => lookupMap.lift(empID)
)
谢谢@user9613318的更正。我想知道,正如我在问题中所问的,在这种情况下(本地模式),使用广播与不使用广播有什么区别?这将是一个更好的回答这个问题,所以我可以接受它。