1. 程式人生 > >Spark設計理念與基本架構

Spark設計理念與基本架構

http textfile hdf www 接受 ng- exe tag 高可用

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

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


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


第2章 設計理念與基本架構


“若夫乘天地之正。而禦六氣之辯,以遊無窮者。彼且惡乎待哉?”

——《莊子·逍遙遊》

本章導讀:

上一章,介紹了Spark環境的搭建。為方便讀者學習Spark做好準備。本章首先從Spark產生的背景開始,介紹Spark的主要特點、基本概念、版本號變遷。然後簡要說明Spark的主要模塊和編程模型。

最後從Spark的設計理念和基本架構入手,使讀者可以對Spark有宏觀的認識,為之後的內容做一些準備工作。

Spark是一個通用的並行計算框架,由加州伯克利大學(UCBerkeley)的AMP實驗室開發於2009年。並於2010年開源。

2013年成長為Apache旗下為大數據領域最活躍的開源項目之中的一個。Spark也是基於map reduce 算法模式實現的分布式計算框架,擁有Hadoop MapReduce所具有的長處,而且攻克了HadoopMapReduce中的諸多缺陷。



2.1 初識Spark


2.1.1 Hadoop MRv1的局限

早在Hadoop1.0版本號。當時採用的是MRv1版本號的MapReduce編程模型。MRv1版本號的實現都封裝在org.apache.hadoop.mapred包中。MRv1的Map和Reduce是通過接口實現的。MRv1包含三個部分:

  • 執行時環境(JobTracker和TaskTracker)。
  • 編程模型(MapReduce);
  • 數據處理引擎(Map任務和Reduce任務)。

MRv1存在下面不足:

  • 可擴展性差:在執行時,JobTracker既負責資源管理又負責任務調度,當集群繁忙時。JobTracker非常easy成為瓶頸。終於導致它的可擴展性問題。

  • 可用性差:採用了單節點的Master,沒有備用Master及選舉操作,這導致一旦Master出現問題,整個集群將不可用。
  • 資源利用率低: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也會被閑置。

  • 不能支持多種MapReduce框架:無法通過可插拔方式將自身的MapReduce框架替換為其它實現,如Spark、Storm等。

MRv1的示意如圖2-1。

技術分享

圖2-1 MRv1示意圖

Apache為了解決以上問題,對Hadoop升級改造,MRv2終於誕生了。MRv2中,重用了MRv1中的編程模型和數據處理引擎。可是執行時環境被重構了。

JobTracker被拆分成了通用的資源調度平臺(ResourceManager,簡稱RM)和負責各個計算框架的任務調度模型(ApplicationMaste,簡稱AM)。MRv2中MapReduce的核心不再是MapReduce框架,而是YARN。在以YARN為核心的MRv2中,MapReduce框架是可插拔的。全然能夠替換為其它MapReduce實現,比方Spark、Storm等。MRv2的示意如圖2-2所看到的。

技術分享

圖2-2 MRv2示意圖

Hadoop MRv2盡管攻克了MRv1中的一些問題。可是因為對HDFS的頻繁操作(包含計算結果持久化、數據備份及shuffle等)導致磁盤I/O成為系統性能的瓶頸,因此僅僅適用於離線數據處理,而不能提供實時數據處理能力。


2.1.2 使用場景

Hadoop經常使用於解決高吞吐、批量處理的業務場景,比如離線計算結果用於瀏覽量統計。假設須要實時查看瀏覽量統計信息。Hadoop顯然不符合這種要求。

Spark通過內存計算能力極大地提高了大數據處理速度,滿足了以上場景的須要。此外,Spark還支持SQL查詢,流式計算,圖計算。機器學習等。

通過對Java、Python、Scala、R等語言的支持,極大地方便了用戶的使用。

2.1.3 Spark的特點

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

  • 高速處理能力。隨著實時大數據應用越來越多,Hadoop作為離線的高吞吐、低響應框架已不能滿足這類需求。HadoopMapReduce的Job將中間輸出和結果存儲在HDFS中,讀寫HDFS造成磁盤IO成為瓶頸。Spark同意將中間輸出和結果存儲在內存中。節省了大量的磁盤IO。

    同一時候Spark自身的DAG運行引擎也支持數據在內存中的計算。Spark官網聲稱性能比Hadoop快100倍,如圖2-3所看到的。即便是內存不足須要磁盤IO。其速度也是Hadoop的10倍以上。

