《深刻理解Spark:核心思想與源碼分析》(第2章)

《深刻理解Spark:核心思想與源碼分析》一書前言的內容請看連接《深刻理解SPARK:核心思想與源碼分析》一書正式出版上市html

《深刻理解Spark:核心思想與源碼分析》一書第一章的內容請看連接《第1章 環境準備》算法

本文主要展現本書的第2章內容:shell

Spark設計理念與基本架構

「若夫乘天地之正,而御六氣之辯,以遊無窮者,彼且惡乎待哉?」數據庫

——《莊子·逍遙遊》apache

n  本章導讀:編程

上一章,介紹了Spark環境的搭建,爲方便讀者學習Spark作好準備。本章首先從Spark產生的背景開始,介紹Spark的主要特色、基本概念、版本變遷。而後簡要說明Spark的主要模塊和編程模型。最後從Spark的設計理念和基本架構入手,使讀者可以對Spark有宏觀的認識,爲以後的內容作一些準備工做。c#

Spark是一個通用的並行計算框架,由加州伯克利大學(UCBerkeley)的AMP實驗室開發於2009年,並於2010年開源。2013年成長爲Apache旗下爲大數據領域最活躍的開源項目之一。Spark也是基於map reduce 算法模式實現的分佈式計算框架,擁有Hadoop MapReduce所具備的優勢,而且解決了Hadoop MapReduce中的諸多缺陷。緩存

 

2.1 初識Spark

2.1.1 Hadoop MRv1的侷限

         早在Hadoop1.0版本,當時採用的是MRv1版本的MapReduce編程模型。MRv1版本的實現都封裝在org.apache.hadoop.mapred包中,MRv1MapReduce是經過接口實現的。MRv1包括三個部分:安全

q  運行時環境(JobTrackerTaskTracker);網絡

q  編程模型(MapReduce);

q  數據處理引擎(Map任務和Reduce任務)。

MRv1存在如下不足:

q  可擴展性差:在運行時,JobTracker既負責資源管理又負責任務調度,當集羣繁忙時,JobTracker很容易成爲瓶頸,最終致使它的可擴展性問題。

q  可用性差:採用了單節點的Master,沒有備用Master及選舉操做,這致使一旦Master出現故障,整個集羣將不可用。

q  資源利用率低:TaskTracker 使用「slot」等量劃分本節點上的資源量。「slot」表明計算資源(CPU、內存等)。一個Task 獲取到一個slot 後纔有機會運行,Hadoop 調度器負責將各個TaskTracker 上的空閒slot 分配給Task 使用。一些Task並不能充分利用slot,而其餘Task也沒法使用這些空閒的資源。slot 分爲Map slot Reduce slot 兩種,分別供MapTask Reduce Task 使用。有時會由於做業剛剛啓動等緣由致使MapTask不少,而Reduce Task任務尚未調度的狀況,這時Reduce slot也會被閒置。

q  不能支持多種MapReduce框架:沒法經過可插拔方式將自身的MapReduce框架替換爲其餘實現,如SparkStorm等。

MRv1的示意如圖2-1

2-1        MRv1示意圖 [1]

Apache爲了解決以上問題,對Hadoop升級改造,MRv2最終誕生了。MRv2中,重用了MRv1中的編程模型和數據處理引擎。可是運行時環境被重構了。JobTracker被拆分紅了通用的資源調度平臺(ResourceManager,簡稱RM)和負責各個計算框架的任務調度模型(ApplicationMaste,簡稱AM)。MRv2MapReduce的核心再也不是MapReduce框架,而是YARN。在以YARN爲核心的MRv2中,MapReduce框架是可插拔的,徹底能夠替換爲其餘MapReduce實現,好比SparkStorm等。MRv2的示意如圖2-2所示。

2-2        MRv2示意圖

         Hadoop MRv2雖然解決了MRv1中的一些問題,可是因爲對HDFS的頻繁操做(包括計算結果持久化、數據備份及shuffle等)致使磁盤I/O成爲系統性能的瓶頸,所以只適用於離線數據處理,而不能提供實時數據處理能力。

