spark广播变量 和 累加器
1 为什么使用广播变量 和 累加器
变量存在的问题:在spark程序中,当一个传递给Spark操作(例如map和reduce)的函数在远程节点上面运行时,Spark操作实际上操作的是这个函数所用变量的一个独立副本。这些变量会被复制到每台机器上,并且这些变量在远程机器上的所有更新都不会传递回驱动程序,通常跨任务的读写变量是低效的。
广播变量的目的就是解决变量存在的问题,变量声明为广播变量,那么知识每个executor拥有一份,这个executor启动的task会共享这个变量,节省了通信的成本和服务器的资源。
总的来说:累加器是用来对信息进行聚合,广播变量是用来分发较大的只读对象。
2 如何定义 和 还原 广播变量
int a = 3; Broadcast<Integer> broadcast = sc.broadcast(a); //定义广播变量
int c = broadcast.value; //还原广播变量
3 广播变量注意事项
(1)变量一旦被定义为一个广播变量,那么这个变量只能读,不能修改
(2)能不能将一个RDD使用广播变量广播出去?
不能,因为RDD是不存储数据的。可以将RDD的结果广播出去。
(3) 广播变量只能在Driver端定义,不能在Executor端定义。
(4) 在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值。
(5)如果executor端用到了Driver的变量,如果不使用广播变量在Executor有多少task就有多少Driver端的变量副本。
(6)如果Executor端用到了Driver的变量,如果使用广播变量在每个Executor中只有一份Driver端的变量副本。
4 广播变量的优化
当广播一个比较大的值时,选择既快又好的序列化格式是很重要的。因为如果序列化对象的时间很长或者传送时间太久,这段时间很容易出现性能瓶颈。
默认情况下,spark会使用java内建的序列化库。建议选择kryo序列化工具,使用方法设置spark.serializer为org.apache.spark.serializer.KryoSerializer;
最好强制要求这种注册,设置spark.kryo.registrationRequired为true;
SparkConf conf = new SparkConf(); conf.set("spark.serializer","org.apache.spark.serializer.KryoSerializer"); conf.set("spark.kryo.registrationRequired","true"); conf.registerKryoClasses(Array(classOf[myClass]),classOf(MyOtherClass));
这样还会有其他的问题,如果代码中引用的类没有序列化,会报异常,最简单的方式是实现序列化接口。
5 累加器和定义和还原
累加器只是一个只写变量
LongAccumulator accumulator = new LongAccumulator(); accumulator.add(1); long count = accumulator.count();
参考文献:扎心了,老铁
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!