Spark入門學習

1、Spark簡介

Apache Spark是一種快速、通用、可擴展的大數據分析引擎。它是不斷壯大的大數據分析解決方案家族中備受關注的明星成員,爲分佈式數據集的處理提供了一個有效框架,並以高效的方式處理分佈式數據集。Spark集批處理、實時流處理、交互式查詢與圖計算於一體,避免了多種運算場景下需要部署不同集羣帶來的資源浪費。Spark在過去的2014年中獲得了極大關注,並得到廣泛應用,Spark社區也成爲大數據領域和Apache軟件基金會最活躍的項目之一,其活躍度甚至遠超曾經只能望其項背的Hadoop。

2、Spark的優點

第一個優點是速度。

與Hadoop的MapReduce相比,Spark基於內存的運算要快100倍以上;而基於硬盤的運算也要快10倍以上。Spark實現了高效的DAG(數據庫可用性組)執行引擎,可以通過基於內存來高效處理數據流。

第二個優點是易用性。

Spark支持Java、Python和Scala的API,還支持超過80種高級算法,使用戶可以快速構建不同的應用。而且Spark支持交互式的Python和Scala的shell,這意味着可以非常方便地在這些shell中使用Spark集羣來驗證解決問題的方法,而不是像以前一樣,需要打包、上傳集羣、驗證等。這對於原型開發非常重要。

第三個優點是通用性。

Spark提供了統一的解決方案。Spark可以用於批處理、交互式查詢(通過Spark SQL)、實時流處理(通過Spark Streaming)、機器學習(通過Spark MLlib)和圖計算(通過Spark GraphX),這些不同類型的處理都可以在同一個應用中無縫使用。

第四個優點是可融合性。

Spark可以非常方便地與其他的開源產品進行融合。如Spark可以使用Hadoop的YARN和Apache Mesos作爲它的資源管理和調度器,並且可以處理所有Hadoop支持的數據,包括HDFS、HBase和Cas-sandra等,不需要做任何數據遷移就可以使用Spark的強大處理能力。Spark也可以不依賴於第三方的資源管理和調度器,它實現了Standalone作爲其內置的資源管理和調度框架。

3、Spark性能比Hadoop快的原因

傳統Hadoop的數據抽取運算基於磁盤,中間結果也是存儲在磁盤上。


圖1

Spark則使用內存代替了傳統HDFS存儲中間結果:第一代的Hadoop完全使用Hdfs存儲中間結果,第二代的Hadoop加入了cache來保存中間結果。

圖2

4、Spark架構綜述


圖3

4.1、組件介紹

Driver是用戶編寫的數據處理邏輯,這個邏輯中包含用戶創建的SparkContext。
SparkContext是用戶邏輯與Spark集羣主要的交互接口,它會和ClusterManager交互,包括向它申請計算資源等。
Cluster Manager負責集羣的資源管理和調度,現在支持Standalone、Apache Mesos(集羣管理器)和Hadoop的YARN(Apache新MapReduce框架)。
Worker Node是集羣中可以執行計算任務的節點。
Executor是在一個Worker Node上爲某應用啓動的一個進程,該進程負責運行任務,並且負責將數據存在內存或者磁盤上。每個應用都有各自獨立的Executor,計算最終在計算節點的Executor中執行。
Task是被送到某個Executor上的計算單元。

4.2、執行過程

用戶程序從最開始的提交到最終的計算執行,需要經歷以下幾個階段:
1)用戶程序創建SparkContext時,新創建的SparkContext實例會連接到Cluster Manager。Cluster Manager會根據用戶提交時設置的CPU和內存等信息爲本次提交分配計算資源,啓動Executor。
2)Driver會將用戶程序劃分爲不同的執行階段,每個執行階段由一組完全相同的Task組成,這些Task分別作用於待處理數據的不同分區。在階段劃分完成和Task創建後,Driver會向Executor發送Task。
3)Executor在接收到Task後,會下載Task的運行時依賴,在準備好Task的執行環境後,會開始執行Task,並且將Task的運行狀態彙報給Driver。
4)Driver會根據收到的Task的運行狀態來處理不同的狀態更新。Task分爲兩種:一種是Shuffle Map Task,它實現數據的重新洗牌,洗牌的結果保存到Executor所在節點的文件系統中;另外一種是Result Task,它負責生成結果數據。
5)Driver會不斷地調用Task,將Task發送到Executor執行,在所有的Task都正確執行或者超過執行次數的限制仍然沒有執行成功時停止。

5、Spark的核心RDD

5.1、RDD簡介

RDD(Resilient Distributed Dataset,彈性分佈式數據集):分佈在集羣節點上的數據集, 這些集合可以用來進行各種操作。
RDD是Spark操縱數據的一個高度抽象,即Spark所操作的數據集都是包裝成RDD來進行操作的。RDD 是一個有容錯機制且可以被並行操作的元素集合。

5.2、RDD的類型