2.1.2 Spark使用場景

         Hadoop經常使用於解決高吞吐、批量處理的業務場景,例如離線計算結果用於瀏覽量統計。若是須要實時查看瀏覽量統計信息,Hadoop顯然不符合這樣的要求。Spark經過內存計算能力極大地提升了大數據處理速度,知足了以上場景的須要。此外,Spark還支持SQL查詢,流式計算,圖計算,機器學習等。經過對JavaPythonScalaR等語言的支持,極大地方便了用戶的使用。

2.1.3 Spark的特色

         Spark看到MRv1的問題,對MapReduce作了大量優化,總結以下:

q  快速處理能力。隨着實時大數據應用愈來愈多,Hadoop做爲離線的高吞吐、低響應框架已不能知足這類需求。Hadoop MapReduceJob將中間輸出和結果存儲在HDFS中,讀寫HDFS形成磁盤IO成爲瓶頸。Spark容許將中間輸出和結果存儲在內存中,節省了大量的磁盤IO。同時Spark自身的DAG執行引擎也支持數據在內存中的計算。Spark官網聲稱性能比Hadoop100倍,如圖2-3所示。即使是內存不足須要磁盤IO,其速度也是Hadoop10倍以上。

2-3        HadoopSpark執行邏輯迴歸時間比較

q  易於使用。Spark如今支持JavaScalaPythonR等語言編寫應用程序,大大下降了使用者的門檻。自帶了80多個高等級操做符,容許在ScalaPythonRshell中進行交互式查詢。

q  支持查詢。Spark支持SQLHive SQL對數據查詢。

q  支持流式計算。與MapReduce只能處理離線數據相比,Spark還支持實時的流計算。Spark依賴Spark Streaming對數據進行實時的處理,其流式處理能力還要強於Storm

q  可用性高。Spark自身實現了Standalone部署模式,此模式下的Master能夠有多個,解決了單點故障問題。此模式徹底可使用其餘集羣管理器替換,好比YARNMesosEC2等。

q  豐富的數據源支持。Spark除了能夠訪問操做系統自身的文件系統和HDFS,還能夠訪問Cassandra, HBase, Hive, Tachyon以及任何Hadoop的數據源。這極大地方便了已經使用HDFSHbase的用戶順利遷移到Spark

2.2 Spark基礎知識

1.版本變遷

         通過4年多的發展,Spark目前的版本是1.4.1。咱們簡單看看它的版本發展過程。

1)         Spark誕生於UCBerkeleyAMP實驗室(2009)。

2)         Spark正式對外開源(2010)。

3)         Spark 0.6.0版本發佈(2012-10-15),大範圍的性能改進,增長了一些新特性,並對Standalone部署模式進行了簡化。

4)         Spark 0.6.2版本發佈(2013-02-07),解決了一些bug,並加強了系統的可用性。

5)         Spark 0.7.0版本發佈(2013-02-27),增長了更多關鍵特性,例如:Python APISpark Streamingalpha版本等。

6)         Spark 0.7.2版本發佈(2013-06-02),性能改進並解決了一些bug,新的API使用的例子。

7)         Spark接受進入Apache孵化器(2013-06-21)。

8)         Spark 0.7.3版本發佈(2013-07-16),一些bug的解決,更新Spark Streaming API等。

9)         Spark 0.8.0版本發佈(2013-09-25),一些新功能及可用性改進。

10)     Spark 0.8.1版本發佈(2013-12-19),支持Scala 2.9YARN 2.2Standalone部署模式下調度的高可用性,shuffle的優化等。

11)     Spark 0.9.0版本發佈(2014-02-02),增長了GraphX,機器學習新特性,流式計算新特性,核心引擎優化(外部聚合、增強對YARN的支持)等。

12)     Spark 0.9.1版本發佈(2014-04-09),增長使用YARN的穩定性,改進ScalaPython API的奇偶性。

13)     Spark 1.0.0版本發佈(2014-05-30),增長了Spark SQLMLlibGraphXSpark Streaming都增長了新特性並進行了優化。Spark核心引擎還增長了對安全YARN集羣的支持。

