使用广播变量,每个Executor的内存中,只驻留一份变量副本, 而不是对每个 task 都传输一次大变量(一个executor可以执行多个task),省了很多的网络传输, 对性能提升具有很大帮助, 而且会通过高效的广播算法来减少传输代价。
使用广播变量的场景很多, 我们都知道spark 一种常见的优化方式就是小表广播, 使用 map join 来代替 reduce join, 我们通过把小的数据集广播到各个节点上,节省了一次特别 expensive 的 shuffle 操作。
为什么只能 broadcast 只读的变量
这就涉及一致性的问题,如果变量可以被更新,那么一旦变量被某个节点更新,其他节点要不要一块更新?如果多个节点同时在更新,更新顺序是什么?怎么做同步? 仔细想一下, 每个都很头疼, spark 目前就索性搞成了只读的。 因为分布式强一致性很难处理。
广播变量使用步骤:
1 在主程序里将参数对象广播出去:
val broadcastConf = ssc.sparkContext.broadcast(appProperties)
2 在rdd算子内这样获取广播变量的值:
val appProp = broadcastConf.value
3 然后再通过参数对象appProp去获取相应的参数:appProp.getDstTopic