Shared Variables

Normally, when a function passed to a Spark operation (such as map or reduce) is executed on a remote cluster node, it works on separate copies of all the variables used in the function. These variables are copied to each machine, and no updates to the variables on the remote machine are propagated back to the driver program. Supporting general, read-write shared variables across tasks would be inefficient. However, Spark does provide two limited types of shared variables for two common usage patterns: broadcast variables and accumulators.

Broadcast Variables

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 also attempts to distribute broadcast variables using efficient broadcast algorithms to reduce communication cost.

Spark actions are executed through a set of stages, separated by distributed “shuffle” operations. Spark automatically broadcasts the common data needed by tasks within each stage. The data broadcasted this way is cached in serialized form and deserialized before running each task. This means that explicitly creating broadcast variables is only useful when tasks across multiple stages need the same data or when caching the data in deserialized form is important.

Broadcast variables are created from a variable v by calling SparkContext.broadcast(v). The broadcast variable is a wrapper around v, and its value can be accessed by calling the value method.

共享变量

通常,当在远程集群节点上执行传递给Spark操作(例如mapor reduce)的函数时,它将在函数中使用的所有变量的单独副本上工作。这些变量将复制到每台计算机,并且远程计算机上的变量更新不会传播回驱动程序。支持跨任务的通用,读写共享变量效率低下。但是,Spark确实为两种常见的使用模式提供了两种有限类型的共享变量:广播变量和累加器。

广播变量

广播变量允许程序员在每台机器上保留一个只读变量,而不是随副本一起发送它的副本。例如,它们可用于以有效的方式为每个节点提供大输入数据集的副本。Spark还尝试使用有效的广播算法来分发广播变量,以降低通信成本。

Spark动作通过一组阶段执行,由分布式“shuffle”操作分隔。Spark自动广播每个阶段中任务所需的公共数据。以这种方式广播的数据以序列化形式缓存并在运行每个任务之前反序列化。这意味着显式创建广播变量仅在跨多个阶段的任务需要相同数据或以反序列化形式缓存数据很重要时才有用。

广播变量是v通过调用从变量创建的SparkContext.broadcast(v)。广播变量是一个包装器v,可以通过调用该value 方法来访问它的值。

java 版本:

package cn.rzlee.spark;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.broadcast.Broadcast; import java.util.Arrays;
import java.util.List; /**
* @Author ^_^
* @Create 2018/11/3
*/
public class BroadcastVariable { public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("Persist").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf); // 在Java中,创建共享变量,就是调用SparkContext的broadcast()方法
// 获取的返回结果是Broadcast<T>类型
final int factor =3;
final Broadcast<Integer> factorBroadcast = sc.broadcast(factor); List<Integer> numberList = Arrays.asList(1,2,3,4,5,6,7,8,9);
JavaRDD<Integer> numbers = sc.parallelize(numberList); // 让集合中的每个数字都乘以外部定义的那个 factor
JavaRDD<Integer> multipleNumbers = numbers.map(new Function<Integer, Integer>() {
@Override
public Integer call(Integer v1) throws Exception { // 使用共享变量时,调用其value()方法,即可获取其内部封装的值
Integer factor = factorBroadcast.value();
return v1 * factor;
}
}); multipleNumbers.foreach(new VoidFunction<Integer>() {
@Override
public void call(Integer integer) throws Exception {
System.out.println(integer);
}
}); sc.close();
} }

scala 版本:

package cn.rzlee.spark.scala

import org.apache.spark.broadcast.Broadcast
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext} object BroadcastVariable {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName(this.getClass.getSimpleName)
val sc = new SparkContext(conf) val factor = 3
val factorBroadcast: Broadcast[Int] = sc.broadcast(factor) val numbersArray = Array(1,2,3,4,5,6,7,8,9)
val numbers: RDD[Int] = sc.parallelize(numbersArray, 1)
val mutipleNumbers: RDD[Int] = numbers.map(num =>num * factorBroadcast.value) mutipleNumbers.foreach(num=>println(num))
sc.stop()
}
}

累加器

累加器是仅通过关联操作“添加”的变量,因此可以并行有效地支持。它们可用于实现计数器(如MapReduce)或总和。Spark本身支持数值类型的累加器,程序员可以添加对新类型的支持。如果使用名称创建累加器,它们将显示在Spark的UI中。这对于理解运行阶段的进度非常有用(注意:Python中尚不支持此功能)。

v通过调用从初始值创建累加器SparkContext.accumulator(v)。然后,在集群上运行的任务可以使用add方法或+=运算符(在Scala和Python中)添加到它。但是,他们无法读懂它的价值。只有驱动程序可以使用其value方法读取累加器的值。

下面的代码显示了一个累加器用于添加数组的元素:

java 版本:

package cn.rzlee.spark.core;