14)     Spark 1.0.1版本發佈(2014-07-11),增長了Spark SQL的新特性和堆JSON數據的支持等。

15)     Spark 1.0.2版本發佈(2014-08-05),Spark核心APIStreamingPythonMLlibbug修復。

16)     Spark 1.1.0版本發佈(2014-09-11)。

17)     Spark 1.1.1版本發佈(2014-11-26),Spark核心APIStreamingPythonSQLGraphXMLlibbug修復。

18)     Spark 1.2.0版本發佈(2014-12-18)。

19)     Spark 1.2.1版本發佈(2015-02-09),Spark核心APIStreamingPythonSQLGraphXMLlibbug修復。

20)     Spark 1.3.0版本發佈(2015-03-13)。

21)     Spark 1.4.0版本發佈(2015-06-11)。

22)     Spark 1.4.1版本發佈(2015-07-15),DataFrame APIStreamingPythonSQLMLlibbug修復。

2.基本概念

         要想對Spark有總體性的瞭解,推薦讀者閱讀Matei ZahariaSpark論文。此處筆者先介紹Spark中的一些概念:

q  RDDresillient distributed dataset):彈性分佈式數據集。

q  Task:具體執行任務。Task分爲ShuffleMapTaskResultTask兩種。ShuffleMapTaskResultTask分別相似於Hadoop中的MapReduce

q  Job:用戶提交的做業。一個Job可能由一到多個Task組成。

q  StageJob分紅的階段。一個Job可能被劃分爲一到多個Stage

q  Partition:數據分區。即一個RDD的數據能夠劃分爲多少個分區。

q  NarrowDependency:窄依賴。即子RDD依賴於父RDD中固定的PartitionNarrowDependency分爲OneToOneDependencyRangeDependency兩種。

q  ShuffleDependencyshuffle依賴,也稱爲寬依賴。即子RDD對父RDD中的全部Partition都有依賴。

q  DAGDirected Acycle graph):有向無環圖。用於反映各RDD之間的依賴關係。

3.ScalaJava的比較

         Spark爲何要選擇Java做爲開發語言?筆者不得而知。若是能對兩者進行比較,也許能看出一些端倪。表2-1列出了對ScalaJava的比較。

2-1        ScalaJava的比較

 

Scala

Java

語言類型

面向函數爲主,兼有面向對象

面向對象(Java8也增長了lambda函數編程)

簡潔性

很是簡潔

不簡潔

類型推斷

豐富的類型推斷,例如深度和鏈式的類型推斷、 duck type 、隱式類型轉換等,但也所以增長了編譯時長

少許的類型推斷

可讀性

通常,豐富的語法糖致使的各類奇幻用法,例如方法簽名

學習成本

較高

通常

語言特性

很是豐富的語法糖和更現代的語言特性,例如 Option 、模式匹配、使用空格的方法調用

豐富

併發編程

使用Actor的消息模型

使用阻塞、鎖、阻塞隊列等

 

經過以上比較彷佛仍然沒法判斷Spark選擇開發語言的緣由。因爲函數式編程更接近計算機思惟,所以便於經過算法從大數據中建模,這應該更符合Spark做爲大數據框架的理念吧!

2.3 Spark基本設計思想

2.3.1 模塊設計

         整個Spark主要由如下模塊組成:

q  Spark CoreSpark的核心功能實現,包括:SparkContext的初始化(Driver Application經過SparkContext提交)、部署模式、存儲體系、任務提交與執行、計算引擎等。

q  Spark SQL:提供SQL處理能力,便於熟悉關係型數據庫操做的工程師進行交互查詢。此外,還爲熟悉Hadoop的用戶提供Hive SQL處理能力。

q  Spark Streaming:提供流式計算處理能力,目前支持KafkaFlumeTwitterMQTTZeroMQKinesis和簡單的TCP套接字等數據源。此外,還提供窗口操做。

q  GraphX:提供圖計算處理能力,支持分佈式, Pregel提供的API能夠解決圖計算中的常見問題。

q  MLlib:提供機器學習相關的統計、分類、迴歸等領域的多種算法實現。其一致的API接口大大下降了用戶的學習成本。

