Spark随谈

本文深入探讨了Spark的架构、依赖、安装与开发指南,详细介绍了Spark的核心概念弹性分布式数据集(RDD)及其操作,共享变量(广播变量、累加器),分布式数据集的创建与操作,以及Spark在集群部署中的应用。旨在为开发者提供全面的Spark入门与实践指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark随谈(一)---总体架构

Spark是一个小巧玲珑的项目,由Berkeley大学的Matei为主的小团队所开发。使用的语言是Scala,项目的core部分的代码只有63个Scala文件,充分体现了精简之美。

系列文章见: Spark随谈 http://www.linuxidc.com/Linux/2013-08/88592.htm

Spark之依赖

(1)Map Reduce模型
作为一个分布式计算框架,Spark采用了MapReduce模型。在它身上,Google的Map Reduce和Hadoop的痕迹很重,很明显,它并非一个大的创新,而是微创新。在基础理念不变的前提下,它借鉴,模仿并依赖了先辈,加入了一点改进,极大的提升了MapReduce的效率。

使用MapReduce模型解决大数据并行计算的问题,带来的最大优势,是它和Hadoop的同属一家人。因为同属于MapReduce并行编程模型,而不是MPI和OpenMP其它模型,因此,复杂的算法,只要能够以Java算法表达,在Hadoop上运行的,就能以Scala算法表达,在Spark上运行,而速度有倍数的提升。相比之下,在MPI和Hadoop算法之间切换,难度就大多了。

(2)函数式编程
Spark由Scala写就,而支持的语言亦是Scala。其原因之一就是Scala支持函数式编程。这一来造就了Spark的代码简洁,二来使得基于Spark开发的程序,也特别的简洁。一次完整的MapReduce,Hadoop中需要创建一个Mapper类和Reduce类,而Spark只需要创建相应的一个map函数和reduce函数即可,代码量大大降低

(3)Mesos
Spark将分布式运行的需要考虑的事情,都交给了Mesos,自己不Care,这也是它代码能够精简的原因之一。这也算是偷了一个大懒吧,呵呵

(4)HDFS和S3

Spark支持2种分布式存储系统:HDFS和S3。应该算是目前最主流的两种了。对文件系统的读取和写入功能是Spark自己提供的,借助Mesos分布式实现。如果自己想做集群试验,又没有HDFS环境,也没有EC2环境的话,可以搞个NFS,确保所有MESOS的Slave都可以访问,也可以模拟一下。

Spark的术语

(1)RDD(Resilient distributed datasets )

弹性分布式数据集,Spark中最核心的模块和类,也是设计精华所在。你将它理解为一个大的集合,将所有数据都加载到内存中,方便进行多次重用。第一,它是分布式的,可以分布在多台机器上,进行计算。第二,它是弹性的,在计算处理过程中,机器的内存不够时,它会和硬盘进行数据交换,某种程度上会减低性能,但是可以确保计算得以继续进行。关于RDD的详细阐述,后面会单独再起一篇文章。


(2)Local模式和Mesos模式
Spark支持Local调用和Mesos集群两种模式,在Spark上开发算法程序,可以在本地模式调试成功后,直接改用Mesos集群运行,除了文件的保存位置需要考虑以外,算法理论上不需要做任何修改。

Spark的本地模式支持多线程,有一定的单机并发处理能力。但是不算很强劲。本地模式可以保存结果在本地或者分布式文件系统,而Mesos模式一定需要保存在分布式或者共享文件系统。

(3)Transformations和Actions

对于RDD,有两种类型的动作,一种是Transformation,一种是Action。它们本质区别是:

  • Transformation返回值还是一个RDD。它使用了链式调用的设计模式,对一个RDD进行计算后,变换成另外一个RDD,然后这个RDD又可以进行另外一次转换。这个过程是分布式的
  • Action返回值不是一个RDD。它要么是一个Scala的普通集合,要么是一个值,要么是空,最终或返回到Driver程序,或把RDD写入到文件系统中

