Spark隨談_Spark

來源:互聯網
上載者:User
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的本地模式支援多線程,有一定的單機並發處理能力。但是不算很強勁。本地模式可以儲存結果在本地或者Distributed File System,而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,或者直接寫入到Distributed File System。

基於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 安裝Spark 安裝Mesos 啟動Mesos 啟動Spark On Mesos 叢集部署

1、安裝Spark 1.1 安裝Java

推薦版本是JDK1.6.0 u18,具體下載安裝過程就不說了,最後一定要設定JAVA_HOME,這個是後面步驟,尤其是mesos安裝必須

export JAVA_HOME=/usr/java/jdkexport PATH=$JAVA_HOME/bin:$PATH
1.2 安裝Scala
wget http://www.scala-lang.org/downloads/distrib/files/scala-2.9.2.tgztar xvf scala-2.9.2.tgzmkdir /usr/share/scalacp -r scala-2.9.2/* /usr/share/scalaexport SCALA_HOME=/usr/share/scalaexport 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.0tar -xzvf mesos-spark-v0.5.0-0.tar.gzmv mesos-spark-0472cf8 sparkcd sparksbt/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.gztar zxvf mesos-0.9.0-incubating.tar.gzcd mesos-0.9.0mkdir buildcd 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/mesosmakemake 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/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.