技術分享

圖2-3 Hadoop與Spark運行邏輯回歸時間比較

  • 易於使用。Spark如今支持Java、Scala、Python和R等語言編寫應用程序,大大減少了使用者的門檻。自帶了80多個高等級操作符,同意在Scala,Python,R的shell中進行交互式查詢。
  • 支持查詢。

    Spark支持SQL及Hive SQL對數據查詢。

  • 支持流式計算。

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

  • 可用性高。Spark自身實現了Standalone部署模式,此模式下的Master能夠有多個,攻克了單點故障問題。此模式全然能夠使用其它集群管理器替換。比方YARN、Mesos、EC2等。
  • 豐富的數據源支持。Spark除了能夠訪問操作系統自身的文件系統和HDFS。還能夠訪問Cassandra, HBase, Hive, Tachyon以及不論什麽Hadoop的數據源。這極大地方便了已經使用HDFS、Hbase的用戶順利遷移到Spark。


2.2 基礎知識


1.版本號變遷

經過4年多的發展,Spark眼下的版本號是1.4.1。我們簡單看看它的版本號發展過程。

1) Spark誕生於UCBerkeley的AMP實驗室(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),添加了很多其它關鍵特性。比如:PythonAPI、Spark Streaming的alpha版本號等。

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.9,YARN 2.2,Standalone部署模式下調度的高可用性。shuffle的優化等。

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

12) Spark 0.9.1版本號公布(2014-04-09)。添加使用YARN的穩定性。改進Scala和Python API的奇偶性。

13) Spark 1.0.0版本號公布(2014-05-30),添加了Spark SQL、MLlib、GraphX和Spark Streaming都添加了新特性並進行了優化。

Spark核心引擎還添加了對安全YARN集群的支持。

14) Spark 1.0.1版本號公布(2014-07-11),添加了Spark SQL的新特性和堆JSON數據的支持等。

15) Spark 1.0.2版本號公布(2014-08-05)。Spark核心API及Streaming。Python,MLlib的bug修復。

16) Spark 1.1.0版本號公布(2014-09-11)。

17) Spark 1.1.1版本號公布(2014-11-26),Spark核心API及Streaming,Python。SQL。GraphX和MLlib的bug修復。

18) Spark 1.2.0版本號公布(2014-12-18)。

19) Spark 1.2.1版本號公布(2015-02-09)。Spark核心API及Streaming,Python。SQL。GraphX和MLlib的bug修復。

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 API及Streaming,Python。SQL和MLlib的bug修復。


2.基本概念

要想對Spark有總體性的了解,推薦讀者閱讀Matei Zaharia的Spark論文。

此處筆者先介紹Spark中的一些概念:

  • RDD(resillient distributed dataset):彈性分布式數據集。
  • Task:詳細運行任務。Task分為ShuffleMapTask和ResultTask兩種。ShuffleMapTask和ResultTask分別類似於Hadoop中的Map,Reduce。
  • Job:用戶提交的作業。

    一個Job可能由一到多個Task組成。

  • Stage:Job分成的階段。一個Job可能被劃分為一到多個Stage。

  • Partition:數據分區。

    即一個RDD的數據能夠劃分為多少個分區。

  • NarrowDependency:窄依賴。

    即子RDD依賴於父RDD中固定的Partition。NarrowDependency分為OneToOneDependency和RangeDependency兩種。

  • ShuffleDependency:shuffle依賴,也稱為寬依賴。

    即子RDD對父RDD中的全部Partition都有依賴。

  • DAG(Directed Acycle graph):有向無環圖。用於反映各RDD之間的依賴關系。

3.與Java的比較

Spark為什麽要選擇Java作為開發語言?筆者不得而知。假設能對二者進行比較,或許能看出一些端倪。

表2-1列出了對Scala與Java的比較。

表2-1 Scala與Java的比較

Scala

Java

語言類型

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

面向對象(Java8也添加了lambda函數編程)

簡潔性

很簡潔

不簡潔

類型判斷

豐富的類型判斷,比如深度和鏈式的類型判斷、 duck type 、隱式類型轉換等,但也因此添加了編譯時長

