一:广播变量的作用
广播变量允许开发者将一个 Read-Only 的变量缓存到集群中每个节点中, 而不是传递给每一个 Task 一个副本.
所以在需要跨多个 Stage 的多个 Task 中使用相同数据的情况下, 广播特别的有用
二:广播变量的API
三:广播变量的使用
class demo04 {
private val sc: SparkContext = new SparkContext(new SparkConf().setMaster("local[2]").setAppName("broadcast"))
@Test
def broadcast = {
//1.创建广播变量
val bc: Broadcast[Int] = sc.broadcast(100)
println("变量的id值 : "+bc.id) //变量的id值 : 0
println("toString : "+bc.toString()) //toString : Broadcast(0)
//2.使用value获取广播变量的值
println(bc.value) //100
//3.使用unpersist删除数据
bc.unpersist()
//4.unpersist删除数据后还是可以使用变量
//结果: unpersist之后再次打印: 100
println("unpersist之后再次打印: "+bc.value)
//5.使用destroy销毁变量
bc.destroy()
//6.尝试销毁之后再次使用广播变量bc
//报错:org.apache.spark.SparkException: Attempted to use Broadcast(0) after it was destroyed (destroy at demo04.scala:19)
println("销毁之后再次打印: "+bc.value)
//7.尝试多次destroy变量
//报错:org.apache.spark.SparkException: Attempted to use Broadcast(0) after it was destroyed (destroy at demo04.scala:19)
println("======================================")
bc.destroy()
}
}
注意:
1.而且在 Spark 中还有一个约定俗称的做法, 当一个 RDD 很大并且还需要和另外一个 RDD 执行 join 的时候, 可以将较小的 RDD 广播出去, 然后使用大的 RDD 在算子 map 中直接 join, 从而实现在 Map 端 join
2.RDD在广播出去之前需要执行Action算子,比如: collect,因为RDD中无法保存数据
3.一般情况下在这种场景下, 会广播 Map 类型的数据, 而不是数组, 因为这样容易使用 Key 找到对应的 Value 简化使用