spark 共享变量

共享变量

一般情况下,当一个传递给Spark操作(例如map和reduce)的函数在远程节点上面运行时,Spark操作实际上操作的是这个函数所用变量的一个独立副本。这些变量被复制到每台机器上,并且这些变量在远程机器上 的所有更新都不会传递回驱动程序。通常跨任务的读写变量是低效的,但是,Spark还是为两种常见的使用模式提供了两种有限的共享变量:广播变量(broadcast variable)和累加器(accumulator)

广播变量

广播变量允许程序员缓存一个只读的变量在每台机器上面,而不是每个任务保存一份拷贝。例如,利用广播变量,我们能够以一种更有效率的方式将一个大数据量输入集合的副本分配给每个节点。(Broadcast variables allow the programmer to keep a read-only variable cached on each machine rather than shipping a copy of it with tasks.They can be used, for example, to give every node a copy of a large input dataset in an efficient manner.)Spark也尝试着利用有效的广播算法去分配广播变量,以减少通信的成本。

一个广播变量可以通过调用 SparkContext.broadcast(v) 方法从一个初始变量v中创建。广播变量是v的一个包装变量,它的值可以通过 value 方法访问,下面的代码说明了这个过程:

scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
broadcastVar: spark.Broadcast[Array[Int]] = spark.Broadcast(b5c40191-a864-4c7d-b9bf-d87e1a4e787c)
scala> broadcastVar.value
res0: Array[Int] = Array(1, 2, 3)

广播变量创建以后,我们就能够在集群的任何函数中使用它来代替变量v,这样我们就不需要再次传递变量v到每个节点上。 另外,为了保证所有的节点得到广播变量具有相同的值,对象v不能在广播之后被修改。

累加器

顾名思义,累加器是一种只能通过关联操作进行“加”操作的变量,因此它能够高效的应用于并行操作中。它们能够用来实现 counters 和 sums 。Spark原生支持数值类型的累加器,开发者可以自己添加支持的类型。 如果创建了一个具名的累加 器,它可以在spark的UI中显示。这对于理解运行阶段(running stages)的过程有很重要的作用。(注意:这在python中还不被支持)

一个累加器可以通过调用 SparkContext.accumulator(v) 方法从一个初始变量v中创建。运行在集群上的任务可以通过 add 方法或者使用 += 操作来给它加值。然而,它们无法读取这个值。只有驱动程序可以使用 value 方法来读取累加器的值。 如下的代码,展示了如何利用累加器将一个数组里面的所有元素相加:

scala> val accum = sc.accumulator(0, "My Accumulator")
accum: spark.Accumulator[Int] = 0
scala> sc.parallelize(Array(1, 2, 3, 4)).foreach(x => accum += x)
...
10/09/29 18:41:08 INFO SparkContext: Tasks finished in 0.317106 s
scala> accum.value
res2: Int = 10

这个例子利用了内置的整数类型累加器。开发者可以利用子类AccumulatorParam创建自己的 累加器类型。 AccumulatorParam接口有两个方法: zero 方法为你的数据类型提供一个“0 值”(zero value); addInPlace 方法计算两个值的和。例如,假设我们有一个 Vector 类代表数学上的向量,我们能够 如下定义累加器:

class VectorAccumulatorV2 extends AccumulatorV2[MyVector, MyVector] {

  private val myVector: MyVector = MyVector.createZeroVector

  def reset(): Unit = {
    myVector.reset()
  }

  def add(v: MyVector): Unit = {
    myVector.add(v)
  }
  ...
}

// Then, create an Accumulator of this type:
val myVectorAcc = new VectorAccumulatorV2
// Then, register it into spark context:
sc.register(myVectorAcc, "MyVectorAcc1")

在scala中,Spark支持用更一般的Accumulable接口来累积数据-结果类型和用于累加的元素类型 不一样(例如通过收集的元素建立一个列表)。Spark也支持用 SparkContext.accumulableCollection 方法累加一般的scala集合类型。

转载于:https://my.oschina.net/OttoWu/blog/855575

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark共享变量主要有两种类型:累加器和广播变量。累加器用于对信息进行聚合,而广播变量则用于高效分发较大对象。 累加器是一种只能被“加”的变量,可以在分布式计算中进行并行操作,最终得到一个全局的结果。累加器通常用于计数器、求和等场景,可以在不同的节点上进行并行计算,最终将结果汇总。例如,可以使用累加器来统计某个单词在整个数据集中出现的次数。 广播变量则是一种将较大的只读数据分发到所有节点上的机制,可以在分布式计算中减少网络传输和内存消耗。广播变量通常用于将一些只读数据(如配置信息、字典等)在所有节点上缓存一份,以便在任务执行时快速访问。例如,可以使用广播变量将一个大型的机器学习模型分发到所有节点上,以便在任务执行时快速加载。 下面是两个Spark共享变量的例子: 1.使用累加器统计单词出现次数 ```python from pyspark import SparkContext, SparkConf conf = SparkConf().setAppName("wordCount").setMaster("local") sc = SparkContext(conf=conf) # 创建一个累加器 wordCount = sc.accumulator(0) def countWords(line): global wordCount words = line.split() for word in words: wordCount += 1 # 读取文件并进行单词计数 lines = sc.textFile("file.txt") lines.foreach(countWords) # 输出单词总数 print("Total words: ", wordCount.value) ``` 2.使用广播变量缓存机器学习模型 ```python from pyspark import SparkContext, SparkConf conf = SparkConf().setAppName("machineLearning").setMaster("local") sc = SparkContext(conf=conf) # 创建一个广播变量 model = sc.broadcast(loadModel()) def predict(data): # 使用广播变量中的模型进行预测 result = model.value.predict(data) return result # 读取数据并进行预测 data = sc.textFile("data.txt") result = data.map(predict) # 输出预测结果 print(result.collect()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值