import org.apache.spark.Accumulator;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.VoidFunction; import java.util.Arrays;
import java.util.List; /**
* @Author ^_^
* @Create 2018/11/3
*/
public class AccumulatorVariable {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("AccumulatorVariable").setMaster("local");
JavaSparkContext sc = new JavaSparkContext(conf); // 创建Accumulator变量
// 需要调用SparkContext的accumulator()方法
Accumulator<Integer> sum = sc.accumulator(0); List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 9, 8);
JavaRDD<Integer> numbers = sc.parallelize(numbersList); numbers.foreach(new VoidFunction<Integer>() {
@Override
public void call(Integer integer) throws Exception {
// 然后在函数内部,就可以对Accumulator变量,调用add()方法,累加值
sum.add(integer);
}
});
// 在driver程序中,可以调用accumulator的value()方法,获取其值
System.out.println(sum.value()); }
}

scala 版本:

package cn.rzlee.spark.scala

import org.apache.spark.{Accumulable, Accumulator, SparkConf, SparkContext}

object AccumulatorValiable {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local")
val sc = new SparkContext(conf) val sum: Accumulator[Int] = sc.accumulator(0)
val numbersArray = Array(1,2,3,4,5,6,7,8,9) val numbers = sc.parallelize(numbersArray,1)
numbers.foreach(number=>sum+=number)
println(sum.value)
}
}

Spark- 共享变量的更多相关文章

  1. spark共享变量

    boradcast例子代码: scala版本 spark共享变量之Accumulator 例子代码: scala版本

  2. 7.spark共享变量

    spark共享变量 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark弹性分布式数据集 ...

  3. Spark——共享变量

    Spark执行不少操作时都依赖于闭包函数的调用,此时如果闭包函数使用到了外部变量驱动程序在使用行动操作时传递到集群中各worker节点任务时就会进行一系列操作: 1.驱动程序使将闭包中使用变量封装成对 ...

  4. Spark共享变量(广播变量、累加器)

    转载自:https://blog.csdn.net/Android_xue/article/details/79780463 Spark两种共享变量:广播变量(broadcast variable)与 ...

  5. SPARK共享变量:广播变量和累加器

    Shared Variables Spark does provide two limited types of shared variables for two common usage patte ...

  6. Spark分布式编程之全局变量专题【共享变量】

    转载自:http://www.aboutyun.com/thread-19652-1-1.html 问题导读 1.spark共享变量的作用是什么?2.什么情况下使用共享变量?3.如何在程序中使用共享变 ...

  7. 9.Spark Streaming

    Spark Streaming 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark弹性 ...

  8. 8.Spark SQL

    Spark SQL 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark弹性分布式数据集 ...

  9. 5.spark弹性分布式数据集

    弹性分布式数据集 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark弹性分布式数据集 ...

  10. 4.Apache Spark的工作原理

    Apache Spark的工作原理 1 Why Apache Spark 2 关于Apache Spark 3 如何安装Apache Spark 4 Apache Spark的工作原理 5 spark ...

随机推荐

  1. redis 集群安装 3主3从3台云主机

    穷呀!! 3台云主机来搭建个集群! 配置低的伤心! 1u2G ! 不说了,干吧! 可以看出 OK了. 准备工作 :

  2. Python 通过字符串调用函数、接近属性

    需求:传入的是函数名.属性名,想通过字符串调用函数,接近属性. 通过字符串接近.变动属性 变量:model_name, field_name # 获取 model model = AppConfig. ...

  3. python系列十四:Python3 文件

    #!/usr/bin/python #Python3 文件 from urllib import requestimport pprint,pickle'''读和写文件open() 将会返回一个 fi ...

  4. GDI+绘制图形和画刷填充图形

    GDI+可以再Windows窗体应用程序中以编程方式绘制图形等. 可以在VS里新建项目-Windows窗体应用程序-建一个窗体.首先引入命名空间using System.Drawing.Imaging ...

  5. Python3.6全栈开发实例[015]

    15.电影投票:程序先给出几个目前正在上映的电影列表. 由用户给每个电影投票.最终将该用户投票信息公布出来 lst = ['北京遇上西雅图', '解救吴先生', '美国往事', '西西里的美丽传说'] ...

  6. shutil 模块 高级的文件、文件夹、压缩包 处理模块

    高级的文件.文件夹.压缩包 处理模块 # 将文件内容拷贝到另一个文件中 shutil.copyfileobj(fsrc, fdst[, length]) import shutil shutil.co ...

  7. (4.7)怎么捕获和记录SQL Server中发生的死锁?

    转自:https://blog.csdn.net/c_enhui/article/details/19498327 怎么捕获和记录SQL Server中发生的死锁? 关键词:死锁记录,死锁捕获 sql ...

  8. 《Python机器学习》笔记(五)

    通过降维压缩数据 在前面已经介绍了几种不同的特征选择技术对数据集进行降维的方法.另一种常用于降维的特征选择方法就是特征抽取.数据压缩也是机器学习领域中的一个重要内容.数据压缩技术可以帮助我们对数据及逆 ...

  9. 爬虫四 selenium模块

    一.介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作, ...

  10. asp.net(c#)中String.Empty、NULL、"" 三者到底有啥区别和联系?

    开门见山,首先看下面代码,你认为结果分别是什么? string str = string.Empty; string str1 = ""; string str2 = null; ...