我知道广播允许在每台机器上保留一个只读副本,而不是随副本一起发送副本。 但是,我想知道广播在本地模式下是否会产生巨大影响,因为我没有节点集群。 或者在本地模式下不使用广播就可以使用?我只是想了解它的用法。
Spark版本#2.0,Scala版本#2.10 本地模式 - 8Cores CPU 64GB RAM
我有类似下面的内容:
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|
+------+--------+-----+---------------------------+--------------------------+
在上面的场景中,建议使用广播还是有点矫枉过正?请建议
答案 0 :(得分:0)
如果这样使用,广播根本就没有价值。
致电时:
lookup(broadCastLookupMap.value)($"EmpID")
根据Scala替换模型, broadCastLookupMap.value
将在本地进行评估。
正确的实施将是:
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)
)