Spark有两种共享变量方式:广播变量(broadcast variable)与累加器(accumulator)。
累加器用来对信息进行聚合,而广播变量用来高效分发较大的只读对象。
共享变量的作用
共享变量允许在spark应用的driver程序与executor之间共享信息。共享变量允许在RDD的各个partition之间高效地共享信息。
主要有两个作用:
- 广播大的只读值。通过广播变量,可以高效地向所有工作节点发送一个大的数据集,而不需要这个数据集复制多份。
- 在工作节点之间累加值。可以通过累加器实现对所有工作节点上的某个值进行更新。
共享变量的类型
- 广播变量(Broadcast Variables):使用SparkContext的broadcast()创建广播变量,用于分发一个只读值的副本。
- 累加器(Accumulators):使用SparkContext的accumulator()创建累加器,需要指定初始值和add操作,用于聚合每个partition的信息。
广播变量(Broadcast Variables)
- 创建广播变量
使用SparkContext的broadcast()方法创建广播变量。该方法会返回一个Broadcast对象。
broadcast_var = sc.broadcast(some_value)
- 在Driver程序中操作广播变量
在Driver程序中,可以通过Broadcast对象的value属性获取广播变量的值。
print(broadcast_var.value)
- 在RDD操作中使用广播变量
在RDD的map、filter等transformation操作中,可以直接通过广播变量的名称访问变量值,不需要通过value属性。
rdd.map(lambda x: x + broadcast_var)
Spark会将broadcast_var自动传输到各个工作节点上,map操作可以直接访问该变量。
- 关闭广播变量(可选)
使用完广播变量后,可以通过unpersist()方法关闭广播变量,释放资源。
broadcast_var.unpersist()
需要注意的是,广播变量是只读的,不能在transformation操作中修改其值。广播变量通常用于高效分发一个较大的只读参数。
累加器(Accumulators)
- 创建累加器
使用 SparkContext 的 accumulator() 方法创建累加器,并指定初始值和添加操作(add):
accum = sc.accumulator(0)
- 在 RDD 操作中使用累加器
在 RDD 的各个 partition 中,可以通过累加器的 add 方法来更新其值:
rdd.foreach(lambda x: accum.add(x))
需要注意的是,累加器只能在 action 操作中使用,不能在 transformation 中使用。
- 获取累加器的值
任务完成后,可以通过累加器的 value 属性获取聚合的结果:
print(accum.value)
- 关闭累加器(可选)
使用完成后,可以通过累加器的 destroy() 方法关闭累加器,释放资源:
accum.destroy()
累加器通常用于实现计数器、求和等功能,可以高效地聚合 RDD 中每个 partition 的信息。
广播变量(Broadcast Variables)解决了什么问题?
- 避免了重复传输大对象
Spark应用程序中经常会用到一些大的只读对象,如查找表或机器学习模型。如果不使用广播变量,这些大对象会跟其他数据一起,在任务之间进行传输,导致重复数据传输和延迟。
使用广播变量可以将这些大对象广播到所有节点,每个节点只保存一份,从而大大减少传输次数。
- 分布式共享只读状态
有时需要在不同的任务中共享只读的状态信息,如配置参数、机器列表等。广播变量为所有任务提供了一个共享的只读变量。
- 加速joins和聚合操作
将小表广播后,可以极大加速双边joins等操作,避免每次都需要传输这个小表。
- 减少内存压力
不使用广播变量,大对象会在每个任务中重新创建,占用大量内存。广播变量只存在一份,减轻了内存压力。
广播变量主要通过减少传输、分发只读状态、优化joins等操作来提升Spark程序的性能和降低内存消耗。
累加器(Accumulators)解决了什么问题?
- 分布式环境下的信息聚合
在分布式计算环境下,需要收集各个任务的统计和聚合信息,如数据条数、处理错误等。累加器提供了一个分布式聚合这些只能增加的统计值的机制。
- 获取副作用结果
Spark RDD的计算是确定性、无副作用的。但有时需要得到诸如数据条数等副产品结果。累加器就可以实现这种需要获取副作用结果的场景。
- 跟踪任务运行情况
可以自定义累加器来跟踪任务的运行指标,如运行时间、IO读写 bytes等,用来监控任务的执行情况。
- 实现类似MapReduce的Counter
累加器在概念上类似MapReduce中的Counter,提供了类似的聚合统计功能。
- 优化JOIN、GROUP BY等操作
累加器可以用来统计各个分区的大小、数量等信息,根据这些统计信息进行负载均衡,从而优化JOIN、GROUP BY等Shuffle操作。
累加器主要解决了在分布式环境下进行信息聚合统计的问题,可以获取任务执行过程中的一些统计指标,从而帮助监控和优化任务执行。