我們從這節(jié)課開(kāi)始,講Spark的內(nèi)核俊啼,英文叫做Spark Core撩扒,在講Spark Core之前我們先講一個(gè)重要的概念,RDD吨些,
我們Spark所有的計(jì)算,都是基于RDD來(lái)計(jì)算的炒辉,我們所有的計(jì)算都是通過(guò)RDD來(lái)計(jì)算的豪墅,那問(wèn)題來(lái)了,RDD到底是什么黔寇?
resilient 美 [r?'z?l??nt]
adj. 彈回的偶器,有彈力的
adj. 能復(fù)原的;有復(fù)原力的
distributed 美 [d?'str?bj?t?d]
adj. 分布式的,分散式的
dataset 美 ['det?]美 [s?t]
數(shù)據(jù)集合
這是我們Spark最核心的數(shù)據(jù)結(jié)構(gòu)屏轰,我們所有的開(kāi)發(fā)編程颊郎,都是圍繞這這個(gè)RDD來(lái)展開(kāi)的
根據(jù)這個(gè)名字,我們猜猜這個(gè)RDD是什么意思霎苗?
這個(gè)詞是個(gè)什么詞性姆吭,是個(gè)名詞對(duì)吧?Dataset唁盏,數(shù)據(jù)集内狸,我們學(xué)習(xí)Java的時(shí)候?qū)W過(guò)這個(gè)Set把,他是一個(gè)集合對(duì)吧厘擂,data名詞昆淡,給這個(gè)Set這個(gè)當(dāng)做定語(yǔ)對(duì)吧?說(shuō)明這是一個(gè)數(shù)據(jù)的集合對(duì)吧刽严?Resilient形容詞昂灵,形容這個(gè)數(shù)據(jù)集,是有彈性的舞萄,彈性什么意思眨补,可以伸縮對(duì)吧,你拉他一下鹏氧,他自己可以回到原來(lái)的狀態(tài)對(duì)嗎渤涌?他把這個(gè)定語(yǔ)放在這什么意思,說(shuō)明我們這個(gè)數(shù)據(jù)集是能夠自我修復(fù)對(duì)吧把还?
能夠自我修復(fù)是什么意思实蓬?
《Learning Spark:Lightning-fast Data Analysis》一書(shū)中解釋“彈性”是指在任何時(shí)候都能進(jìn)行重算。這樣當(dāng)集群中的一臺(tái)機(jī)器掛掉而導(dǎo)致存儲(chǔ)在其上的RDD丟失后吊履,Spark還可以重新計(jì)算出這部分的分區(qū)的數(shù)據(jù)安皱。但用戶(hù)感覺(jué)不到這部分的內(nèi)容丟失過(guò)。這樣RDD數(shù)據(jù)集就像塊帶有彈性的海綿一樣艇炎,不管怎樣擠壓(分區(qū)遭到破壞)都是完整的酌伊。
分布式是什么意思?
分布式對(duì)應(yīng)的就是單機(jī)的系統(tǒng)
那我們說(shuō)分布式的優(yōu)點(diǎn)是什么白鹤佟居砖?其實(shí)優(yōu)點(diǎn)還是有很多的,但最顯著的優(yōu)點(diǎn)就是有3個(gè)驴娃,他可以負(fù)載均衡是嗎奏候?當(dāng)我們的計(jì)算資源,緊缺時(shí)唇敞,可以使用其他的計(jì)算資源對(duì)嗎蔗草?他可以容錯(cuò)對(duì)嗎咒彤?當(dāng)我們一臺(tái)機(jī)器的數(shù)據(jù)壞掉了,還有另外一個(gè)機(jī)器做副本咒精,所以還可以找回來(lái)對(duì)嗎镶柱?擴(kuò)展性強(qiáng)對(duì)嗎?我們可以提供更多的機(jī)器模叙,更多的計(jì)算資源歇拆,更多的存儲(chǔ)資源,為整個(gè)分布式系統(tǒng)提供水平的線性擴(kuò)展向楼,對(duì)嗎查吊?
那我們現(xiàn)在明白這個(gè)RDD是什么了嗎?
大家還記得我們之前寫(xiě)的WordCount是怎么寫(xiě)的嗎湖蜕?
sc.這個(gè)sc是Spark上下文這么一個(gè)對(duì)象逻卖,SparkContext
sc.textFile這是讀一個(gè)文件,Spark會(huì)將這個(gè)文件昭抒,加載到RDD里面去捌酪病?
sc.textFile返回的是一個(gè)RDD對(duì)象 是吧灭返?
然后rdd.flatMap.map.reduceByKey 對(duì)吧然后foreach打印一下對(duì)吧盗迟?
這種...是鏈?zhǔn)骄幊探Y(jié)構(gòu)的一種計(jì)算,啥叫鏈?zhǔn)骄幊探Y(jié)構(gòu)呢熙含,就是flatMap的返回對(duì)象其實(shí)還是一個(gè)rdd對(duì)吧罚缕?
所以說(shuō)一切都是基于RDD的
現(xiàn)在我們知道了RDD是彈性分布式數(shù)據(jù)集,
那么他有5大特性怎静,我們說(shuō)RDD的5大特性邮弹,我們可以把他理解為RDD的5個(gè)屬性
這5大特性,我們用畫(huà)圖的方式來(lái)講一下
這5大特性蚓聘,我講完之后你們可能會(huì)有一些疑問(wèn)
到時(shí)候你們可以來(lái)問(wèn)我腌乡,但我不一定會(huì)回答,為什么夜牡?因?yàn)殡S著課程的深入与纽,這5個(gè)特性都會(huì)給你們講明白,這就叫循序漸進(jìn)塘装,知道嗎急迂?
如果你們現(xiàn)在問(wèn)的所有問(wèn)題我都去回答的話,太深入的東西你們肯定理解不了蹦肴,能明白我的意思嗎袋毙?
大家不用擔(dān)心,對(duì)基礎(chǔ)比較好的東西冗尤,我在PPT的最后听盖,給大家提供個(gè)鏈接,這是我們這個(gè)系列課程最后一天要給大家講的內(nèi)容裂七,有余力的同學(xué)可以深入研究一下
我們用畫(huà)圖的方式來(lái)講這5大特性皆看,
比如說(shuō)我們Spark現(xiàn)在要計(jì)算的數(shù)據(jù),是放到HDFS上面
比如我們現(xiàn)在要處理的這個(gè)文件由3個(gè)Block組成的
那么這個(gè)文件是不是可能在不同的節(jié)點(diǎn)上背零?
然后我要用Spark來(lái)計(jì)算一下這個(gè)文件腰吟,首先是不是要把這個(gè)文件加載到Spark里面來(lái)啊徙瓶?
哪一行代碼毛雇?我們用sc.textFile(“hdfs://hostname:port/path”)
我們調(diào)用了sc.textFite方法,他給我們返回回來(lái)一個(gè)rdd是吧侦镇?
這個(gè)RDD里面是有一系列的分區(qū)的灵疮,我們剛才說(shuō)了,RDD是不是一個(gè)彈性分布式數(shù)據(jù)集翱欠薄震捣?
他是一個(gè)分布式的數(shù)據(jù)集,我們可以和hdfs里面的概念和這個(gè)類(lèi)比闹炉,Hadoop里面是不是有block拜镉?hdfs之所以是分布式渣触,是不是因?yàn)槔锩嬗衕dfs里面叫做block的存儲(chǔ)單元跋劭谩?如果hdfs里面沒(méi)有存儲(chǔ)單元嗅钻,那他能完成分布式嗎皂冰?如果沒(méi)有這個(gè)存儲(chǔ)單元這么一說(shuō),一個(gè)大文件啊犬,要么存在A機(jī)器灼擂,要么存在B機(jī)器。如果一臺(tái)機(jī)器存不下觉至,那我們只能去擴(kuò)展這臺(tái)機(jī)器的硬盤(pán)對(duì)嗎剔应?我們想實(shí)現(xiàn)分布式存儲(chǔ),我們首先需要把一個(gè)大文件拆成很多小文件语御,通過(guò)索引的方式知道文件的先后順序和存儲(chǔ)位置峻贮,就可以實(shí)現(xiàn)分布式存儲(chǔ)系統(tǒng)了,對(duì)嗎应闯?
那我們RDD他也是分布式的纤控,是不是也需要類(lèi)似Block這樣的分布式的存儲(chǔ)單元啊碉纺?那我們Spark里面就叫他是Partition
那到底有多少個(gè)partition是有誰(shuí)來(lái)決定的船万?那么到底有多少個(gè)Partition是由我要讀取的這個(gè)file的Block數(shù)量決定的刻撒?能理解嗎?
那再跟大家深入的說(shuō)一下耿导,這個(gè)textFile是一個(gè)讀文件的方法
它的底層封裝的是MR讀文件的方法声怔,Spark本身是沒(méi)有讀文件的方法的,他調(diào)用的是MapReduce讀文件的方法
那我們mapreduce讀文件就有特點(diǎn)了舱呻,首先他要干嘛醋火?
MR讀文件之前是不是要先劃分split
那準(zhǔn)確的來(lái)說(shuō),每一個(gè)Partition是和我們Split對(duì)應(yīng)的對(duì)嗎箱吕?
又因?yàn)镾plit和Block一般情況下是一樣的芥驳,所以Partition的數(shù)量和Block的數(shù)量是一樣的
那一般情況下就把partition的個(gè)數(shù)記成和block數(shù)量是一樣的
hadoop里面的Split數(shù)量是如何決定的?
【Hadoop】三句話告訴你 mapreduce 中MAP進(jìn)程的數(shù)量怎么控制茬高?
然后我們繼續(xù)畫(huà)圖
我們讀完文件兆旬,通過(guò)flatmap.map.reduceByKey一系列算子的轉(zhuǎn)換,完成了我們WordCount這個(gè)業(yè)務(wù)
新的RDD都是依賴(lài)上級(jí)的RDD的雅采,
我們的resultRDD是依賴(lài)mapRDD的
mapRDD是依賴(lài)flatMapRDD的
flatMapRDD是依賴(lài)readFileRDD
我們繼續(xù)畫(huà)圖爵憎,我們之前編程的時(shí)候是針對(duì)RDD的方法,其實(shí)通過(guò)我們之后的講解婚瓜,大家就會(huì)知道宝鼓,我們的textFile算子,flatMap算子巴刻,map算子愚铡,reduceByKey算子都是作用在partition上的,所以我們這個(gè)圖要修改一下
我們繼續(xù)來(lái)講第四個(gè)特性
在什么階段有分區(qū)器昂恪沥寥?在Suffle階段才會(huì)有分區(qū)器,
分區(qū)器的作用是什么柠座?決定我這一條記錄是寫(xiě)在哪個(gè)磁盤(pán)小文件上
那什么是kv格式的RDD我們畫(huà)圖演示一下
我們這個(gè)flatMepRDD是基于readFileRDD的邑雅,readFileRDD里面的partition可能是在不同的Block節(jié)點(diǎn)上面進(jìn)行存儲(chǔ)的,那要是基于RDD進(jìn)行計(jì)算妈经,是要啟動(dòng)task任務(wù)淮野,那我這個(gè)Task任務(wù)分發(fā)到哪個(gè)節(jié)點(diǎn)上是最好的呢?是不是分發(fā)到數(shù)據(jù)所在的節(jié)點(diǎn)上是最好的按蹬荨骤星?這就符合我們大數(shù)據(jù)的計(jì)算原則,移動(dòng)計(jì)算而不移動(dòng)數(shù)據(jù)
第五個(gè)這個(gè)特性就是說(shuō)爆哑,這個(gè)readFileRDD會(huì)對(duì)外提供一個(gè)接口洞难,我調(diào)用這個(gè)接口我就知道每個(gè)Partition所在的節(jié)點(diǎn),和具體的位置
知道他的位置以后揭朝,可以參考這個(gè)位置队贱,分發(fā)Task去執(zhí)行色冀,執(zhí)行完之后就得到flatMap這個(gè)RDD了
答疑時(shí)間,哪不理解
有同學(xué)說(shuō)第五個(gè)特性不理解柱嫌,
rdd可以提供最佳的計(jì)算位置呐伞,task計(jì)算的數(shù)據(jù)本地化
第五個(gè)特性,我們?cè)谥vSpark調(diào)優(yōu)的時(shí)候慎式,會(huì)專(zhuān)門(mén)拿出一節(jié)課的時(shí)間來(lái)講這第五個(gè)特性
第四個(gè)特性,我們會(huì)在講shuffle的時(shí)候趟径,詳細(xì)的講為什么會(huì)有這第四個(gè)特性
我們?cè)谶@里看一下源碼瘪吏,這五個(gè)特性是RDD這個(gè)類(lèi)里面的注釋
那我們?cè)撊绾稳フ襌DD這個(gè)類(lèi)呢?
用搜索蜗巧,快捷鍵是按兩下shift掌眠,
或者我們從代碼里面找,core->src->main->scala->rdd->RDD
rdd這個(gè)包里面有很多的各種各樣的RDD幕屹,其中有一個(gè)叫RDD的這樣一個(gè)抽象類(lèi)
包里面的其他RDD都是這個(gè)RDD的子類(lèi)
最后總結(jié)一點(diǎn)蓝丙,RDD實(shí)際上是不存儲(chǔ)數(shù)據(jù)的
對(duì)于初學(xué)者的你們來(lái)說(shuō),今天一天望拖,你們把RDD以為里面是存儲(chǔ)數(shù)據(jù)的渺尘,這樣便于你們與JAVA開(kāi)發(fā)里面的集合類(lèi)做類(lèi)比,這樣比較方便你們記住這個(gè)概念说敏,但這樣的理解就僅限于今天一天鸥跟,因?yàn)殡S著你們學(xué)習(xí)的深入,你們更多的概念你們會(huì)記住盔沫,就不需要用這個(gè)存數(shù)據(jù)來(lái)關(guān)聯(lián)這個(gè)記憶了
RDD不存數(shù)據(jù)這個(gè)事医咨,我明天會(huì)給你們講明白,這樣更方便你們?nèi)腴T(mén)
最終這張圖片放在這里
好我們RDD就先講到這里
下面我們看這張PPT
這是一張進(jìn)化的圖架诞,非常像我們的RDD
這里有一個(gè)名詞拟淮,叫做Lineage,翻譯成中文谴忧,是血統(tǒng)的意思
人的這一個(gè)方向是我們的resultRDD 猴子的這個(gè)方向是我們的數(shù)據(jù)源
當(dāng)我們?cè)谥虚g的RDD出現(xiàn)問(wèn)題的過(guò)程中很泊,我們可以通過(guò)他的父RDD來(lái)做重新計(jì)算,這是Spark保證數(shù)據(jù)容錯(cuò)的一個(gè)根本俏蛮。
Spark任務(wù)執(zhí)行的流程
這是一個(gè)最簡(jiǎn)單的Spark執(zhí)行的流程撑蚌,之后我們會(huì)逐步深入的講這個(gè)執(zhí)行流程,這個(gè)執(zhí)行流程也是我們?cè)诿嬖囍薪?jīng)常會(huì)被問(wèn)到的搏屑。
看這張圖争涌,一共有四臺(tái)服務(wù)器規(guī)模的一個(gè)集群
這臺(tái)服務(wù)器上啟動(dòng)了一個(gè)進(jìn)程叫做Driver進(jìn)程,還有其他三臺(tái)服務(wù)器辣恋,啟動(dòng)一個(gè)Worker進(jìn)程
這些都是真實(shí)的服務(wù)器亮垫,所以服務(wù)器上面會(huì)有一些計(jì)算用的RAM內(nèi)存模软,這些服務(wù)器還有磁盤(pán),磁盤(pán)上存儲(chǔ)著我們要計(jì)算的數(shù)據(jù)
通過(guò)這張圖來(lái)看饮潦,Driver這個(gè)進(jìn)程主要負(fù)責(zé)人什么燃异?
調(diào)度,什么調(diào)度凹汤回俐?任務(wù)調(diào)度是嗎?
是不是task的下發(fā)和result的收集跋〔ⅰ仅颇?
大家想Driver是負(fù)責(zé)結(jié)果的回收,那如果計(jì)算的結(jié)果特別大碘举,會(huì)有什么一個(gè)后果巴摺?
剛才我有講說(shuō)Driver他是一個(gè)進(jìn)程引颈,進(jìn)程的內(nèi)存是不是有限案ぁ?
如果計(jì)算的結(jié)果result非常的大蝙场,是不是會(huì)導(dǎo)致Driver進(jìn)程O(píng)OM傲柰!?
我們看到的Driver李丰,Worker他都是一個(gè)JVM進(jìn)程苦锨,
JVM是什么啊趴泌?是不是java虛擬機(jī)爸凼妗?來(lái)大家跟上我的思路啊嗜憔,我問(wèn)的問(wèn)題秃励,一定在腦袋里面過(guò)一下啊
從這張圖來(lái)看,Driver是不是跟我們的集群吉捶,會(huì)有頻繁的通信岸嵯省?
都有哪些通信啊呐舔,分發(fā)Task是不是通信氨依?收集結(jié)果是不是通信吧浩础食呻?
那我們說(shuō)Driver做調(diào)度,Driver是不是要知道Worker執(zhí)行的情況啊仅胞?
舉個(gè)例子每辟,我們?cè)诠纠锩婀ぷ鳎I(lǐng)導(dǎo)分配給你一個(gè)任務(wù)干旧,你說(shuō)這任務(wù)特別的難渠欺,我自己研究一個(gè)禮拜,一個(gè)禮拜以后領(lǐng)導(dǎo)來(lái)問(wèn)你椎眯,你告訴他你搞不定挠将,領(lǐng)導(dǎo)會(huì)喜歡你這樣的員工嗎?
那你要是員工你應(yīng)該怎么做氨嗾捐名?
講這張圖的目的,是讓大家對(duì)Spark任務(wù)執(zhí)行流程有個(gè)初步的了解闹击,
Driver與Worker之間會(huì)有頻繁的通信,就是你跟你領(lǐng)導(dǎo)要有頻繁的溝通成艘。
大家能記住這一點(diǎn)嗎赏半?要怎么?要溝通淆两,對(duì)嗎断箫?誰(shuí)跟誰(shuí)來(lái)溝通?Driver和Worker來(lái)溝通
然后我們繼續(xù)往下秋冰,如果我們要寫(xiě)一個(gè)Spark程序仲义,那流程是什么樣子的呢?
我們來(lái)感受一下寫(xiě)應(yīng)用程序怎么寫(xiě)剑勾?
首先加載數(shù)據(jù)集對(duì)嗎埃撵?數(shù)據(jù)集可以是Hadoop分布式文件系統(tǒng)上的數(shù)據(jù)
可以是Hbase的數(shù)據(jù),可以是Hive的數(shù)據(jù)虽另,可以是NoSQL的數(shù)據(jù)暂刘,可以是本機(jī)的數(shù)據(jù),
也可以是內(nèi)存對(duì)象的數(shù)據(jù)捂刺,加載完的數(shù)據(jù)對(duì)象谣拣,就是我們的RDD
我們現(xiàn)在有了RDD以后是不是要對(duì)這個(gè)RDD進(jìn)行一系列的操作啊族展?
我們可以對(duì)RDD進(jìn)行transformation類(lèi)的操作
什么叫transformation類(lèi)的操作吧?
我們之前所講的flatMap仪缸、map贵涵、reduceByKey都屬于transformation類(lèi)的算子
transformation他是一個(gè)類(lèi)別的名稱(chēng),在這個(gè)類(lèi)里面有很多具體的算子
那這些就是具體的算子
所有的transformation類(lèi)算子他有一個(gè)特點(diǎn),就是他是延遲執(zhí)行的独悴。
對(duì)剛加載過(guò)來(lái)的RDD例书,執(zhí)行一把flatMap,實(shí)際上他并不會(huì)真正的去執(zhí)行刻炒,他等待一個(gè)時(shí)機(jī)來(lái)觸發(fā)執(zhí)行决采,
還有一類(lèi)的算子叫做action類(lèi)算子,Action類(lèi)算子他是立即執(zhí)行坟奥,或者說(shuō)叫觸發(fā)執(zhí)行
一個(gè)Spark 應(yīng)用程序 你寫(xiě)的一系列轉(zhuǎn)換树瞭,他是由transformation類(lèi)算子進(jìn)行轉(zhuǎn)換的
遇到Action類(lèi)算子才會(huì)執(zhí)行
我們?cè)趯?xiě)WordCount的時(shí)候,最后有一個(gè)foreach算子爱谁,老師在這告訴大家晒喷,foreach算子是一個(gè)Action算子,所以我們的程序可以執(zhí)行出結(jié)果
大家可以式一下访敌,如果不寫(xiě)foreach算子凉敲,程序并不會(huì)執(zhí)行
我們可以看一下這段代碼,這是一段偽代碼
sc.textFile他是讀一個(gè)文件對(duì)吧寺旺?
filter是過(guò)濾的這樣一個(gè)transformation類(lèi)算子
他會(huì)將lines這個(gè)RDD的內(nèi)容進(jìn)行過(guò)濾爷抓,那過(guò)濾的條件是什么?startWith(“ERROR”)
我們之前講過(guò)Boolean類(lèi)型的匿名函數(shù)阻塑,我們稱(chēng)他為謂詞蓝撇,大家還記得嗎?
那大家回憶一下陈莽,Boolean是true的時(shí)候是保留還是false的時(shí)候是保留安巢?
那保留的結(jié)果是不是放到errors這個(gè)RDD里面去了
那下面一行將errors又進(jìn)行了一次過(guò)濾走搁,包含MySQL的內(nèi)容過(guò)濾出來(lái)了
在.count之前也是一個(gè)延遲執(zhí)行的transformation類(lèi)算子独柑,我們把這個(gè)結(jié)果進(jìn)行一個(gè)count計(jì)數(shù)由于count是Action類(lèi)算子,所以他立即執(zhí)行
最下面一行也是一樣私植,過(guò)濾了包含Http這樣一個(gè)字符串的所有記錄
整個(gè)這一段代碼我們叫他為Spark Application群嗤,Spark應(yīng)用程序
在這段代碼里面有幾個(gè)Action類(lèi)算子,那么這個(gè)應(yīng)用程序就有多少個(gè)Job
Job的個(gè)數(shù)與我們的Action類(lèi)算子是一一對(duì)應(yīng)的兵琳。
那么一個(gè)Application里面可以有很多個(gè)job狂秘,那有多少個(gè)Action類(lèi)算子就有多少個(gè)Job