RDD有2種類型:
1、並行集合(parallelized collections):
接收一個已經存在的 scala 集合,然後進行各種並行計算。
如:val distData=sc.parallelize(Array(1,2,3,4,5))
即創建了一個 Int 數組的 RDD 集合。
distData.collect()
2、 Hadoop 數據集:
是從 hadoop 上的文件系統創建的 RDD。
可以支持 textfile,sequence file 以及其他任何的 hadoop 輸入格式。
如: val val tfile=sc.textFile(“hdfs://master:9000/tmp/file2.txt”)
一旦創建完成, tfile 可以被進行數據集操作:
val counts = tfile.flatMap(line => line.split(” “)).map(word => (word,1)).reduceByKey(+)
counts.collect()

5.3、RDD支持的操作

RDD 支持2種操作:
1、轉換(transformation):從現有的數據集創建一個新的數據集。
2、動作(actions):在數據集上運行計算後,返回一個值給驅動程序。

5.4、RDD提供的功能

RDD提供2種功能:
1、斷點恢復功能:
當多次計算過程中有某些 RDD 被重複使用或者保持斷點恢復功能,爲了減少計算代價,可以調用 checkpoint()方法來標記 RDD 是需要被 checkpoint的 , 當下次使用該 RDD 時, 將直接使用該 RDD 的 CheckPointRdd,不再重新計算該 RDD 及其父 RDD。
2、在內存中持久化數據集:
Spark 最重要的一個功能,就是在不同操作間,持久化(或緩存)一個數據集在內存中。當持久化一個 RDD, 每一個結點都將把它的計算分塊結果保存在內存中, 並在對此數據集 (或者衍生出的數據集) 進行的其它動作中重用。 這將使得後續的動作(Actions)變得更加迅速 (通常快10倍) 。
緩存是用 Spark 構建迭代算法的關鍵。

6、Spark核心組件概述

Spark Streaming實現了實時流處理;
GraphX實現了圖計算;
MLlib實現了很多機器學習算法;
Spark SQL實現了基於Spark的交互式查詢。

6.1、Spark Streaming

Spark Streaming基於Spark Core實現了可擴展、高吞吐和容錯的實時數據流處理。


圖4

現在支持的數據源有Kafka、Flume、Twitter、ZeroMQ、Ki-nesis、HDFS、S3和TCP socket。處理後的結果可以存儲到HDFS、Database或者Dashboard中。

圖5

Spark Streaming是將流式計算分解成一系列短小的批處理作業。這裏的批處理引擎是Spark,也就是把Spark Streaming的輸入數據按照批處理尺寸(如1秒)分成一段一段的數據(Stream),每一段數據都轉換成Spark中的RDD,然後將Spark Streaming中對DStream的轉換操作變爲針對Spark中對RDD的轉換操作,將RDD經過操作變成中間結果保存在內存中。

6.2、Mlib

MLlib是Spark對常用的機器學習算法的實現庫,同時含有相關的測試和數據生成器,包括分類、迴歸、聚類、協同過濾、降維(dimensionality re-duction)以及底層基本的優化元素。
現在,MLlib實現了許多常用的算法:
與分類和迴歸相關的算法包括SVM、邏輯迴歸、線性迴歸、樸素貝葉斯分類、決策樹等;協同過濾實現了交替最小二乘法(Alternating Least Square,ALS);
聚類實現了K-means、高斯混合(Gaus-sian mixture)、Power Iteration Clustering(PIC)、Latent Dirichlet Allocation(LDA)和Streaming版本的K-means;
降維實現了Singular Value De-composition(SVD)和Principal ComponentAnalysis(PCA);頻繁模式挖掘(frequent pat-tern mining)實現了FP-growth。

6.3、Spark SQL

Spark SQL支持的數據源:


圖6

數據源API通過Spark SQL提供了訪問結構化數據的可插拔機制。這使數據源有了簡便的途徑進行數據轉換並加入到Spark平臺中。
由API提供的密集優化器集合意味着過濾和列修剪在很多情況下都會被運用於數據源。這些綜合的優化極大地減少了需要處理的數據量,因此能夠顯著提高Spark的工作效率。
數據源API的另一個優點就是不管數據的來源如何,用戶都能夠通過Spark支持的所有語言來操作這些數據。
此外,Spark SQL可以使用單一接口訪問不同數據源的數據。
總之,Spark SQL提供的這些功能進一步統一了大數據分析的解決方案。

6.4、GraphX

Spark GraphX是Spark提供的關於圖和圖並行計算的API,它集ETL、試探性分析和迭代式的圖計算於一體,並且在不失靈活性、易用性和容錯性的前提下獲得了很好的性能。現在GraphX已經提供了很多的算法,新的算法也在不斷加入,而且很多的算法都是由Spark的用戶貢獻的。

7、Spark支持的部署方式

目前Apache Spark支持三種分佈式部署方式,分別是standalone、spark on mesos和 spark on YARN。

7.1、standalone模式。

即獨立模式,自帶完整的服務,可單獨部署到一個集羣中,無需依賴任何其他資源管理系統。從一定程度上說,該模式是其他兩種的基礎。
Spark On Mesos模式。
這是很多公司採用的模式,官方推薦這種模式(當然,原因之一是血緣關係)。正是由於Spark開發之初就考慮到支持Mesos,因此,目前而言,Spark運行在Mesos上會比運行在YARN上更加靈活,更加自然。目前在Spark On Mesos環境中,用戶可選擇兩種調度模式之一運行自己的應用程序:
1)粗粒度模式。2)細粒度模式。
1) 粗粒度模式(Coarse-grained Mode):每個應用程序的運行環境由一個Dirver和若干個Executor組成,其中,每個Executor佔用若干資源,內部可運行多個Task(對應多少個“slot”)。應用程序的各個任務正式運行之前,需要將運行環境中的資源全部申請好,且運行過程中要一直佔用這些資源,即使不用,最後程序運行結束後,回收這些資源。舉個例子,比如你提交應用程序時,指定使用5個executor運行你的應用程序,每個executor佔用5GB內存和5個CPU,每個executor內部設置了5個slot,則Mesos需要先爲executor分配資源並啓動它們,之後開始調度任務。另外,在程序運行過程中,mesos的master和slave並不知道executor內部各個task的運行情況,executor直接將任務狀態通過內部的通信機制彙報給Driver,從一定程度上可以認爲,每個應用程序利用mesos搭建了一個虛擬集羣自己使用。
2) 細粒度模式(Fine-grained Mode):鑑於粗粒度模式會造成大量資源浪費,Spark On Mesos還提供了另外一種調度模式:細粒度模式,這種模式類似於現在的雲計算,思想是按需分配。與粗粒度模式一樣,應用程序啓動時,先會啓動executor,但每個executor佔用資源僅僅是自己運行所需的資源,不需要考慮將來要運行的任務,之後,mesos會爲每個executor動態分配資源,每分配一些,便可以運行一個新任務,單個Task運行完之後可以馬上釋放對應的資源。每個Task會彙報狀態給Mesos slave和Mesos Master,便於更加細粒度管理和容錯,這種調度模式類似於MapReduce調度模式,每個Task完全獨立,優點是便於資源控制和隔離,但缺點也很明顯,短作業運行延遲大。