Spark SQLSpark StreamingGraphXMLlib的能力都是創建在覈心引擎之上,如圖2-4

2-4        Spark各模塊依賴關係

1.   Spark核心功能

Spark Core提供Spark最基礎與最核心的功能,主要包括:

q  SparkContext:一般而言,Driver Application的執行與輸出都是經過SparkContext來完成的,在正式提交Application以前,首先須要初始化SparkContextSparkContext隱藏了網絡通訊、分佈式部署、消息通訊、存儲能力、計算能力、緩存、測量系統、文件服務、Web服務等內容,應用程序開發者只須要使用SparkContext提供的API完成功能開發。SparkContext內置的DAGScheduler負責建立Job,將DAG中的RDD劃分到不一樣的Stage,提交Stage等功能。內置的TaskScheduler負責資源的申請、任務的提交及請求集羣對任務的調度等工做。

q  存儲體系:Spark優先考慮使用各節點的內存做爲存儲,當內存不足時纔會考慮使用磁盤,這極大地減小了磁盤I/O,提高了任務執行的效率,使得Spark適用於實時計算、流式計算等場景。此外,Spark還提供了之內存爲中心的高容錯的分佈式文件系統Tachyon供用戶進行選擇。Tachyon可以爲Spark提供可靠的內存級的文件共享服務。

q  計算引擎:計算引擎由SparkContext中的DAGSchedulerRDD以及具體節點上的Executor負責執行的MapReduce任務組成。DAGSchedulerRDD雖然位於SparkContext內部,可是在任務正式提交與執行以前將Job中的RDD組織成有向無關圖(簡稱DAG)、並對Stage進行劃分決定了任務執行階段任務的數量、迭代計算、shuffle等過程。

2.   Spark擴展功能

         爲了擴大應用範圍,Spark陸續增長了一些擴展功能,主要包括:

q  Spark SQL:因爲SQL具備普及率高、學習成本低等特色,爲了擴大Spark的應用面,所以增長了對SQLHive的支持。Spark SQL的過程能夠總結爲:首先使用SQL語句解析器(SqlParser)將SQL轉換爲語法樹(Tree),而且使用規則執行器(RuleExecutor)將一系列規則(Rule)應用到語法樹,最終生成物理執行計劃並執行的過程。其中,規則包括語法分析器(Analyzer)和優化器(Optimizer)。Hive的執行過程與SQ相似。

q  Spark StreamingSpark StreamingApache Storm相似,也用於流式計算。Spark Streaming支持KafkaFlumeTwitterMQTTZeroMQKinesis和簡單的TCP套接字等多種數據輸入源。輸入流接收器(Receiver)負責接入數據,是接入數據流的接口規範。DstreamSpark Streaming中全部數據流的抽象,Dstream能夠被組織爲DStream GraphDstream本質上由一系列連續的RDD組成。

q  GraphXSpark提供的分佈式圖計算框架。GraphX主要遵循總體同步並行計算模式(Bulk Synchronous Parallell,簡稱BSP)下的Pregel模型實現。GraphX提供了對圖的抽象GraphGraph由頂點(Vertex)、邊(Edge)及繼承了EdgeEdgeTriplet(添加了srcAttrdstAttr用來保存源頂點和目的頂點的屬性)三種結構組成。GraphX目前已經封裝了最短路徑、網頁排名、鏈接組件、三角關係統計等算法的實現,用戶能夠選擇使用。

q  MLlibSpark提供的機器學習框架。機器學習是一門涉及機率論、統計學、逼近論、凸分析、算法複雜度理論等多領域的交叉學科。MLlib目前已經提供了基礎統計、分類、迴歸、決策樹、隨機森林、樸素貝葉斯、保序迴歸、協同過濾、聚類、維數縮減、特徵提取與轉型、頻繁模式挖掘、預言模型標記語言、管道等多種數理統計、機率論、數據挖掘方面的數學算法

 

 

2.3.2 Spark模型設計

 

1. Spark編程模型

Spark 應用程序從編寫到提交、執行、輸出的整個過程如圖2-5所示,圖中描述的步驟以下:

