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

怀瑾握瑜的嘉与嘉
发布于 2022-1-23 18:45
浏览
1收藏

春节不停更,此文正在参加「星光计划-春节更帖活动

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


1. 起因

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

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

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

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

2. 什么是广播变量

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

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

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

3. 广播变量示例

如一个数据,转成Map后,每个子任务都需要使用,工作过程大致为:
spark调优(六):大家好才是真的好——广播变量-鸿蒙开发者社区

如把Map转成广播变量时,工作过程大致为:
spark调优(六):大家好才是真的好——广播变量-鸿蒙开发者社区

可以看到广播变量初始的时候就在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端无法修改广播变量的值。


结束语

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

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
2
收藏 1
回复
举报
回复
    相关推荐