7.2、Spark On Mesos模式。

這是很多公司採用的模式,官方推薦這種模式(當然,原因之一是血緣關係)。正是由於Spark開發之初就考慮到支持Mesos,因此,目前而言,Spark運行在Mesos上會比運行在YARN上更加靈活,更加自然。目前在Spark On Mesos環境中,用戶可選擇兩種調度模式之一運行自己的應用程序:
1)粗粒度模式。2)細粒度模式。

7.3、Spark On YARN模式。

這是一種最有前景的部署模式。但限於YARN自身的發展,目前僅支持粗粒度模式(Coarse-grained Mode)。這是由於YARN上的Container資源是不可以動態伸縮的,一旦Container啓動之後,可使用的資源不能再發生變化,不過這個已經在YARN計劃。

8、Spark應用實例

任何Spark程序的編寫都是從SparkContext(或用java編寫時的JavaSparkContext)開始的。SparkContext的初始化需要一個SparkConf對象,後者包含了Spark集羣配置的各種參數。
初始化後,我們可用SparkContext對象包含的各種方法來創建和操作分佈式數據集和共享變量。Spark shell(在Scala和Python下可以,但不支持Java)能自動完成上述初始化。若要用Scala代碼來實現的話,可參照以下代碼:
val conf=new SparkConf()
.setAppName(“Test Spark App”)
.setMaster(“local[4]”)
val sc=new SparkContext(conf)
這段代碼會創建一個4個線程的SparkContext對象,並將其相應的任務命名爲Test Spark APP。我們也可通過如下方式調用SparkContext的簡單構造函數,以默認的參數值來創建相應的對象。其效果和上述的完全相同:
val sc=new SparkContext(“local[4]”,”Test Spark App”)

8.1、WordCount

8.1.1、讀取本地文件:

val file=sc.textFile(“file:/opt/file/file2.txt”)
val count=file.flatMap(line => line.split(” “)).map(word => (word,1)).reduceByKey(+)//<=>(x,y)=>x+y (x相同則y相加)
count.count()//返回記錄的數目
count.collect()//將RDD以Scala集合的形式返回

8.1.2、讀取hdfs中的文件:

val tfile=sc.textFile(“hdfs://master:9000/tmp/file1.txt”)
val counts = tfile.flatMap(line => line.split(” “)).map(word => (word,1)).reduceByKey(+)
counts.count()
counts.collect()

程序解讀:

=>是Scala下表示匿名函數的語法。匿名函數指那些沒有指定函數名的函數(比如Scala或Python中用def關鍵字定義的函數)。
語法line=>line.size表示以=>操作符左邊的部分作爲輸入,對其執行一個函數,並以=>操作符右邊代碼的執行結果爲輸出。在這個例子中,輸入爲line,輸出則是line.size函數的執行結果。

8.2、 Estimating Pi

val count = sc.parallelize(1 to 10000).map{i =>
val x = Math.random()
val y = Math.random()
if (x*x + y*y < 1)
1
else
0}.reduce(_ + _)

4.0 * count / 10000
此算法設計來源於數學經典求pi值之面積比方法。

9、 資源推薦


圖7

發佈了56 篇原創文章 · 獲贊 108 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章