使用累加器配合广播变量做码表动态更新

广播变量简单介绍

广播变量是允许程序员缓存一个只读的变量在每个节点上,而不是每个任务保存一份拷贝。例如,利用广播变量,我们能够将配置、较小数据量的码表分发到每个节点上,以减少通信的成本。
一个广播变量可以通过调用SparkContext.broadcast(v)方法从一个初始变量v中创建。广播变量是v的一个包装变量,它的值可以通过value方法访问,下面的代码说明了这个过程:

scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int]] = Broadcast(0)

scala> broadcastVar.value
res0: Array[Int] = Array(1, 2, 3)

从上文我们可以看出广播变量的声明很简单,调用broadcast就能搞定,并且scala中一切可序列化的对象都是可以进行广播的,这就给了我们很大的想象空间,可以利用广播变量将一些经常访问的大变量进行广播,而不是每个任务保存一份,这样可以减少资源上的浪费。

更新广播变量(rebroadcast)

广播变量可以用来更新一些大的配置变量,比如数据库中的一张表格,那么有这样一个问题,如果数据库当中的配置表格进行了更新,我们需要重新广播变量该怎么做呢。上文对广播变量的说明中,我们知道广播变量是只读的,也就是说广播出去的变量没法再修改,那么我们应该怎么解决这个问题呢?
答案是利用spark中的unpersist函数
Spark automatically monitors cache usage on each node and drops out old data partitions in a least-recently-used (LRU) fashion. If you would like to manually remove an RDD instead of waiting for it to fall out of the cache, use the RDD.unpersist() method.
上文是从spark官方文档摘抄出来的,我们可以看出,正常来说每个节点的数据是不需要我们操心的,spark会自动按照LRU规则将老数据删除,如果需要手动删除可以调用unpersist函数。
那么更新广播变量的基本思路:将老的广播变量删除(unpersist),然后重新广播一遍新的广播变量,为此简单包装了一个用于广播和更新广播变量的wraper类,如下:

PS:我们这里结合spark里累加器及spark自动监控hdfs目录功能来触发执行广播变量更新,使用方法见下边的示例:
不明白累加器的同学自行借助各类搜索查阅资料。

广播变量更新的wraper类

package cn.com.bonc.tools

import java.io.{ ObjectInputStream, ObjectOutputStream }
import org.apache.spark.broadcast.Broadcast
import org.apache.spark.streaming.StreamingContext
import scala.reflect.ClassTag

// This wrapper lets us update brodcast variables within DStreams' foreachRDD
// without running into serialization issues
case class BroadcastWrapper[T: ClassTag](
    @transient private val ssc: StreamingContext,
    @transient private val _v: T) {
   

  @transient private var v = ssc.sparkContext.broadcast(_v)

  def update(newV
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
广播变量累加器是 PySpark 中常用的两种分布式计算工具。 广播变量(Broadcast Variables)是用于在集群中的所有节点之间共享大型只读数据集的机制。它们可以提高任务执行的效率,因为它们只需要在网络上传输一次,而不是每个任务都传输一次。广播变量通常用于将大型查找表或机器学习模型有效地广播到集群的每个节点上。 下面是一个使用广播变量的示例: ```python from pyspark import SparkContext # 创建 SparkContext 对象 sc = SparkContext("local", "Broadcast Example") # 创建要广播的数据集 data = [1, 2, 3, 4, 5] broadcast_data = sc.broadcast(data) # 在集群中的每个节点上使用广播变量 result = sc.parallelize([1, 2, 3, 4, 5]).map(lambda x: x * broadcast_data.value[0]).collect() print(result) # 输出 [1, 2, 3, 4, 5] ``` 累加器(Accumulators)是用于在分布式计算中进行累加操作的变量。它们通常用于在集群的所有节点上对计数器或求和器进行更新累加器只支持“加”操作,并且在单个任务中对累加器进行更新不会影响其他任务。 下面是一个使用累加器的示例: ```python from pyspark import SparkContext # 创建 SparkContext 对象 sc = SparkContext("local", "Accumulator Example") # 创建累加器 accumulator = sc.accumulator(0) # 在集群中的每个节点上更新累加器 sc.parallelize([1, 2, 3, 4, 5]).foreach(lambda x: accumulator.add(x)) print(accumulator.value) # 输出 15 ``` 在这个示例中,我们创建了一个累加器,并在集群中的每个节点上通过 `foreach` 操作对累加器进行更新。最后,我们打印出累加器的值,得到结果为 15。 这就是广播变量累加器在 PySpark 中的应用方式。希望对你有所帮助!如果还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值