Spark生態系統解析及基於Redis的開源分佈式服務Codis

摘要:在第九期“七牛開發者最佳實踐日”上,陳超就Spark整個生態圈進行了講解,而劉奇則分享豌豆莢在Redis上的摸索和實踐。

1月24日,一場基於Spark和Redis組成的分佈式系統實踐分享由Spark資深佈道者陳超和豌豆莢資深系統架構師劉奇聯手打造。

陳超:Spark Ecosystem & Internals

 

陳超(@CrazyJvm),Spark佈道者

在分享中,陳超首先簡短的介紹了Spark社區在2014年的發展:目前Spark的發佈版本是1.2,整個2014年Spark共發佈了3個主要版本——1.0、1.1、1.2。隨後,陳超對Spark生態圈進行了詳細的分析:

Spark:What & Why?

Spark是一個非常快,並且普適性非常強的一個大數據處理引擎。談到Spark,首先就是一些常見特性:速度快、易用、通用和兼容Hadoop。首先通用,Spark可以支撐批處理、流計算、圖計算、機器學習等衆多應用場景;其次,與Hadoop良好的兼容。鑑於大多數的企業仍選用HDFS來存數據,Spark的設計與HDFS有着非常好的兼容性——假如數據存儲在HDFS,那麼不做任何數據遷移工作就可以直接使用Spark。

Spark vs. Hadoop

  

對於爲什麼要選擇Spark,如上圖所示,陳超從迭代計算和HDFS同批數據的多維度查詢兩個方面將之與Hadoop進行了對比:

  • 迭代計算。在這個場景下,Hadoop需要多次讀寫HDFS(磁盤),造成了大量的IO和序列化、反序列化等額外開銷。此外,每次寫HDFS都需要寫入3份,因此造成了備份方面的開銷。
  • HDFS同批數據的多維度查詢。對HDFS同一批數據做成百或上千維度查詢時,Hadoop每次做一個獨立的query,也就是每次都要從磁盤讀取這個數據。因爲每次都從磁盤中讀取同一組數據,效率顯然可以繼續提高。

而在這兩種場景中,Spark可以使用內存緩存中間/常用數據,從而在避免磁盤IO開銷的同時,還將大幅度提高性能。

Why Spark is so Fast?

Spark一直以快速著稱,那麼除下之前所說的內存,又是什麼特性讓Spark可以如此之快?在這裏,陳超提到了DAG(有向無環圖,下文詳細介紹)、Thread Model(線程模型)和Optimization(比如延遲調度)3個方面。

Thread Model。Hadoop基於進程模型,每次啓動一個task都需要新啓動一個子JVM進行計算,可能也會存在JVM Reuse,這裏即使避開JVM Reuse中存在的問題不談,每次JVM啓動時已經造成了不菲的開銷。而Spark在應用程序啓動時就啓動了線程池,所以任務的啓動開銷非常小。

Optimization——延遲調度。當任務下達到某臺主機時,恰好該主機的計算資源(CPU、內存等)已被耗盡,這個時候,Spark會採用延遲調度的機制,讓其等待一小會,而不是將該臺主機上需要計算的數據通過網絡傳輸到另外的主機上。使用這個機制,在計算數據體積非常大時,有着很大的優勢。 也就是所謂的“讓計算跟着數據走,而不是數據跟着計算走”。

Spark解析

伯克利數據分析協議棧 

 

其中包括:資源管理框架,Apache YARN、Apache Mesos;基於內存的分佈式文件系統,Tachyon;隨後是Spark,更上面則是實現各種功能的系統,比如機器學習MLlib庫,圖計算GraphX,流計算Spark Streaming。再上面比如:SparkR,分析師的最愛;BlinkDB,我們可以強迫它幾秒鐘內給我們查詢結果。

正是這個生態圈,讓Spark可以實現“one stack to rule them all”,它既可以完成批處理也可以從事流計算,從而避免了去實現兩份邏輯代碼。而整個Spark的理論基礎就是RDD:

RDD的核心理念

RDD可以想象爲一個個的partitions,退一步也可理解爲一個非常大的List(1,2,....9),使用3個Partion分別保存這個List的3個元素,而每個partition(或者split)都會有一個函數去計算。同時,RDD之間是可以相互依賴的。然後,可以爲Key-value RDD指定partitioner, RDD中的每個split也都有各自的preferred location。

最後一個preferred locations,這個理念存在於當下的衆多分佈式系統中,也就是計算跟着數據走。通常情況下,轉移計算的時間遠遠小於轉移數據的時間。對於Hadoop來說,因爲數據在磁盤中,磁盤本地性通常達到了頂峯,而對於Spark來講,因爲數據(可以)保存在內存中,所以內存本地性才具備最高優先級。