少量的類型判斷

可讀性

一般,豐富的語法糖導致的各種奇幻使用方法,比如方法簽名

學習成本

較高

一般

語言特性

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

豐富

並發編程

使用Actor的消息模型

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

通過以上比較似乎仍然無法推斷Spark選擇開發語言的原因。因為函數式編程更接近計算機思維,因此便於通過算法從大數據中建模,這應該更符合Spark作為大數據框架的理念吧!


2.3 基本設計思想


2.3.1 Spark模塊設計

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

  • Spark Core:Spark的核心功能實現,包含:SparkContext的初始化(DriverApplication通過SparkContext提交)、部署模式、存儲體系、任務提交與運行、計算引擎等。
  • Spark SQL:提供SQL處理能力,便於熟悉關系型數據庫操作的project師進行交互查詢。此外。還為熟悉Hadoop的用戶提供Hive SQL處理能力。
  • Spark Streaming:提供流式計算處理能力,眼下支持Kafka、Flume、Twitter、MQTT、ZeroMQ、Kinesis和簡單的TCP套接字等數據源。此外,還提供窗體操作。
  • GraphX:提供圖計算處理能力,支持分布式, Pregel提供的API能夠解決圖計算中的常見問題。
  • MLlib:提供機器學習相關的統計、分類、回歸等領域的多種算法實現。其一致的API接口大大減少了用戶的學習成本。

Spark SQL、Spark Streaming、GraphX、MLlib的能力都是建立在核心引擎之上,如圖2-4。

技術分享

圖2-4 Spark各模塊依賴關系

1. Spark核心功能

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

  • SparkContext:通常而言。DriverApplication的運行與輸出都是通過SparkContext來完畢的,在正式提交Application之前,首先須要初始化SparkContext。SparkContext隱藏了網絡通信、分布式部署、消息通信、存儲能力、計算能力、緩存、測量系統、文件服務、Web服務等內容,應用程序開發人員僅僅須要使用SparkContext提供的API完畢功能開發。

    SparkContext內置的DAGScheduler負責創建Job。將DAG中的RDD劃分到不同的Stage。提交Stage等功能。內置的TaskScheduler負責資源的申請、任務的提交及請求集群對任務的調度等工作。

  • 存儲體系:Spark優先考慮使用各節點的內存作為存儲,當內存不足時才會考慮使用磁盤。這極大地降低了磁盤I/O,提升了任務運行的效率,使得Spark適用於實時計算、流式計算等場景。

    此外。Spark還提供了以內存為中心的高容錯的分布式文件系統Tachyon供用戶進行選擇。Tachyon可以為Spark提供可靠的內存級的文件共享服務。

  • 計算引擎:計算引擎由SparkContext中的DAGScheduler、RDD以及詳細節點上的Executor負責運行的Map和Reduce任務組成。

    DAGScheduler和RDD盡管位於SparkContext內部,可是在任務正式提交與運行之前將Job中的RDD組織成有向無關圖(簡稱DAG)、並對Stage進行劃分決定了任務運行階段任務的數量、叠代計算、shuffle等過程。

  • 部署模式:因為單節點不足以提供足夠的存儲及計算能力,所以作為大數據處理的Spark在SparkContext的TaskScheduler組件中提供了對Standalone部署模式的實現和Yarn、Mesos等分布式資源管理系統的支持。通過使用Standalone、Yarn、Mesos等部署模式為Task分配計算資源,提高任務的並發運行效率。

    除了可用於實際生產環境的Standalone、Yarn、Mesos等部署模式外,Spark還提供了Local模式和local-cluster模式便於開發和調試。

2. Spark擴展功能