关于这两个动作,在Spark开发指南中会有就进一步的详细介绍,它们是基于Spark开发的核心。这里将Spark的官方ppt中的一张图略作改造,阐明一下两种动作的区别。

Spark On Mesos

为了在Mesos框架上运行,安装Mesos的规范和设计,Spark实现两个类,一个是SparkScheduler,在Spark中类名是MesosScheduler;一个是SparkExecutor,在Spark中类名是Executor。有了这两个类,Spark就可以通过Mesos进行分布式的计算。

Spark会将RDD和MapReduce函数,进行一次转换,变成标准的Job和一系列的Task。提交给SparkScheduler,SparkScheduler会把Task提交给Mesos Master,由Master分配给不同的Slave,最终由Slave中的Spark Executor,将分配到的Task一一执行,并且返回,组成新的RDD,或者直接写入到分布式文件系统。

基于Spark的项目

基于Spark的项目有2个,也是AMP实验室出品

第一个是Spark内部的Bagel,Pregel on Spark,可以用Spark进行图计算,这是个非常有用的小项目。Bagel自带了一个例子,实现了Google的PageRank算法,实验数据在http://download.freebase.com/wex/,感兴趣的可以下载试试。

第二个是Shark,Hive On Spark,将Hive的语法迁移到Spark上,将SQL翻译为Spark的mapreduce运行,并且可以直接读取hive的元数据库和对应数据。这个项目还在获得了2012的SIGMOD大会上获得最佳Demo奖,目前已经进入Alpha版本,很快将会有正式版本发布,希望它能够是一个完全兼容现有hive,速度快10x倍的牛B产品。


Spark随谈(二)—— 安装攻略

本来安装这件事情,不用单独开一篇谈的。但是Spark的安装实在是一件点蛋疼的事情,这和Spark的语言和框架两者有颇大的关系。

Spark是Scala语言写的,所以要先安装Java和Scala,而底层的调度框架是Mesos,Mesos是C++写的,所以又对机器的glibc和gcc环境有一定的要求。装好了Mesos和Spark,还要把2者衔接起来,版本要选择正确,这几个步骤,中间任何一步错了都Spark都不能以集群方式正常运行,所以Spark的安装,还是颇有点周折的,在这里把完整的过程记录下来,包括mesos 0.9的安装过程,希望后来者尽量不需要掉坑里。

本攻略基于版本是Spark 0.5 和Mesos 0.9,服务器是RedHat Enterprise 6.1 32位,其它服务器的命令可能会稍微有所区别

系列文章见: Spark随谈 http://www.linuxidc.com/Linux/2013-08/88592.htm

  1. 安装Spark
  2. 安装Mesos
  3. 启动Mesos
  4. 启动Spark On Mesos
  5. 集群部署

1、安装Spark

1.1 安装Java

推荐版本是JDK1.6.0 u18,具体下载安装过程就不说了,最后一定要设定JAVA_HOME,这个是后面步骤,尤其是mesos安装必须