運行原理

 

上圖表述了Spark運行原理:rdd1、rdd2、rdd3等等一直轉換到另外一個RDD。需要注意的是,這裏面存在的是一個延遲的執行,也就是轉換不會立刻執行。Spark只會在元數據中記錄這個過程,但是不會真正的執行,這個要注意一點,只有在碰到action的時候纔會真正的去執行。這個時候需要注意的是,比如上圖RDD2所做的cache,這個操作同樣是lazy的,同樣在碰到action的時候纔會執行。就在這裏,坑出現了,即使persist與cache使用的是相同的接口,但是unpersist卻是eager的。從1.1版本開始,cache其實已經有了更安全的做法,但是涉及過多內核細節,這裏就不做多的解釋。

RDD的依賴性

 

narrow dependency和wide dependency是Spark中另外兩個重要的概念。對比後者,narrow dependency無論是在從容錯上,還是在執行效率上都佔有優勢。

ClusterManager:目前來講,在國內採用率更大的顯然是YARN。

Cluster overview

 

Sparkcontext,寫代碼時生成,並向ClusterManager請求資源。ClusterManager會負責連接到Worker Node取得資源,其中executor纔是task的真正執行者。這裏有三個需要注意的點:第一,ClusterManager是可插拔的,可以任意選擇;第二點,因爲driver program需求發送任務給Worker Node,因此提交任何的地方不要離Worker Node特別遠。第三點比較重要的一點,每個應用程序在每個Worker Node上都會有獨立的executor,並且不同應用程序的executor(間)是不可以共享數據的。

PS:YARN通過Container來封裝資源,因此在YARN中Worker對應的是Container。

調度

 

最初,Spark程序會隱式地建立一個邏輯上有向無環圖(DAG),隨後DAGScheduler會將DAG切分成一個個stage,隨後這些stage會被傳送給TaskSchedluer,之後再傳送給Worker上的excutor執行。其中excutor會以多線程的模式執行。

Shuffle

從理論上講,Spark Shuffle從未超過MapReduce,直到改完以後才OK。當下,Shuffle使用的是基於PULL的模式,中間文件會寫到磁盤,同時,在每個partition都會建立hash map。需要注意的是,在可以跨keys spill的同時,主機內存必須可以裝進單key-value。

在監控上,之前的版本中,只有當一個任務結束時,纔可以收集這個任務的運行數據,這點在當下的版本已被改進。

生態系統簡析

Spark Streaming:Spark Streaming實質上仍然是批處理,但是把之前大的批處理拆爲小的batch。同時,當下Spark Streaming已支持限流,當流量很大時,Spark可以擋住。此外,它還可以支持實時機器學習。在Spark Streaming中,數據丟失一般因爲兩種情況——worker failure和driver failure。在之前版本中,可能會存在小部分的數據丟失,而在1.2版本發佈後,reliable receiver模式保證了所有數據不會丟失,這點在Kafka的連接上非常適用。

MLlib:當下的算法已經非常豐富,包括分類、聚類、迴歸、協同過濾、降維等等。ML Pipeline可以大幅度的減少開發時間,它可以幫開發者打通數據收集、數據清理、特徵提取,模型訓練,測試、評估、上線整個流程。

Graphx:在這裏,Spark的優勢是既能處理表視圖,也能處理圖視圖。

Spark SQL:Spark生態圈中最火的組件,目的很簡單,用來支持SQL標準。對比Spark SQL,因爲基於MapReduce的進程模型,Hive中存在許多一直未修復的多線程bug。值得一提的是,Spark SQL的貢獻者中,一半以上是華人。

 

Tachyon可以支撐幾乎所有框架

Tachyon:內存分佈式系統,讓不同的Job或者框架分享數據,從而繞過HDFS,以更快地速度執行。同時,它還可以避免任務失敗時的數據重算。最後,Tachyon可以讓系統避免多次GC。

SparkR:讓R語言調用Spark。原理是Spark Context通過JNI調用Java Spark Context,隨後通過Worker上的Excutor調用R的shell來執行。現在存在的問題是,每次task執行時都需要啓動R shell,所以還亟待優化。

 

BlinkDB,一個任性的數據庫

BlinkDB:很任性的一個數據庫,允許操作者帶着time bounds或者error bounds去查。原理是在原始數據上維護一組多維樣本,當然其中還需要一個動態的樣本選擇策略。

JobServer:提供了一個RESTful接口來提交和管理Apache Spark job、jars及job contexts,即Spark as a Service。  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章