写点什么

spark 调优(六):大家好才是真的好——广播变量

  • 2022 年 7 月 15 日
  • 本文字数:1050 字

    阅读完需:约 3 分钟

大家好,我是怀瑾握瑜,一只大数据萌新,上能 code 下能 teach 的全能奶爸,家有两只吞金兽,嘉与嘉如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~



1. 起因

在进行数据处理时,会经常用到一些中间表,比如 DIM 表,比如其他数据源的数据。


如果这些数据量很小,直接与大数据做 JOIN,会很影响性能。


如果直接解开数据转成对象,这个对象是放在 driver 中的,executor 端直接使用 Driver 的变量在 Executor 有多少 task 就有多少 Driver 端的变量副本。


所以这里我们就要使用“广播变量”。

2. 什么是广播变量

广播变量允许程序员在每台计算机上缓存只读变量,而不是将其副本与任务一起发送。例如,它们可以为每个节点提供一个大数据集的副本,而不用给每个 task 来传送一个副本。


广播变量只会被发到各个节点一次,应作为只读值处理(修改广播变量的值不会影响到别的节点)。


Spark 会使用高效的广播算法来分配广播变量,以降低通信成本。

3. 广播变量示例

如一个数据,转成 Map 后,每个子任务都需要使用,工作过程大致为:



如把 Map 转成广播变量时,工作过程大致为:



可以看到广播变量初始的时候就在 Drvier 上有一份副本,task 在运行的时候,想要使用广播变量中的数据,此时首先会在自己本地的 Executor 对应的 BlockManager 中,尝试获取变量副本。如果本地没有,那么就从 Driver 远程拉取变量副本,并保存在本地的 BlockManager 中,此后这个 executor 上的 task 都会直接使用本地的 BlockManager 中的副本。executor 的 BlockManager 除了从 driver 上拉取,也可能从其他节点的 BlockManager 上拉取变量副本,距离越近越好。

4. 实际应用

将查询到的数据转成 Map,然后在 driver 中广播出去,在子任务执行时可以直接获取。


使用 broadcast 方法声明广播变量,使用 getValue 方法获取广播变量。


Map<Long, VehicleInfo> vehicleInfoMap = new HashMap<>();// 声明广播变量JavaSparkContext jsc = new JavaSparkContext(sparkSession.sparkContext());Broadcast<Map<Long, VehicleInfo>> vehicleInfoBroadcast = jsc.broadcast(vehicleInfoMap);rdd.mapPartitions(x->{    // 获取广播变量  Map<Long, VehicleInfo> vehicleInfoMap = vehicleInfoBroadcast.getValue();});
复制代码

5. 注意事项

  1. 广播变量只能在 Driver 端定义,不能在 Executor 端定义。

  2. 不能将一个 RDD 广播出去,只能将 RDD 的结果广播出去。

  3. 在 Driver 端可以修改广播变量的值,在 Executor 端无法修改广播变量的值。



结束语

如果您喜欢我的文章,可以[关注⭐]+[点赞👍]+[评论📃],您的三连是我前进的动力,期待与您共同成长~

发布于: 刚刚阅读数: 3
用户头像

还未添加个人签名 2022.07.01 加入

还未添加个人简介

评论

发布
暂无评论
spark调优(六):大家好才是真的好——广播变量_spark_怀瑾握瑜的嘉与嘉_InfoQ写作社区