export JAVA_HOME=/usr/java/jdk
export PATH=$JAVA_HOME/bin:$PATH
1.2 安装Scala
wget http://www.scala-lang.org/downloads/distrib/files/scala-2.9.2.tgz
tar xvf scala-2.9.2.tgz
mkdir /usr/share/scala
cp -r scala-2.9.2/* /usr/share/scala
export SCALA_HOME=/usr/share/scala
export PATH=$PATH:$SCALA_HOME/bin/
1.3 安装Spark
wget -O mesos-spark-v0.5.0-0.tar.gz https://github.com/mesos/spark/tarball/v0.5.0
tar -xzvf mesos-spark-v0.5.0-0.tar.gz
mv mesos-spark-0472cf8 spark
cd spark
sbt/sbt compile

至此,Spark的基本安装已经完毕,可以尝试用本地模式运行

./run spark.examples.SparkPi local

看到正确的Pi结果,表示Spark安装第一步完成,本地模式运行OK

2、安装Mesos

Mesos 0.9安装,必须具备下列条件:

glibc 2.9(必须2.9以上)
gcc-c++ 4.1
python 2.6
python-devel
cppunit-devel
libtool

Redhat 6上述条件基本上已经具备了,Redhat 5的话,glibc有可能低于2.5,必须升级,才能完成mesos的编译安装,否则就别折腾了,洗洗睡吧 :)

wget http://people.apache.org/~benh/mesos-0.9.0-incubating-RC3/mesos-0.9.0-incubating.tar.gz
tar zxvf mesos-0.9.0-incubating.tar.gz
cd mesos-0.9.0
mkdir build
cd build
../configure --with-python-headers=/usr/include/python2.6 --with-java-home=$JAVA_HOME --with-java-headers=$JAVA_HOME/include --with-webui --with-included-zookeeper --prefix=/usr/local/mesos
make
make install

祈祷吧,一切顺利的话,mesos就会被安装到/usr/local/mesos下,最后关键一步,设置MESOS_HOME

export MESOS_HOME=/usr/local/mesos

3、启动Mesos

手工模式启动:

3.1 启动Master

cd /usr/local/mesos
(sbin/mesos-master –log_dir=/usr/local/mesos/logs & ) &

出现下面的提示Master就成功

Starting Mesos master
Master started on ***:5050
Master ID: ***
Elected as master!
Loading webui script at ‘/usr/local/new_mesos/share/mesos/webui/master/webui.py’
Bottle server starting up (using WSGIRefServer())…
Listening on http://0.0.0.0:8080/
Use Ctrl-C to quit.

3.2 启动Slave

(sbin/mesos-slave -m 127.0.0.1:5050 –log_dir=/home/andy/mesos/logs –work_dir=/home/andy/mesos/works & ) &

使用–resources=”mem:20240;cpus:10″参数,可以根据具体的机器情况,指定分配的资源

Starting Mesos slave
Slave started on ***:42584
Slave resources: cpus=16; mem=23123
New master detected at master@***:5050
Registered with master; given slave ID ***
Loading webui script at ‘/usr/local/new_mesos/share/mesos/webui/slave/webui.py’
Bottle server starting up (using WSGIRefServer())…
Listening on http://0.0.0.0:8081/
Use Ctrl-C to quit.

4、启动Spark On Mesos

好了,终于来到最关键的一步了,在Mesos上运行Spark,要把Spark和Mesos连接到一起了。Spark是披着Scala外衣的Java,Mesos是C++,他们的通道,不可避免的就是JNI

配置的关键是Spark的配置文件,Spark带了样例文件conf/spark-env.sh.template,并有详细的解释,根据我们之前的安装路径,参考该文件,配置如下:

#保持与系统的MESOS_HOME一致
export MESOS_HOME=/usr/local/mesos/

#新版本的配置项,直接指定libmesso.so的位置,该so和spark目录下的mesos-0.9.0.jar必须一致,是spark和mesos沟通的关键
export MESOS_NATIVE_LIBRARY=/usr/local/mesos/lib/libmesos.so

#旧版本的配置项,其它的so,目前看来不需要了
export SPARK_LIBRARY_PATH=/usr/local/mesos/lib

#自定义的程序jar包,可以放在该目录下
export SPARK_CLASSPATH=...

#保持与系统的SCALA_HOME一致
export SCALA_HOME=/usr/share/scala

#必须小于或者等于Slave中的mem,Slave resources: cpus=16; mem=23123
#本地模式下,运行大任务也需要修改该参数,默认是512m,很小
export SPARK_MEM=10g

好了,一切就绪之后,尝试运行下面的命令:

cd spark
./run spark.examples.SparkPi 127.0.0.1:5050
(注意,和以前的mesos版本不一样,不需要打master@127.0.0.1:5050,否则mesos会报错的)

如果你再次成功的看到Pi值,恭喜,Spark的安装又成功了一步。


Spark随谈——开发指南(译)

本文翻译自官方博客,略有添加:https://github.com/mesos/spark/wiki/Spark-Programming-Guide,谢谢师允tx的校正。希望能够给希望尝试Spark的朋友,带来一些帮助。目前的版本是0.5.0

系列文章见: Spark随谈 http://www.linuxidc.com/Linux/2013-08/88592.htm

Spark开发指南 

从高的层面来看,其实每一个Spark的应用,都是一个Driver类,通过运行用户定义的main函数,在集群上执行各种并发操作和计算

Spark提供的最主要的抽象,是一个弹性分布式数据集(RDD),它是一种特殊集合,可以分布在集群的节点上,以函数式编程操作集合的方式,进行各种各样的并发操作。它可以由hdfs上的一个文件创建而来,或者是Driver程序中,从一个已经存在的集合转换而来。用户可以将数据集缓存在内存中,让它被有效的重用,进行并发操作。最后,分布式数据集可以自动的从结点失败中恢复,再次进行计算。

Spark的第二个抽象,是并行计算中使用的共享变量。默认来说,当Spark并发运行一个函数时,它是以多个的task,在不同的结点上运行,它传递每一个变量的一个拷贝,到每一个独立task使用到的函数中,因此这些变量并非共享的。然而有时候,我们需要在任务中能够被共享的变量,或者在任务与驱动程序之间共享。Spark支持两种类型的共享变量:

广播变量: 可以在内存的所有结点中被访问,用于缓存变量(只读)

累加器: 只能用来做加法的变量,例如计数和求和

本指南通过一些样例展示这些特征。读者最好是熟悉Scala,尤其是闭包的语法。请留意,Spark可以通过Spark-Shell的解释器进行交互式运行。你可能会需要它。

接入Spark

为了写一个Spark的应用,你需要将Spark和它的依赖,加入到CLASSPATH中。最简单的方法,就是运行sbt/sbt assembly来编译Spark和它的依赖,打到一个Jar里面core/target/scala_2.9.1/spark-core-assembly-0.0.0.jar,然后将它加入到你的CLASSPATH中。或者你可以选择将spark发布到maven的本地缓存中,使用sbt/sbt publish。它将在组织org.spark-project下成为一个spark-core.

另外,你会需要导入一些Spark的类和隐式转换, 将下面几行加入到你程序的顶部

import spark.SparkContext

import SparkContext._

初始化Spark

写Spark程序需要做的第一件事情,就是创建一个SparkContext对象,它将告诉Spark如何访问一个集群。这个通常是通过下面的构造器来实现的:

new SparkContext(master, jobName, [sparkHome], [jars])

Master参数是一个字符串,指定了连接的Mesos集群,或者用特殊的字符串“local”来指明用local模式运行。如下面的描述一般,JobName是你任务的名称,当在集群上运行的时候,将会在Mesos的Web UI监控界面显示。后面的两个参数,是用在将你的代码,部署到mesos集群上运行时使用的,后面会提到。

在Spark的解释器中,一个特殊的SparkContext变量已经为你创建,变量名字叫sc。创建你自己的SparkContext是不会生效的。你可以通过设置MASTER环境变量,来让master连接到需要的上下文。

MASTER=local; ./spark-shell

Master的命名

Master的名字可以是以下3个格式中的一种

Master Name

Meaning

local

本地化运行Spark,使用一个Worker线程(没有并行)

 

local[K]

本地化运行Spark,使用K个Worker线程(根据机器的CPU核数设定)

 

HOST:PORT

将Spark连接到指定的Mesos Master,在集群上运行。Host参数是Mesos Master的Hostname, 端口是master配置的端口,默认为5050.

注意:在早期的Mesos版本(spark的old-mesos分支),你必须使用master@HOST:PORT.

集群部署
如果你想你的任务运行在一个集群上,你需要指定2个可选参数:
  • SparkHome:Spark在集群机器上的安装路径(必须全部一致)
  • Jars:在本地机器上,包含了你任务的代码和依赖的Jars文件列表。 Spark会把它们部署到所有的集群结点上。 你需要使用自己的编译系统将你的作业,打包成一套jars文件。例如,如果你使用sbt,那么sbt-assembly插件是一个好方法,将你的代码和依赖,变成一个单一的jar文件。

如果有一些类库是公用的,需要在不同的作业间共享,你可能需要手工拷贝到mesos的结点上,在conf/spark-env中,通过设置SPARK_CLASSPATH环境变量指向它们。详细信息可以参考配置

分布式数据集

Spark围绕的核心概念,是弹性分布式数据集(RDD),一个有容错机制,可以被并行操作的集合。目前有两种类型的RDD: 并行集合(Parrallelized Collections),接收一个已经存在的Scala集合,在它上面运行各种并发计算; Hadoop数据集(Hadoop DataSets),在一个文件的每条记录上,运行各种函数。只要文件系统是Hdfs,或者hadoop支持的任意存储系统。这两种RDD都可以通过相同的方式进行操作。

并行集合

并行集合是通过调用SparkContext的parallelize方法,在一个已经存在的Scala集合(只要是seq对象就可以)上创建而来。集合的对象将会被拷贝来创建一个分布式数据集,可以被并行操作。下面通过spark解释器的例子,展示如何从一个数组创建一个并发集合

scala> val data = Array(1, 2, 3, 4, 5)

data: Array[Int] = Array(1, 2, 3, 4, 5)

scala> val distData = sc.parallelize(data)

distData: spark.RDD[Int] = spark.ParallelCollection@10d13e3e

一旦被创建,分布数据集(distData)可以被并行操作。例如,我们可以调用distData.reduce(_ +_) 来将数组的元素相加。我们会在后续的分布式数据集做进一步描述。

创建并行集合的一个重要参数,是slices的数目,它指定了将数据集切分为几份。在集群模式中,Spark将会在一份slice上起一个Task。典型的,你可以在集群中的每个cpu上,起2-4个Slice (也就是每个cpu分配2-4个Task)。一般来说,Spark会尝试根据集群的状况,来自动设定slices的数目。然而,你也可以手动的设置它,通过parallelize方法的第二个参数(例如:sc.parallelize(data, 10)).

Hadoop数据集

Spark可以创建分布式数据集,从任何存储在HDFS文件系统或者Hadoop支持的其它文件系统(包括本地文件,Amazon S3, Hypertable, HBase等等)上的文件。 Spark可以支持Text File, SequenceFiles 及其它任何Hadoop输入格式

文本文件的RDDs可以通过SparkContext的textFile方法创建,该方法接受文件的URI地址(或者机器上的文件本地路径,或者一个hdfs://, sdn://,kfs://,其它URI).这里是一个调用例子:

scala> val distFile = sc.textFile(“data.txt”)

distFile: spark.RDD[String] = spark.HadoopRDD@1d4cee08

一旦被创建,distFile可以进行数据集操作。例如,我们可以使用如下的map和reduce操作将所有行数的长度相加:

distFile.map(_.size).reduce(_ + _ )

方法也接受可选的第二参数,来控制文件的分片数目。默认来说,Spark为每一块文件创建一个分片(HDFS默认的块大小为64MB),但是你可以通过传入一个更大的值来指定更多的分片。注意,你不能指定一个比块个数更少的片值(和hadoop中,Map数不能小于Block数一样)

对于SequenceFiles,使用SparkContext的sequenceFile[K, V]方法,K和V是文件中的key和values类型。他们必须是Hadoop的Writable的子类,例如IntWritable和Text。另外,Spark允许你指定几种原生的通用Writable类型,例如:sequencFile[Int, String]会自动读取IntWritable和Texts

最后,对于其他类型的Hadoop输入格式,你可以使用SparkContext.hadoopRDD方法,它可以接收任意类型的JobConf和输入格式类,键类型和值类型。按照对Hadoop作业一样的方法,来设置输入源就可以了。

分布式数据集操作

分布式数据集支持两种操作:

转换(transformation):根据现有的数据集创建一个新的数据集

动作(actions):在数据集上运行计算后,返回一个值给驱动程序

例如,Map是一个转换,将数据集的每一个元素,都经过一个函数进行计算后,返回一个新的分布式数据集作为结果。而另一方面,Reduce是一个动作,将数据集的所有元素,用某个函数进行聚合,然后将最终结果返回驱动程序,而并行的reduceByKey还是返回一个分布式数据集

所有Spark中的转换都是惰性的,也就是说,并不会马上发生计算。相反的,它只是记住应用到基础数据集上的这些转换(Transformation)。而这些转换(Transformation),只会在有一个动作(Action)发生,要求返回结果给驱动应用时,才真正进行计算。这个设计让Spark更加有效率的运行。例如,我们可以实现,通过map创建一个数据集,然后再用reduce,而只返回reduce的结果给driver,而不是整个大的数据集。

spark提供的一个重要转换操作是Caching。当你cache一个分布式数据集时,每个节点会存储该数据集的所有片,并在内存中计算,并在其它操作中重用。这将会使得后续的计算更加的快速(通常是10倍),缓存是spark中一个构造迭代算法的关键工具,也可以在解释器中交互使用。

下面的表格列出目前支持的转换和动作:

转换(Transformations)

Transformation

Meaning

map(func)

 

返回一个新的分布式数据集,由每个原元素经过func函数转换后组成

filter(func)

 

返回一个新的数据集,由经过func函数后返回值为true的原元素组成

flatMap(func)

类似于map,但是每一个输入元素,会被映射为0到多个输出元素(因此,func函数的返回值是一个Seq,而不是单一元素)

sample(withReplacement, frac, seed)

 

根据给定的随机种子seed,随机抽样出数量为frac的数据

union(otherDataset)

 

返回一个新的数据集,由原数据集和参数联合而成

groupByKey([numTasks])

 

在一个由(K,V)对组成的数据集上调用,返回一个(K,Seq[V])对的数据集。注意:默认情况下,使用8个并行任务进行分组,你可以传入numTask可选参数,根据数据量设置不同数目的Task

(groupByKey和filter结合,可以实现类似Hadoop中的Reduce功能)

reduceByKey(func, [numTasks])

在一个(K,V)对的数据集上使用,返回一个(K,V)对的数据集,key相同的值,都被使用指定的reduce函数聚合到一起。和groupbykey类似,任务的个数是可以通过第二个可选参数来配置的。

join(otherDataset, [numTasks])

在类型为(K,V)和(K,W)类型的数据集上调用,返回一个(K,(V,W))对,每个key中的所有元素都在一起的数据集

groupWith(otherDataset, [numTasks])

在类型为(K,V)和(K,W)类型的数据集上调用,返回一个数据集,组成元素为(K, Seq[V], Seq[W]) Tuples。这个操作在其它框架,称为CoGroup

cartesian(otherDataset)

笛卡尔积。但在数据集T和U上调用时,返回一个(T,U)对的数据集,所有元素交互进行笛卡尔积。

sortByKey([ascendingOrder])

在类型为( K, V )的数据集上调用,返回以K为键进行排序的(K,V)对数据集。升序或者降序由boolean型的ascendingOrder参数决定

(类似于Hadoop的Map-Reduce中间阶段的Sort,按Key进行排序)

Actions(动作)

Action

Meaning

reduce(func)

通过函数func聚集数据集中的所有元素。Func函数接受2个参数,返回一个值。这个函数必须是关联性的,确保可以被正确的并发执行

collect()

在Driver的程序中,以数组的形式,返回数据集的所有元素。这通常会在使用filter或者其它操作后,返回一个足够小的数据子集再使用,直接将整个RDD集Collect返回,很可能会让Driver程序OOM

count()

返回数据集的元素个数

take(n)

返回一个数组,由数据集的前n个元素组成。注意,这个操作目前并非在多个节点上,并行执行,而是Driver程序所在机器,单机计算所有的元素

(Gateway的内存压力会增大,需要谨慎使用)

first()

返回数据集的第一个元素(类似于take(1))

saveAsTextFile(path)

将数据集的元素,以textfile的形式,保存到本地文件系统,hdfs或者任何其它hadoop支持的文件系统。Spark将会调用每个元素的toString方法,并将它转换为文件中的一行文本

saveAsSequenceFile(path)

将数据集的元素,以sequencefile的格式,保存到指定的目录下,本地系统,hdfs或者任何其它hadoop支持的文件系统。RDD的元素必须由key-value对组成,并都实现了Hadoop的Writable接口,或隐式可以转换为Writable(Spark包括了基本类型的转换,例如Int,Double,String等等)

foreach(func)

在数据集的每一个元素上,运行函数func。这通常用于更新一个累加器变量,或者和外部存储系统做交互

缓存

调用RDD的cache()方法,可以让它在第一次计算后,将结果保持存储在内存。数据集的不同部分,将会被存储在计算它的不同的集群节点上,让后续的数据集使用更快。缓存是有容错功能的,如果任一分区的RDD数据丢失了,它会被使用原来创建它的转换,再计算一次(不需要全部重新计算,只计算丢失的分区)

Shared Variables

共享变量

一般来说,当一个函数被传递给Spark操作(例如map和reduce),通常是在集群结点上运行,在函数中使用到的所有变量,都做分别拷贝,供函数操作,而不会互相影响。这些变量会被拷贝到每一台机器,而在远程机器上,在对变量的所有更新,都不会被传播回Driver程序。然而,Spark提供两种有限的共享变量,供两种公用的使用模式:���播变量和累加器

广播变量

广播变量允许程序员保留一个只读的变量,缓存在每一台机器上,而非每个任务保存一份拷贝。他们可以使用,例如,给每个结点一个大的输入数据集,以一种高效的方式。Spark也会尝试,使用一种高效的广播算法,来减少沟通的损耗。

广播变量是从变量V创建的,通过调用SparkContext.broadcast(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不能在被广播后修改,是只读的,从而保证所有结点的变量,收到的都是一模一样的。

累加器

累加器是只能通过组合操作“加”起来的变量,可以高效的被并行支持。他们可以用来实现计数器(如同MapReduce中)和求和。Spark原生就支持Int和Double类型的计数器,程序员可以添加新的类型。

一个计数器,可以通过调用SparkContext.accumulator(V)方法来创建。运行在集群上的任务,可以使用+=来加值。然而,它们不能读取计数器的值。当Driver程序需要读取值的时候,它可以使用.value方法。

如下的解释器,展示了如何利用累加器,将一个数组里面的所有元素相加

scala> val accum = sc.accumulator(0)

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

更多资料

在Spark的网站上,你可以看到Spark样例程序

另外,Spark包括了一些例子,在examples/src/main/scala上,有些既有Spark版本,又有本地非并行版本,允许你看到如果要让程序以集群化的方式跑起来的话,需要做什么改变。你可以运行它们,通过将类名传递给spark中的run脚本 — 例如./run spark.examples.SparkPi. 每一个样例程序,都会打印使用帮助,当运行时没任何参数时。


出自 淘宝 明风

出处:http://www.linuxidc.com/Linux/2013-08/88592.htm

参考:http://spark.apache.org/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值