Spark Streaming精進(jìn)之前必須了解的基本概念
Spark整體介紹
Spark是一個(gè)快速的,多用途的計(jì)算系統(tǒng)。這是來(lái)自官網(wǎng)的自我介紹。一般敢自稱系統(tǒng)的都是有兩把刷子的,況且還是多用途的計(jì)算系統(tǒng)。Spark計(jì)算系統(tǒng)包含如下功能組件
Spark Core: Spark的核心功能模塊。
Spark SQL: 用于處理結(jié)構(gòu)化數(shù)據(jù)。
MLlib:用于機(jī)器學(xué)習(xí)。
GraphX:用于圖像處理。
Spark Streaming:用于處理實(shí)時(shí)數(shù)據(jù)流。
包含如此多的功能,自稱多功能計(jì)算系統(tǒng)也是可以的。這篇文章幫大家梳理一下學(xué)習(xí)Spark Streaming過(guò)程中可能會(huì)讓你產(chǎn)生困惑的基本概念。
RDD
Spark Core 是 Spark的核心模塊,這個(gè)模塊提供了一個(gè)核心概念叫做RDD(resilient distributed dataset)。你可以簡(jiǎn)單的把它理解成一個(gè)數(shù)據(jù)片段集合,你要處理的源數(shù)據(jù)文件可以分解成很多個(gè)RDD。Spark為RDD提供了兩種類型的操作,一種是transformations,一種是 action。
transformations:如果一個(gè)RDD經(jīng)過(guò)某種操作之后,生成一個(gè)新的RDD,那么這個(gè)操作就是transaction的。比如,map,flatMap,filter等。 action:對(duì)一個(gè)RDD進(jìn)行計(jì)算操作,以生成某種結(jié)果,比如reduce,count等操作。
注意:所有的transformations都是Lazy的,也就是說(shuō)只有碰到action操作的時(shí)候才會(huì)執(zhí)行前面的transformations操作。
DStream
Spark Streaming 是用來(lái)處理流式數(shù)據(jù)的,假設(shè)我們規(guī)定每隔一秒鐘(通過(guò)duration設(shè)置)取一次數(shù)據(jù),那么這段時(shí)間內(nèi)積贊的數(shù)據(jù)就稱為一個(gè)batch,里面的數(shù)據(jù)就用DStream表示。從編寫(xiě)代碼的角度來(lái)看,你可以把DStream和RDD同等對(duì)待,因?yàn)樗麄兊乃阕硬僮鞫际且粯拥摹5撬麄兊臄?shù)據(jù)結(jié)構(gòu)還是有著本質(zhì)不同的,我們可以把DStream簡(jiǎn)單的理解成是RDD加上了時(shí)間戳。如下圖
DAG
Spark 使用DAG 進(jìn)行數(shù)據(jù)建模,DAG 被稱為有向無(wú)環(huán)圖,有向無(wú)環(huán)圖的定義是這樣的 "在圖論中,如果一個(gè)有向圖從任意頂點(diǎn)出發(fā)無(wú)法經(jīng)過(guò)若干條邊回到該點(diǎn),則這個(gè)圖是一個(gè)有向無(wú)環(huán)圖(DAG,directed acyclic graph)",我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)感受一下,Spark是如何使用DAG建模的。
下面的代碼可以完成一段文本內(nèi)容的各個(gè)單詞的數(shù)量統(tǒng)計(jì)。
- var textFile = sc.textFile(args[1]);
- var result = textFile.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey((a, b) => a + b);
- result.saveAsTextFile(args[2]);
上面這段代碼可以用下面這個(gè)圖表示
這就是一個(gè)簡(jiǎn)單的DAG模型,數(shù)據(jù)按照方向流動(dòng),再也回不到原點(diǎn)。Spark Streaming將這個(gè)DAG模型,不斷的應(yīng)用到每一個(gè)Batch里面的數(shù)據(jù)中。大家可以把DAG模型理解成類,它是數(shù)據(jù)處理的模版,而每個(gè)Batch里面的數(shù)據(jù)就是不同的實(shí)例對(duì)象。
Job,Stage,Task
Spark應(yīng)用程序啟動(dòng)之后,我們會(huì)利用Spark提供的監(jiān)控頁(yè)面來(lái)查看程序的運(yùn)行情況。在頁(yè)面上會(huì)看到Job,Stage,Task等內(nèi)容展示,如果不理解他們代表什么意思,那么Spark好心好意提供的監(jiān)控頁(yè)面對(duì)我們來(lái)說(shuō)就毫無(wú)意義。 下面給大家簡(jiǎn)單說(shuō)一下這些概念到底什么意思,以及他們之間的關(guān)系。
先來(lái)看個(gè)圖
從圖中可以看出,一個(gè)Application被分解成多個(gè)Job,每個(gè)Job又分解成多個(gè)Stage,Stage又會(huì)分解成多個(gè)Task,而Task是任務(wù)運(yùn)行的最小單元,最終會(huì)被Executor執(zhí)行。
Application:簡(jiǎn)單的說(shuō)就是我們寫(xiě)的應(yīng)用代碼,啟動(dòng)起來(lái)之后就是一個(gè)Application。
Job:由Spark的action算子觸發(fā)。也就是每遇到一個(gè)action算子就會(huì)觸發(fā)一個(gè)Job任務(wù),這個(gè)時(shí)候就會(huì)執(zhí)行前面的一系列transformations操作。
Stage:Job任務(wù)會(huì)繼續(xù)分解成Stage,Stage是根據(jù)DAG的寬窄依賴來(lái)劃分,也就是RDD之間的依賴關(guān)系。從后往前,每遇到一個(gè)寬依賴就劃分為一個(gè)Stage。
寬依賴(Shuffle/Wide Dependency):父RDD的分區(qū)和子RDD的分區(qū)是一對(duì)多或者多對(duì)多的關(guān)系。比如groupByKey,reduceByKey,join等操作
窄依賴(Narrow Dependency):父RDD的分區(qū)和子RDD的分區(qū)的關(guān)系是一對(duì)一或者多對(duì)一的關(guān)系,比如map,flatmap,filter等操作。
寬窄依賴的定義可以用如下圖,形象的展示。
拿文章開(kāi)頭的單詞統(tǒng)計(jì)程序?yàn)槔?,Stage劃分情況應(yīng)該是這樣的。
task:Stage包含很多Task,每個(gè)Task會(huì)執(zhí)行Stage中包含的算子。
以上就是Spark精進(jìn)之路上必須了解的基本概念,希望對(duì)各位有幫助。