聲明:
本文轉(zhuǎn)自我的個(gè)人博客拥褂,有興趣的可以查看原文镇匀。
轉(zhuǎn)發(fā)請(qǐng)注明來源。
最近工作開始接觸Spark免钻,本系列博客可以作為學(xué)習(xí)思考的紀(jì)錄彼水。
如果無特殊說明,均針對(duì)Spark 2.2 伯襟。
1. Spark 介紹
1.1 Spark 是什么
Apache Spark is a fast and general engine for large-scale data processing.
Spark 官網(wǎng)將Spark 定義為一個(gè)大型可擴(kuò)展數(shù)據(jù)的快速和通用處理引擎猿涨。
首先,Spark 采用了先進(jìn)的DAG執(zhí)行引擎姆怪,支持循環(huán)數(shù)據(jù)流和內(nèi)存計(jì)算,使得 Spark 速度更快,在內(nèi)存中的速度是Hadoop MR的百倍稽揭,在磁盤上的速度是Hadoop MR的十倍(官網(wǎng)數(shù)據(jù)) 俺附。
其次,Spark 是一個(gè)通用的處理引擎溪掀。Spark 被設(shè)計(jì)用來做批處理事镣、迭代運(yùn)算、交互式查詢揪胃、流處理璃哟、機(jī)器學(xué)習(xí)等。
另外喊递,Spark 易用随闪,可以用Scala、Java骚勘、Python铐伴、R等快速開發(fā)分布式應(yīng)用,Spark 提供了大量的高級(jí)API俏讹,方便開發(fā)(對(duì)比MapReduce...)当宴。
最后,Spark 集成了多種數(shù)據(jù)源泽疆,并且可以通過Yarn户矢、Mesos、Standalone(Spark 提供的部署方式)等各種模式運(yùn)行殉疼。
1.2 為什么需要Spark
在Spark 之前逗嫡,我們已經(jīng)有了Hadoop,Hadoop 作為大數(shù)據(jù)時(shí)代企業(yè)首選技術(shù)株依,方興未艾驱证,我們?yōu)槭裁催€需要Spark 呢?
我的理解是恋腕,Hadoop 對(duì)某些工作并不是最優(yōu)的選擇:
- 中間輸出到磁盤抹锄,會(huì)產(chǎn)生較高的延遲。
- 缺少對(duì)迭代運(yùn)算的支持荠藤。
總的來說伙单,Hadoop 設(shè)計(jì)得比較適合處理離線數(shù)據(jù),在實(shí)時(shí)查詢哈肖、迭代計(jì)算方面存在不足吻育,而業(yè)界對(duì)實(shí)時(shí)查詢和迭代計(jì)算有著越來越多的需求。Spark 的出現(xiàn)正好能解決這些問題淤井,快速布疼、易用摊趾、通用,而且對(duì)有效支持Hadoop游两。
1.3 Spark 核心生態(tài)圈與重要擴(kuò)展
上圖是一個(gè)比較常見的以 Spark 為核心的大數(shù)據(jù)處理框架砾层。
其中,Spark Core 提供了 Spark 中的任務(wù)調(diào)度贱案、內(nèi)存管理肛炮、錯(cuò)誤恢復(fù)、與存儲(chǔ)系統(tǒng)交互等基本功能宝踪,而且侨糟,Spark Core 定義了RDDs(resilient distributed datasets,彈性分布式數(shù)據(jù)集瘩燥,是Spark 的核心抽象)和操作RDDs的各種APIs秕重。
基于Spark Core,提供六大核心擴(kuò)展颤芬。Spark SQL 提供交互式SQL查詢功能悲幅;Spark 2.0 引入了 Structured Streaming,Structured Streaming 是建立在Spark SQL 之上的可擴(kuò)展站蝠、高容錯(cuò)的流處理引擎汰具;MLlib 提供機(jī)器學(xué)習(xí);GraphX提供圖計(jì)算服務(wù)菱魔;Spark Streaming 基于 Spark 核心 API 提供可擴(kuò)展留荔、高吞吐量、高容錯(cuò)的實(shí)時(shí)流處理澜倦;SparkR 是Spark的一個(gè)R開發(fā)包聚蝶。這些核心擴(kuò)展,除了Structured Streaming藻治,都基于Spark 核心API處理問題碘勉,方法幾乎是通用的,處理的數(shù)據(jù)可共享桩卵,大大提高了數(shù)據(jù)集成的靈活性验靡。
Spark 可擴(kuò)展至大量節(jié)點(diǎn),為實(shí)現(xiàn)這個(gè)目的并最大程度的保證靈活性雏节,Spark 支持多種資源管理器(cluster manageers)胜嗓,包括 Yarn、Mesos 以及 Spark 提供的Standalone钩乍,另外辞州,local模式主要用于開發(fā)測(cè)試。
最后寥粹,Spark 可支持多種數(shù)據(jù)集变过,包括本地文件系統(tǒng)埃元、HDFS、Hbase牵啦、Cassandra等亚情。
可見妄痪,Spark 提供了一站式數(shù)據(jù)處理能力哈雏,這是大數(shù)據(jù)時(shí)代相對(duì)很多專用引擎來說所不具備的。
2. Spark核心概念
2.1 基本抽象
Spark 基于兩個(gè)抽象衫生,分別是RDDs和Shared Variables裳瘪。
2.1.1 RDDs
Spark 提出了一種分布式的數(shù)據(jù)抽象,稱為 RDDs(resilient distributed datasets罪针,彈性分布式數(shù)據(jù)集)彭羹,是一個(gè)可并行處理且支持容錯(cuò)的數(shù)據(jù)集,同時(shí)泪酱,也是一個(gè)受限的數(shù)據(jù)集派殷,RDDs是一個(gè)只讀的、記錄分區(qū)的數(shù)據(jù)集墓阀,僅支持transformation和action兩種操作毡惜,這些受限,使得RDDs可以以較小的成本實(shí)現(xiàn)高容錯(cuò)性斯撮、可靠性经伙。
RDDs有兩種創(chuàng)建方式,一種是從外部數(shù)據(jù)源創(chuàng)建勿锅,另一種是從其它RDDs transform而來帕膜。transformation
是對(duì)RDDs進(jìn)行確定性的操作,輸入是RDDs溢十,輸出RDDs垮刹。action
是向應(yīng)用程序返回值或者將結(jié)果寫到外部存儲(chǔ)。
最后张弛,transformation具有 LAZY 的特點(diǎn)荒典,當(dāng)在RDDs上進(jìn)行一次transformation時(shí),并不會(huì)立即執(zhí)行乌庶,只會(huì)在進(jìn)行action時(shí)种蝶,前面的transformation才會(huì)真正執(zhí)行。這個(gè)特點(diǎn)瞒大,被 Spark 用來優(yōu)化整個(gè)工作鏈路螃征,可以有效減少網(wǎng)絡(luò)溝通、傳輸時(shí)間(大數(shù)據(jù)處理過程中透敌,網(wǎng)絡(luò)傳輸可以說是最大的性能殺手)盯滚,從而大幅提高運(yùn)行速度踢械。
舉個(gè)例子,我們具有如下代碼:
lines = spark.textFile("hdfs://...")
errors = lines.filter(_.startsWith("ERROR"))
errors.cache()
errors.count()
第一行魄藕,讀取外部數(shù)據(jù)源内列,生成一個(gè)RDDs;第二行背率,在RDDs lines上做了一次transformation運(yùn)算 filter话瞧,取出以"ERROR" 開頭的所有行,得到一個(gè)新的RDDs errors寝姿;第三行交排,緩存RDDs;第四行饵筑,在errors 上執(zhí)行action埃篓,得到errors的行數(shù)。在整個(gè)過程中根资,只有在執(zhí)行count()時(shí)架专,才會(huì)真正開始讀取數(shù)據(jù)、過濾玄帕、緩存部脚、計(jì)算行數(shù)。
如上圖所示桨仿,展示了整個(gè)過程睛低,稱為lineage
,根據(jù)lineage服傍,可以從具體的物理數(shù)據(jù)钱雷,計(jì)算出相應(yīng)的結(jié)果。在Spark中吹零,實(shí)現(xiàn)容錯(cuò)就是根據(jù) lineage罩抗,當(dāng)某個(gè)分區(qū)失敗后,重新進(jìn)行一次計(jì)算即可灿椅,而不是采用檢查點(diǎn)套蒂、回滾等代價(jià)高昂的方式。同時(shí)茫蛹,lineage 是Spark用來優(yōu)化計(jì)算流程的依據(jù)操刀。
最后,Spark 支持RDD persist/cache婴洼。當(dāng)?shù)谝淮螆?zhí)行action時(shí)骨坑,會(huì)將調(diào)用 persist()
或cache()
的RDD緩存下來,在下次進(jìn)行action操作時(shí),直接使用緩存數(shù)據(jù)欢唾,這使得后邊的action操作速度更快且警,在迭代運(yùn)算或交互運(yùn)算中,緩存使用較多礁遣。
2.1.2 Shared variables
在Spark中斑芜,具體的運(yùn)算都在集群的節(jié)點(diǎn)上進(jìn)行,這些運(yùn)算操作的是從driver program 拷貝的變量的副本祟霍,且不會(huì)更新driver program上的變量杏头,而要實(shí)現(xiàn)多任務(wù)共享的可讀寫變量會(huì)非常低效,Spark在這方面僅支持受限的共享變量浅碾。
Broadcast variables
廣播變量是支持每臺(tái)機(jī)器持有而不是每個(gè)task持有的只讀變量大州,比如续语,給每臺(tái)機(jī)器分發(fā)大型的輸入數(shù)據(jù)集就會(huì)變得更加高效垂谢,同時(shí),Spark 采用了高效的分發(fā)算法來實(shí)現(xiàn)廣播變量的分發(fā)疮茄。
Accumulators
累加器是只被相關(guān)變量累加的變量滥朱,可以用于計(jì)數(shù)(sum)。在Spark中力试,原生支持?jǐn)?shù)值類型的累加器徙邻,并且可以自己實(shí)現(xiàn)對(duì)其他類型的累加器。
3. 總結(jié)
本文主要簡(jiǎn)單介紹Spark的基礎(chǔ)畸裳,包括Spark的基本介紹與Spark的核心概念缰犁。在下一篇,介紹如何搭建Spark項(xiàng)目怖糊。
4. 參閱
Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster Computing