Spark 介紹

聲明:
本文轉自我的個人博客,有興趣的可以查看原文。
轉發請註明來源。

最近工作開始接觸Spark,本系列博客可以作爲學習思考的紀錄。

如果無特殊說明,均針對Spark 2.2 。

1. Spark 介紹

1.1 Spark 是什麼

Apache Spark is a fast and general engine for large-scale data processing.

Spark 官網將Spark 定義爲一個大型可擴展數據的快速通用處理引擎。

首先,Spark 採用了先進的DAG執行引擎,支持循環數據流和內存計算,使得 Spark 速度更快,在內存中的速度是Hadoop MR的百倍,在磁盤上的速度是Hadoop MR的十倍(官網數據) 。

其次,Spark 是一個通用的處理引擎。Spark 被設計用來做批處理、迭代運算、交互式查詢、流處理、機器學習等。

另外,Spark 易用,可以用Scala、Java、Python、R等快速開發分佈式應用,Spark 提供了大量的高級API,方便開發(對比MapReduce...)。

最後,Spark 集成了多種數據源,並且可以通過Yarn、Mesos、Standalone(Spark 提供的部署方式)等各種模式運行。

1.2 爲什麼需要Spark

在Spark 之前,我們已經有了Hadoop,Hadoop 作爲大數據時代企業首選技術,方興未艾,我們爲什麼還需要Spark 呢?

我的理解是,Hadoop 對某些工作並不是最優的選擇:

  1. 中間輸出到磁盤,會產生較高的延遲。
  2. 缺少對迭代運算的支持。

總的來說,Hadoop 設計得比較適合處理離線數據,在實時查詢、迭代計算方面存在不足,而業界對實時查詢和迭代計算有着越來越多的需求。Spark 的出現正好能解決這些問題,快速、易用、通用,而且對有效支持Hadoop。

1.3 Spark 核心生態圈與重要擴展

上圖是一個比較常見的以 Spark 爲核心的大數據處理框架。

其中,Spark Core 提供了 Spark 中的任務調度、內存管理、錯誤恢復、與存儲系統交互等基本功能,而且,Spark Core 定義了RDDs(resilient distributed datasets,彈性分佈式數據集,是Spark 的核心抽象)和操作RDDs的各種APIs。

基於Spark Core,提供六大核心擴展。Spark SQL 提供交互式SQL查詢功能;Spark 2.0 引入了 Structured Streaming,Structured Streaming 是建立在Spark SQL 之上的可擴展、高容錯的流處理引擎;MLlib 提供機器學習;GraphX提供圖計算服務;Spark Streaming 基於 Spark 核心 API 提供可擴展、高吞吐量、高容錯的實時流處理;SparkR 是Spark的一個R開發包。這些核心擴展,除了Structured Streaming,都基於Spark 核心API處理問題,方法幾乎是通用的,處理的數據可共享,大大提高了數據集成的靈活性。

Spark 可擴展至大量節點,爲實現這個目的並最大程度的保證靈活性,Spark 支持多種資源管理器(cluster manageers),包括 Yarn、Mesos 以及 Spark 提供的Standalone,另外,local模式主要用於開發測試。

最後,Spark 可支持多種數據集,包括本地文件系統、HDFS、Hbase、Cassandra等。

可見,Spark 提供了一站式數據處理能力,這是大數據時代相對很多專用引擎來說所不具備的。

2. Spark核心概念

2.1 基本抽象

Spark 基於兩個抽象,分別是RDDs和Shared Variables。

2.1.1 RDDs

Spark 提出了一種分佈式的數據抽象,稱爲 RDDs(resilient distributed datasets,彈性分佈式數據集),是一個可並行處理且支持容錯的數據集,同時,也是一個受限的數據集,RDDs是一個只讀的、記錄分區的數據集,僅支持transformation和action兩種操作,這些受限,使得RDDs可以以較小的成本實現高容錯性、可靠性。

RDDs有兩種創建方式,一種是從外部數據源創建,另一種是從其它RDDs transform而來。transformation 是對RDDs進行確定性的操作,輸入是RDDs,輸出RDDs。action 是嚮應用程序返回值或者將結果寫到外部存儲。

最後,transformation具有 LAZY 的特點,當在RDDs上進行一次transformation時,並不會立即執行,只會在進行action時,前面的transformation纔會真正執行。這個特點,被 Spark 用來優化整個工作鏈路,可以有效減少網絡溝通、傳輸時間(大數據處理過程中,網絡傳輸可以說是最大的性能殺手),從而大幅提高運行速度。

舉個例子,我們具有如下代碼:

lines = spark.textFile("hdfs://...")
errors = lines.filter(_.startsWith("ERROR"))
errors.cache()
errors.count()

第一行,讀取外部數據源,生成一個RDDs;第二行,在RDDs lines上做了一次transformation運算 filter,取出以"ERROR" 開頭的所有行,得到一個新的RDDs errors;第三行,緩存RDDs;第四行,在errors 上執行action,得到errors的行數。在整個過程中,只有在執行count()時,纔會真正開始讀取數據、過濾、緩存、計算行數。

如上圖所示,展示了整個過程,稱爲lineage,根據lineage,可以從具體的物理數據,計算出相應的結果。在Spark中,實現容錯就是根據 lineage,當某個分區失敗後,重新進行一次計算即可,而不是採用檢查點、回滾等代價高昂的方式。同時,lineage 是Spark用來優化計算流程的依據。

最後,Spark 支持RDD persist/cache。當第一次執行action時,會將調用 persist()cache()的RDD緩存下來,在下次進行action操作時,直接使用緩存數據,這使得後邊的action操作速度更快,在迭代運算或交互運算中,緩存使用較多。

2.1.2 Shared variables

在Spark中,具體的運算都在集羣的節點上進行,這些運算操作的是從driver program 拷貝的變量的副本,且不會更新driver program上的變量,而要實現多任務共享的可讀寫變量會非常低效,Spark在這方面僅支持受限的共享變量。

Broadcast variables

廣播變量是支持每臺機器持有而不是每個task持有的只讀變量,比如,給每臺機器分發大型的輸入數據集就會變得更加高效,同時,Spark 採用了高效的分發算法來實現廣播變量的分發。

Accumulators

累加器是隻被相關變量累加的變量,可以用於計數(sum)。在Spark中,原生支持數值類型的累加器,並且可以自己實現對其他類型的累加器。

3. 總結

本文主要簡單介紹Spark的基礎,包括Spark的基本介紹與Spark的核心概念。在下一篇,介紹如何搭建Spark項目。

4. 參閱

Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing

官方文檔

Learning Spark

Spark核心技術與高級應用

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