1)         用戶使用SparkContext提供的API(經常使用的有textFilesequenceFilerunJobstop等)編寫Driver application程序。此外SQLContextHiveContextStreamingContextSparkContext進行封裝,並提供了SQLHive及流式計算相關的API

2)         使用SparkContext提交的用戶應用程序,首先會使用BlockManagerBroadcastManager將任務的Hadoop配置進行廣播。而後由DAGScheduler將任務轉換爲RDD並組織成DAGDAG還將被劃分爲不一樣的Stage。最後由TaskScheduler藉助ActorSystem將任務提交給集羣管理器(Cluster Manager)。

3)         集羣管理器(Cluster Manager)給任務分配資源,即將具體任務分配到Worker上,Worker建立Executor來處理任務的運行。StandaloneYARNMesosEC2等均可以做爲Spark的集羣管理器。

2-5        代碼執行過程

2. Spark計算模型

         RDD能夠看作是對各類數據計算模型的統一抽象,Spark的計算過程主要是RDD的迭代計算過程,如圖2-6RDD的迭代計算過程很是相似於管道。分區數量取決於partition數量的設定,每一個分區的數據只會在一個Task中計算。全部分區能夠在多個機器節點的Executor上並行執行。

2-6        RDD計算模型

 

2.4 Spark基本架構

         從集羣部署的角度來看,Spark集羣由如下部分組成:

q  Cluster ManagerSpark的集羣管理器,主要負責資源的分配與管理。集羣管理器分配的資源屬於一級分配,它將各個Worker上的內存、CPU等資源分配給應用程序,可是並不負責對Executor的資源分配。目前,StandaloneYARNMesosEC2等均可以做爲Spark的集羣管理器。

q  WorkerSpark的工做節點。對Spark應用程序來講,由集羣管理器分配獲得資源的Worker節點主要負責如下工做:建立Executor,將資源和任務進一步分配給Executor,同步資源信息給Cluster Manager

q  Executor:執行計算任務的一線進程。主要負責任務的執行以及與WorkerDriver App的信息同步。

q  Driver App:客戶端驅動程序,也能夠理解爲客戶端應用程序,用於將任務程序轉換爲RDDDAG,並與Cluster Manager進行通訊與調度。

這些組成部分之間的總體關係如圖2-7所示。

2-7        Spark基本架構圖

2.5 小結

         每項技術的誕生都會由某種社會需求所驅動,Spark正是在實時計算的大量需求下誕生的。Spark藉助其優秀的處理能力,可用性高,豐富的數據源支持等特色,在當前大數據領域變得火熱,參與的開發者也愈來愈多。Spark通過幾年的迭代發展,現在已經提供了豐富的功能。筆者相信,Spark在將來必將產生更耀眼的火花。



[1] 2-1和圖2-2都來源自http://blog.chinaunix.net/uid-28311809-id-4383551.html

 

後記:本身犧牲了7個月的週末和下班空閒時間,經過研究Spark源碼和原理,總結整理的《深刻理解Spark:核心思想與源碼分析》一書如今已經正式出版上市,目前亞馬遜、京東、噹噹、天貓等網站均有銷售,歡迎感興趣的同窗購買。我開始研究源碼時的Spark版本是1.2.0,通過7個多月的研究和出版社近4個月的流程,Spark自身的版本迭代也很快,現在最新已是1.6.0。目前市面上另外2本源碼研究的Spark書籍的版本分別是0.9.0版本和1.2.0版本,看來這些書的做者都與我同樣,遇到了這種問題。因爲研究和出版都須要時間,因此不能及時跟上Spark的腳步,還請你們見諒。可是Spark核心部分的變化相對仍是不多的,若是對版本不是過於追求,依然能夠選擇本書。

 

京東(現有滿100減30活動):http://item.jd.com/11846120.html 

噹噹:http://product.dangdang.com/23838168.html 

亞馬遜:http://www.amazon.cn/gp/product/B01A5G5LHK/sr=8-1/qid=1452505597/ref=olp_product_details?ie=UTF8&me=&qid=1452505597&sr=8-1

相關文章
相關標籤/搜索