為了擴大應用範圍。Spark陸續添加了一些擴展功能,主要包含:

  • Spark SQL:因為SQL具有普及率高、學習成本低等特點,為了擴大Spark的應用面。因此添加了對SQL及Hive的支持。

    Spark SQL的過程能夠總結為:首先使用SQL語句解析器(SqlParser)將SQL轉換為語法樹(Tree),而且使用規則運行器(RuleExecutor)將一系列規則(Rule)應用到語法樹,終於生成物理運行計劃並運行的過程。當中,規則包含語法分析器(Analyzer)和優化器(Optimizer)。Hive的運行過程與SQ類似。

  • Spark Streaming:Spark Streaming與Apache Storm類似。也用於流式計算。SparkStreaming支持Kafka、Flume、Twitter、MQTT、ZeroMQ、Kinesis和簡單的TCP套接字等多種數據輸入源。

    輸入流接收器(Receiver)負責接入數據。是接入數據流的接口規範。Dstream是Spark Streaming中全部數據流的抽象,Dstream能夠被組織為DStreamGraph。

    Dstream本質上由一系列連續的RDD組成。

  • GraphX:Spark提供的分布式圖計算框架。GraphX主要遵循總體同步並行計算模式(BulkSynchronous Parallell。簡稱BSP)下的Pregel模型實現。GraphX提供了對圖的抽象Graph,Graph由頂點(Vertex)、邊(Edge)及繼承了Edge的EdgeTriplet(加入了srcAttr和dstAttr用來保存源頂點和目的頂點的屬性)三種結構組成。GraphX眼下已經封裝了最短路徑、網頁排名、連接組件、三角關系統計等算法的實現。用戶能夠選擇使用。
  • MLlib:Spark提供的機器學習框架。機器學習是一門涉及概率論、統計學、逼近論、凸分析、算法復雜度理論等多領域的交叉學科。MLlib眼下已經提供了基礎統計、分類、回歸、決策樹、隨機森林、樸素貝葉斯、保序回歸、協同過濾、聚類、維數縮減、特征提取與轉型、頻繁模式挖掘、預言模型標記語言、管道等多種數理統計、概率論、數據挖掘方面的數學算法。

2.3.2 Spark模型設計

1. Spark編程模型

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

1) 用戶使用SparkContext提供的API(經常使用的有textFile、sequenceFile、runJob、stop等)編寫Driver application程序。

此外SQLContext、HiveContext及StreamingContext對SparkContext進行封裝,並提供了SQL、Hive及流式計算相關的API。

2) 使用SparkContext提交的用戶應用程序,首先會使用BlockManager和BroadcastManager將任務的Hadoop配置進行廣播。

然後由DAGScheduler將任務轉換為RDD並組織成DAG,DAG還將被劃分為不同的Stage。最後由TaskScheduler借助ActorSystem將任務提交給集群管理器(Cluster Manager)。

3) 集群管理器(ClusterManager)給任務分配資源,即將詳細任務分配到Worker上,Worker創建Executor來處理任務的執行。Standalone、YARN、Mesos、EC2等都能夠作為Spark的集群管理器。

技術分享

圖2-5 代碼運行過程


2.計算模型

RDD能夠看做是對各種數據計算模型的統一抽象,Spark的計算過程主要是RDD的叠代計算過程,如圖2-6。RDD的叠代計算過程很類似於管道。分區數量取決於partition數量的設定,每一個分區的數據僅僅會在一個Task中計算。

全部分區能夠在多個機器節點的Executor上並行運行。

技術分享

圖2-6 RDD計算模型


2.4 Spark基本架構

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

  • Cluster Manager:Spark的集群管理器,主要負責資源的分配與管理。集群管理器分配的資源屬於一級分配,它將各個Worker上的內存、CPU等資源分配給應用程序,可是並不負責對Executor的資源分配。

    眼下,Standalone、YARN、Mesos、EC2等都能夠作為Spark的集群管理器。

  • Worker:Spark的工作節點。對Spark應用程序來說,由集群管理器分配得到資源的Worker節點主要負責下面工作:創建Executor。將資源和任務進一步分配給Executor,同步資源信息給Cluster Manager。

  • Executor:運行計算任務的一線進程。

    主要負責任務的運行以及與Worker、Driver App的信息同步。

  • Driver App:client驅動程序,也能夠理解為client應用程序,用於將任務程序轉換為RDD和DAG,並與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核心部分的變化相對還是非常少的,假設對版本號不是過於追求,依舊能夠選擇本書。

技術分享

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

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

天貓:https://detail.tmall.com/item.htm?

spm=a220m.1000858.1000725.97.Jm1mNT&id=526150622300&areaId=131000&cat_id=2&rn=e5af4acfd6698f6d3e6a2e4fb543bb83&user_id=2086236400&is_b=1

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

ie=UTF8&me=&qid=1452505597&sr=8-1

Spark設計理念與基本架構