大數(shù)據(jù)-Spark編程基礎(chǔ)(Scala版)_第1頁
大數(shù)據(jù)-Spark編程基礎(chǔ)(Scala版)_第2頁
大數(shù)據(jù)-Spark編程基礎(chǔ)(Scala版)_第3頁
大數(shù)據(jù)-Spark編程基礎(chǔ)(Scala版)_第4頁
大數(shù)據(jù)-Spark編程基礎(chǔ)(Scala版)_第5頁
已閱讀5頁,還剩687頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第1章大數(shù)據(jù)技術(shù)概述

《Spark編程基礎(chǔ)》提綱1.1大數(shù)據(jù)時(shí)代1.2大數(shù)據(jù)概念1.3大數(shù)據(jù)的影響1.4大數(shù)據(jù)關(guān)鍵技術(shù)1.5大數(shù)據(jù)計(jì)算模式1.6代表性大數(shù)據(jù)技術(shù)1.1大數(shù)據(jù)時(shí)代1.1.1第三次信息化浪潮根據(jù)IBM前首席執(zhí)行官郭士納的觀點(diǎn),IT領(lǐng)域每隔十五年就會(huì)迎來一次重大變革信息化浪潮發(fā)生時(shí)間標(biāo)志解決問題代表企業(yè)第一次浪潮1980年前后個(gè)人計(jì)算機(jī)信息處理Intel、AMD、IBM、蘋果、微軟、聯(lián)想、戴爾、惠普等第二次浪潮1995年前后互聯(lián)網(wǎng)信息傳輸雅虎、谷歌、阿里巴巴、百度、騰訊等第三次浪潮2010年前后物聯(lián)網(wǎng)、云計(jì)算和大數(shù)據(jù)信息爆炸將涌現(xiàn)出一批新的市場(chǎng)標(biāo)桿企業(yè)表1三次信息化浪潮1.1.2信息科技為大數(shù)據(jù)時(shí)代提供技術(shù)支撐圖1-1存儲(chǔ)價(jià)格隨時(shí)間變化情況1.存儲(chǔ)設(shè)備容量不斷增加1.1.2信息科技為大數(shù)據(jù)時(shí)代提供技術(shù)支撐來自斯威本科技大學(xué)(SwinburneUniversityofTechnology)的研究團(tuán)隊(duì),在2013年6月29日刊出的《自然通訊(NatureCommunications)》雜志的文章中,描述了一種全新的數(shù)據(jù)存儲(chǔ)方式,可將1PB(1024TB)的數(shù)據(jù)存儲(chǔ)到一張僅DVD大小的聚合物碟片上。1.1.2信息科技為大數(shù)據(jù)時(shí)代提供技術(shù)支撐圖CPU晶體管數(shù)目隨時(shí)間變化情況2.CPU處理能力大幅提升

1.1.2信息科技為大數(shù)據(jù)時(shí)代提供技術(shù)支撐圖

網(wǎng)絡(luò)帶寬隨時(shí)間變化情況3.網(wǎng)絡(luò)帶寬不斷增加1.1.3數(shù)據(jù)產(chǎn)生方式的變革促成大數(shù)據(jù)時(shí)代的來臨圖

數(shù)據(jù)產(chǎn)生方式的變革1.2大數(shù)據(jù)概念1.2.1 數(shù)據(jù)量大根據(jù)IDC作出的估測(cè),數(shù)據(jù)一直都在以每年50%的速度增長(zhǎng),也就是說每?jī)赡昃驮鲩L(zhǎng)一倍(大數(shù)據(jù)摩爾定律)人類在最近兩年產(chǎn)生的數(shù)據(jù)量相當(dāng)于之前產(chǎn)生的全部數(shù)據(jù)量預(yù)計(jì)到2020年,全球?qū)⒖偣矒碛?5ZB的數(shù)據(jù)量,相較于2010年,數(shù)據(jù)量將增長(zhǎng)近30倍1.2.2數(shù)據(jù)類型繁多大數(shù)據(jù)是由結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù)組成的10%的結(jié)構(gòu)化數(shù)據(jù),存儲(chǔ)在數(shù)據(jù)庫中90%的非結(jié)構(gòu)化數(shù)據(jù),它們與人類信息密切相關(guān)科學(xué)研究–基因組–LHC加速器–地球與空間探測(cè)企業(yè)應(yīng)用–Email、文檔、文件–應(yīng)用日志–交易記錄Web1.0數(shù)據(jù)–文本–圖像–視頻Web2.0數(shù)據(jù)–查詢?nèi)罩?點(diǎn)擊流–Twitter/Blog/SNS–Wiki1.2.3 處理速度快從數(shù)據(jù)的生成到消耗,時(shí)間窗口非常小,可用于生成決策的時(shí)間非常少1秒定律:這一點(diǎn)也是和傳統(tǒng)的數(shù)據(jù)挖掘技術(shù)有著本質(zhì)的不同1.2.4 價(jià)值密度低

價(jià)值密度低,商業(yè)價(jià)值高

以視頻為例,連續(xù)不間斷監(jiān)控過程中,可能有用的數(shù)據(jù)僅僅有一兩秒,但是具有很高的商業(yè)價(jià)值繼續(xù)裝ing1.3大數(shù)據(jù)的影響

圖靈獎(jiǎng)獲得者、著名數(shù)據(jù)庫專家JimGray博士觀察并總結(jié)人類自古以來,在科學(xué)研究上,先后歷經(jīng)了實(shí)驗(yàn)、理論、計(jì)算和數(shù)據(jù)四種范式實(shí)驗(yàn)理論計(jì)算數(shù)據(jù)1.3大數(shù)據(jù)的影響在思維方式方面,大數(shù)據(jù)完全顛覆了傳統(tǒng)的思維方式:全樣而非抽樣效率而非精確相關(guān)而非因果1.4大數(shù)據(jù)關(guān)鍵技術(shù)表1-5大數(shù)據(jù)技術(shù)的不同層面及其功能技術(shù)層面功能數(shù)據(jù)采集利用ETL工具將分布的、異構(gòu)數(shù)據(jù)源中的數(shù)據(jù)如關(guān)系數(shù)據(jù)、平面數(shù)據(jù)文件等,抽取到臨時(shí)中間層后進(jìn)行清洗、轉(zhuǎn)換、集成,最后加載到數(shù)據(jù)倉庫或數(shù)據(jù)集市中,成為聯(lián)機(jī)分析處理、數(shù)據(jù)挖掘的基礎(chǔ);或者也可以把實(shí)時(shí)采集的數(shù)據(jù)作為流計(jì)算系統(tǒng)的輸入,進(jìn)行實(shí)時(shí)處理分析數(shù)據(jù)存儲(chǔ)和管理利用分布式文件系統(tǒng)、數(shù)據(jù)倉庫、關(guān)系數(shù)據(jù)庫、NoSQL數(shù)據(jù)庫、云數(shù)據(jù)庫等,實(shí)現(xiàn)對(duì)結(jié)構(gòu)化、半結(jié)構(gòu)化和非結(jié)構(gòu)化海量數(shù)據(jù)的存儲(chǔ)和管理數(shù)據(jù)處理與分析利用分布式并行編程模型和計(jì)算框架,結(jié)合機(jī)器學(xué)習(xí)和數(shù)據(jù)挖掘算法,實(shí)現(xiàn)對(duì)海量數(shù)據(jù)的處理和分析;對(duì)分析結(jié)果進(jìn)行可視化呈現(xiàn),幫助人們更好地理解數(shù)據(jù)、分析數(shù)據(jù)數(shù)據(jù)隱私和安全在從大數(shù)據(jù)中挖掘潛在的巨大商業(yè)價(jià)值和學(xué)術(shù)價(jià)值的同時(shí),構(gòu)建隱私數(shù)據(jù)保護(hù)體系和數(shù)據(jù)安全體系,有效保護(hù)個(gè)人隱私和數(shù)據(jù)安全1.4大數(shù)據(jù)關(guān)鍵技術(shù)分布式存儲(chǔ)分布式處理GFS\HDFSBigTable\HBaseNoSQL(鍵值、列族、圖形、文檔數(shù)據(jù)庫)NewSQL(如:SQLAzure)MapReduce大數(shù)據(jù)兩大核心技術(shù)1.5大數(shù)據(jù)計(jì)算模式大數(shù)據(jù)計(jì)算模式解決問題代表產(chǎn)品批處理計(jì)算針對(duì)大規(guī)模數(shù)據(jù)的批量處理MapReduce、Spark等流計(jì)算針對(duì)流數(shù)據(jù)的實(shí)時(shí)計(jì)算Storm、S4、Flume、Streams、Puma、DStream、SuperMario、銀河流數(shù)據(jù)處理平臺(tái)等圖計(jì)算針對(duì)大規(guī)模圖結(jié)構(gòu)數(shù)據(jù)的處理Pregel、GraphX、Giraph、PowerGraph、Hama、GoldenOrb等查詢分析計(jì)算大規(guī)模數(shù)據(jù)的存儲(chǔ)管理和查詢分析Dremel、Hive、Cassandra、Impala等表1-3大數(shù)據(jù)計(jì)算模式及其代表產(chǎn)品1.6代表性大數(shù)據(jù)技術(shù)1.6.1Hadoop1.6.2Spark1.6.3Flink1.6.4Beam1.6.1Hadoop圖Hadoop生態(tài)系統(tǒng)1.6.1Hadoop——MapReduce圖MapReduce工作流程ShuffleMapReduce將復(fù)雜的、運(yùn)行于大規(guī)模集群上的并行計(jì)算過程高度地抽象到了兩個(gè)函數(shù):Map和Reduce編程容易,不需要掌握分布式并行編程細(xì)節(jié),也可以很容易把自己的程序運(yùn)行在分布式系統(tǒng)上,完成海量數(shù)據(jù)的計(jì)算MapReduce采用“分而治之”策略,一個(gè)存儲(chǔ)在分布式文件系統(tǒng)中的大規(guī)模數(shù)據(jù)集,會(huì)被切分成許多獨(dú)立的分片(split),這些分片可以被多個(gè)Map任務(wù)并行處理1.6.1Hadoop——YARN一個(gè)企業(yè)當(dāng)中同時(shí)存在各種不同的業(yè)務(wù)應(yīng)用場(chǎng)景,需要采用不同的計(jì)算框架MapReduce實(shí)現(xiàn)離線批處理使用Impala實(shí)現(xiàn)實(shí)時(shí)交互式查詢分析使用Storm實(shí)現(xiàn)流式數(shù)據(jù)實(shí)時(shí)分析使用Spark實(shí)現(xiàn)迭代計(jì)算這些產(chǎn)品通常來自不同的開發(fā)團(tuán)隊(duì),具有各自的資源調(diào)度管理機(jī)制為了避免不同類型應(yīng)用之間互相干擾,企業(yè)就需要把內(nèi)部的服務(wù)器拆分成多個(gè)集群,分別安裝運(yùn)行不同的計(jì)算框架,即“一個(gè)框架一個(gè)集群”導(dǎo)致問題集群資源利用率低數(shù)據(jù)無法共享維護(hù)代價(jià)高YARN的目標(biāo)就是實(shí)現(xiàn)“一個(gè)集群多個(gè)框架”,為什么?圖

在YARN上部署各種計(jì)算框架YARN的目標(biāo)就是實(shí)現(xiàn)“一個(gè)集群多個(gè)框架”,即在一個(gè)集群上部署一個(gè)統(tǒng)一的資源調(diào)度管理框架YARN,在YARN之上可以部署其他各種計(jì)算框架由YARN為這些計(jì)算框架提供統(tǒng)一的資源調(diào)度管理服務(wù),并且能夠根據(jù)各種計(jì)算框架的負(fù)載需求,調(diào)整各自占用的資源,實(shí)現(xiàn)集群資源共享和資源彈性收縮可以實(shí)現(xiàn)一個(gè)集群上的不同應(yīng)用負(fù)載混搭,有效提高了集群的利用率不同計(jì)算框架可以共享底層存儲(chǔ),避免了數(shù)據(jù)集跨集群移動(dòng)1.6.1Hadoop——YARN1.6.2SparkSpark架構(gòu)圖1.6.2SparkSpark生態(tài)系統(tǒng)1.6.2SparkHadoop存在如下一些缺點(diǎn):表達(dá)能力有限磁盤IO開銷大延遲高任務(wù)之間的銜接涉及IO開銷在前一個(gè)任務(wù)執(zhí)行完成之前,其他任務(wù)就無法開始,難以勝任復(fù)雜、多階段的計(jì)算任務(wù)

Hadoop與Spark的對(duì)比1.6.2SparkSpark在借鑒HadoopMapReduce優(yōu)點(diǎn)的同時(shí),很好地解決了MapReduce所面臨的問題相比于HadoopMapReduce,Spark主要具有如下優(yōu)點(diǎn):Spark的計(jì)算模式也屬于MapReduce,但不局限于Map和Reduce操作,還提供了多種數(shù)據(jù)集操作類型,編程模型比HadoopMapReduce更靈活Spark提供了內(nèi)存計(jì)算,可將中間結(jié)果放到內(nèi)存中,對(duì)于迭代運(yùn)算效率更高Spark基于DAG的任務(wù)調(diào)度執(zhí)行機(jī)制,要優(yōu)于HadoopMapReduce的迭代執(zhí)行機(jī)制

Hadoop與Spark的對(duì)比1.6.2Spark圖Hadoop與Spark的執(zhí)行流程對(duì)比1.6.2Spark圖Hadoop與Spark執(zhí)行邏輯回歸的時(shí)間對(duì)比使用Hadoop進(jìn)行迭代計(jì)算非常耗資源Spark將數(shù)據(jù)載入內(nèi)存后,之后的迭代計(jì)算都可以直接使用內(nèi)存中的中間結(jié)果作運(yùn)算,避免了從磁盤中頻繁讀取數(shù)據(jù)1.6.3FlinkFlink架構(gòu)圖1.6.3FlinkFlink生態(tài)系統(tǒng)1.6.3FlinkFlink與Spark的比較1.6.3FlinkSpark和Flink全部都運(yùn)行在HadoopYARN上,性能為Flink>Spark>Hadoop(MR),迭代次數(shù)越多越明顯,性能上,F(xiàn)link優(yōu)于Spark和Hadoop最主要的原因是Flink支持增量迭代,具有對(duì)迭代自動(dòng)優(yōu)化的功能。性能對(duì)比首先它們都可以基于內(nèi)存計(jì)算框架進(jìn)行實(shí)時(shí)計(jì)算,所以都擁有非常好的計(jì)算性能。經(jīng)過測(cè)試,F(xiàn)link計(jì)算性能上略好。1.6.3Flink流式計(jì)算比較它們都支持流式計(jì)算,F(xiàn)link是一行一行處理,而Spark是基于數(shù)據(jù)片集合(RDD)進(jìn)行小批量處理,所以Spark在流式處理方面,不可避免增加一些延時(shí)。Flink的流式計(jì)算跟Storm性能差不多,支持毫秒級(jí)計(jì)算,而Spark則只能支持秒級(jí)計(jì)算。SQL支持都支持SQL,Spark對(duì)SQL的支持比Flink支持的范圍要大一些,另外Spark支持對(duì)SQL的優(yōu)化,而Flink支持主要是對(duì)API級(jí)的優(yōu)化。既生瑜,何生亮!1.6.4Beam谷歌,Beam,一統(tǒng)天下?1.6.4Beam

第2章Scala語言基礎(chǔ)

《Spark編程基礎(chǔ)》提綱2.1Scala語言概述2.2Scala基礎(chǔ)2.3面向?qū)ο缶幊袒A(chǔ)2.4函數(shù)式編程基礎(chǔ)2.1Scala語言概述2.1.1計(jì)算機(jī)的緣起2.1.2編程范式2.1.3Scala簡(jiǎn)介2.1.1計(jì)算機(jī)的緣起數(shù)學(xué)家阿隆佐?邱奇(AlonzoChurch)設(shè)計(jì)了“λ演算”,這是一套用于研究函數(shù)定義、函數(shù)應(yīng)用和遞歸的形式系統(tǒng)λ演算被視為最小的通用程序設(shè)計(jì)語言λ演算的通用性就體現(xiàn)在,任何一個(gè)可計(jì)算函數(shù)都能用這種形式來表達(dá)和求值λ演算是一個(gè)數(shù)理邏輯形式系統(tǒng),強(qiáng)調(diào)的是變換規(guī)則的運(yùn)用,而非實(shí)現(xiàn)它們的具體機(jī)器2.1.1計(jì)算機(jī)的緣起英國(guó)數(shù)學(xué)家阿蘭·圖靈采用了完全不同的設(shè)計(jì)思路,提出了一種全新的抽象計(jì)算模型——圖靈機(jī)圖靈機(jī)是現(xiàn)代計(jì)算機(jī)的鼻祖?,F(xiàn)有理論已經(jīng)證明,λ演算和圖靈機(jī)的計(jì)算能力是等價(jià)的2.1.1計(jì)算機(jī)的緣起馮·諾依曼(JohnVonNeumann)將圖靈的理論物化成為實(shí)際的物理實(shí)體,成為了計(jì)算機(jī)體系結(jié)構(gòu)的奠基者1945年6月,馮·諾依曼提出了在數(shù)字計(jì)算機(jī)內(nèi)部的存儲(chǔ)器中存放程序的概念,這是所有現(xiàn)代計(jì)算機(jī)的范式,被稱為“馮·諾依曼結(jié)構(gòu)”2.1.2編程范式編程范式是指計(jì)算機(jī)編程的基本風(fēng)格或典范模式。常見的編程范式主要包括命令式編程和函數(shù)式編程。面向?qū)ο缶幊叹蛯儆诿钍骄幊?,比如C++、Java等命令式語言是植根于馮·諾依曼體系的,一個(gè)命令式程序就是一個(gè)馮·諾依曼機(jī)的指令序列,給機(jī)器提供一條又一條的命令序列讓其原封不動(dòng)地執(zhí)行函數(shù)式編程,又稱泛函編程,它將計(jì)算機(jī)的計(jì)算視為數(shù)學(xué)上的函數(shù)計(jì)算函數(shù)編程語言最重要的基礎(chǔ)是λ演算。典型的函數(shù)式語言包括Haskell、Erlang和Lisp等2.1.2編程范式一個(gè)很自然的問題是,既然已經(jīng)有了命令式編程,為什么還需要函數(shù)式編程呢?為什么在C++、Java等命令式編程流行了很多年以后,近些年函數(shù)式編程會(huì)迅速升溫呢?命令式編程涉及多線程之間的狀態(tài)共享,需要鎖機(jī)制實(shí)現(xiàn)并發(fā)控制函數(shù)式編程不會(huì)在多個(gè)線程之間共享狀態(tài),不需要用鎖機(jī)制,可以更好并行處理,充分利用多核CPU并行處理能力2.1.3Scala簡(jiǎn)介Scala是一門類Java的多范式語言,它整合了面向?qū)ο缶幊毯秃瘮?shù)式編程的最佳特性。具體來講:Scala運(yùn)行于Java虛擬機(jī)(JVM)之上,并且兼容現(xiàn)有的Java程序Scala是一門純粹的面向?qū)ο蟮恼Z言Scala也是一門函數(shù)式語言MartinOderskyScala之父詹姆斯·高斯林Java之父”IfIweretopickalanguagetousetodayotherthanJava,itwouldbeScala.”

—JamesGosling

2.1.4Scala的安裝和使用方法

安裝Java

安裝Scala

使用Scala解釋器

第1個(gè)Scala程序:HelloWorld具體可以參照廈門大學(xué)數(shù)據(jù)庫實(shí)驗(yàn)室網(wǎng)站博客:/blog/929-2/平臺(tái)每年訪問量超過100萬次

安裝Java直接通過命令安裝OpenJDK7配置JAVA_HOME環(huán)境變量使配置立即生效:

安裝Scala登錄Scala官網(wǎng),下載scala-2.11.8.tgz把scala命令添加到path環(huán)境變量中啟動(dòng)Scala解釋器:

使用Scala解釋器在Shell命令提示符界面中輸入“scala”命令后,會(huì)進(jìn)入scala命令行提示符狀態(tài):可以使用命令“:quit”退出Scala解釋器,如下所示:

使用Scala解釋器(續(xù))用“:load”命令導(dǎo)入腳本,一次運(yùn)行多行程序:使用文本編輯器(比如vim)創(chuàng)建一個(gè)代碼文件Test.scala在ScalaREPL中執(zhí)行如下命令運(yùn)行該代碼文件:

第1個(gè)Scala程序:HelloWorld通過編譯打包的方式運(yùn)行Scala程序使用scalac命令進(jìn)行編譯(編譯的結(jié)果為java字節(jié)碼)使用scala或者java運(yùn)行字節(jié)碼文件2.2Scala基礎(chǔ)2.2.1基本數(shù)據(jù)類型和變量2.2.2輸入輸出2.2.3控制結(jié)構(gòu)2.2.4數(shù)據(jù)結(jié)構(gòu)

2.2.1基本數(shù)據(jù)類型和變量基本數(shù)據(jù)類型

基本操作

變量

基本數(shù)據(jù)類型Scala的數(shù)據(jù)類型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean(注意首字母大寫)和Java不同的是,在Scala中,這些類型都是“類”,并且都是包scala的成員,比如,Int的全名是scala.Int。對(duì)于字符串,Scala用java.lang.String類來表示字符串

基本數(shù)據(jù)類型字面量(literal)

基本操作在Scala中,操作符就是方法。例如,5+3和(5).+(3)是等價(jià)的等價(jià)于算術(shù)運(yùn)算符:加(+)、減(-)、乘(*)、除(/)、余數(shù)(%);關(guān)系運(yùn)算符:大于(>)、小于(<)、等于(==)、不等于(!=)、大于等于(>=)、小于等于(<=)邏輯運(yùn)算符:邏輯與(&&)、邏輯或(||)、邏輯非(!);位運(yùn)算符:按位與(&)、按位或(|)、按位異或(^)、按位取反(~)等賦值運(yùn)算符:=及其與其它運(yùn)算符結(jié)合的擴(kuò)展賦值運(yùn)算符,例如+=、%=。操作符優(yōu)先級(jí):算術(shù)運(yùn)算符>關(guān)系運(yùn)算符>邏輯運(yùn)算符>賦值運(yùn)算符

基本操作富包裝類對(duì)于基本數(shù)據(jù)類型,除了以上提到的各種操作符外,Scala還提供了許多常用運(yùn)算的方法,只是這些方法不是在基本類里面定義,還是被封裝到一個(gè)對(duì)應(yīng)的富包裝類中每個(gè)基本類型都有一個(gè)對(duì)應(yīng)的富包裝類,例如Int有一個(gè)RichInt類、String有一個(gè)RichString類,這些類位于包scala.runtime中當(dāng)對(duì)一個(gè)基本數(shù)據(jù)類型的對(duì)象調(diào)用其富包裝類提供的方法,Scala會(huì)自動(dòng)通過隱式轉(zhuǎn)換將該對(duì)象轉(zhuǎn)換為對(duì)應(yīng)的富包裝類型,然后再調(diào)用相應(yīng)的方法。例如:3max5

變量Scala有兩種類型的變量:val:是不可變的,在聲明時(shí)就必須被初始化,而且初始化以后就不能再賦值;var:是可變的,聲明的時(shí)候需要進(jìn)行初始化,初始化以后還可以再次對(duì)其賦值?;菊Z法:val變量名:數(shù)據(jù)類型=初始值var變量名:數(shù)據(jù)類型=初始值

變量類型推斷機(jī)制(typeinference):根據(jù)初始值自動(dòng)推斷變量的類型,使得定義變量時(shí)可以省略具體的數(shù)據(jù)類型及其前面的冒號(hào)

變量注意:在REPL環(huán)境下,可以重復(fù)使用同一個(gè)變量名來定義變量,而且變量前的修飾符和其類型都可以不一致,REPL會(huì)以最新的一個(gè)定義為準(zhǔn)2.2.2輸入輸出控制臺(tái)輸入輸出語句

讀寫文件

控制臺(tái)輸入輸出語句從控制臺(tái)讀寫數(shù)據(jù)方法:readInt、readDouble、readByte、readShort、readFloat、readLong、readCharreadBoolean及readLine,分別對(duì)應(yīng)9種基本數(shù)據(jù)類型,其中前8種方法沒有參數(shù),readLine可以不提供參數(shù),也可以帶一個(gè)字符串參數(shù)的提示所有這些函數(shù)都屬于對(duì)象scala.io.StdIn的方法,使用前必須導(dǎo)入,或者直接用全稱進(jìn)行調(diào)用控制臺(tái)輸入輸出語句Tips:讀取數(shù)據(jù)時(shí)看不到輸入的解決辦法。用-Xnojline選項(xiàng)禁用控制臺(tái)讀寫庫Jline,但這時(shí)又不能用箭頭調(diào)用命令歷史,所以還需要一個(gè)小工具rlwrap。完整命令為“rlwrapscala-Xnojline”,如果提示rlwrap沒有安裝,請(qǐng)按提示進(jìn)行安裝。

控制臺(tái)輸入輸出語句向控制臺(tái)輸出信息方法:print()和println(),可以直接輸出字符串或者其它數(shù)據(jù)類型,其中println在末尾自動(dòng)換行。

控制臺(tái)輸入輸出語句C語言風(fēng)格格式化字符串的printf()函數(shù)print()、println()和printf()都在對(duì)象Predef中定義,該對(duì)象默認(rèn)情況下被所有Scala程序引用,因此可以直接使用Predef對(duì)象提供的方法,而無需使用scala.Predef.的形式。

控制臺(tái)輸入輸出語句s字符串和f字符串:Scala提供的字符串插值機(jī)制,以方便在字符串字面量中直接嵌入變量的值?;菊Z法:s"…$變量名…"或f"…$變量名%格式化字符…"

讀寫文件寫入文件Scala需要使用java.io.PrintWriter實(shí)現(xiàn)把數(shù)據(jù)寫入到文件,PrintWriter類提供了print和println兩個(gè)寫方法

讀寫文件讀取文件可以使用Scala.io.Source的getLines方法實(shí)現(xiàn)對(duì)文件中所有行的讀取2.2.3控制結(jié)構(gòu)if條件表達(dá)式while循環(huán)for循環(huán)異常處理對(duì)循環(huán)的控制if條件表達(dá)式有一點(diǎn)與Java不同的是,Scala中的if表達(dá)式的值可以賦值給變量while循環(huán)for循環(huán)基本語法其中,“變量<-表達(dá)式”被稱為“生成器(generator)”for循環(huán)“守衛(wèi)(guard)”的表達(dá)式:過濾出一些滿足條件的結(jié)果?;菊Z法:for(變量<-表達(dá)式if

條件表達(dá)式)語句塊for循環(huán)Scala也支持“多個(gè)生成器”的情形,可以用分號(hào)把它們隔開,比如:for循環(huán)for結(jié)構(gòu)可以在每次執(zhí)行的時(shí)候創(chuàng)造一個(gè)值,然后將包含了所有產(chǎn)生值的集合作為for循環(huán)表達(dá)式的結(jié)果返回,集合的類型由生成器中的集合類型確定。for(變量<-表達(dá)式)yield

{語句塊}for推導(dǎo)式

異常處理Scala仍使用try-catch結(jié)構(gòu)來捕獲異常importjava.io.FileReaderimportjava.io.FileNotFoundExceptionimportjava.io.IOExceptiontry

{

valf=newFileReader("input.txt")

//文件操作}

catch

{

caseex:FileNotFoundException=>

//文件不存在時(shí)的操作

caseex:IOException=>

//發(fā)生I/O錯(cuò)誤時(shí)的操作}finally

{

file.close()//確保關(guān)閉文件}

Scala不支持Java中的“受檢查異?!?checkedexception),將所有異常都當(dāng)作“不受檢異?!保ɑ蚍Q為運(yùn)行時(shí)異常)

對(duì)循環(huán)的控制為了提前終止整個(gè)循環(huán)或者跳到下一個(gè)循環(huán),Scala沒有break和continue關(guān)鍵字。Scala提供了一個(gè)Breaks類(位于包scala.util.control)。Breaks類有兩個(gè)方法用于對(duì)循環(huán)結(jié)構(gòu)進(jìn)行控制,即breakable和break:將需要控制的語句塊作為參數(shù)放在breakable后面,然后,其內(nèi)部在某個(gè)條件滿足時(shí)調(diào)用break方法,程序?qū)⑻鯾reakable方法。

對(duì)循環(huán)的控制2.2.4數(shù)據(jù)結(jié)構(gòu)

數(shù)組(Array)

元組(Tuple)

容器(Collection)

序列(Sequence)集合(Set)

映射(Map)

迭代器(Iterator)

數(shù)組(Array)數(shù)組:一種可變的、可索引的、元素具有相同類型的數(shù)據(jù)集合。Scala提供了參數(shù)化類型的通用數(shù)組類Array[T],其中T可以是任意的Scala類型,可以通過顯式指定類型或者通過隱式推斷來實(shí)例化一個(gè)數(shù)組??梢圆唤o出數(shù)組類型,Scala會(huì)自動(dòng)根據(jù)提供的初始化數(shù)據(jù)來推斷出數(shù)組的類型

數(shù)組(Array)多維數(shù)組的創(chuàng)建:調(diào)用Array的ofDim方法valmyMatrix=Array.ofDim[Int](3,4)//類型實(shí)際就是Array[Array[Int]]valmyCube=Array.ofDim[String](3,2,4)//類型實(shí)際是Array[Array[Array[Int]]]可以使用多級(jí)圓括號(hào)來訪問多維數(shù)組的元素,例如myMatrix(0)(1)返回第一行第二列的元素

元組(Tuple)元組是對(duì)多個(gè)不同類型對(duì)象的一種簡(jiǎn)單封裝。定義元組最簡(jiǎn)單的方法就是把多個(gè)元素用逗號(hào)分開并用圓括號(hào)包圍起來。使用下劃線“_”加上從1開始的索引值,來訪問元組的元素。如果需要在方法里返回多個(gè)不同類型的對(duì)象,Scala可以通過返回一個(gè)元組實(shí)現(xiàn)。

容器(collection)Scala提供了一套豐富的容器(collection)庫,包括序列(Sequence)、集合(Set)、映射(Map)等。Scala用了三個(gè)包來組織容器類,分別是scala.collection、scala.collection.mutable和scala.collection.immutable。scala.collection包中的容器通常都具備對(duì)應(yīng)的不可變實(shí)現(xiàn)和可變實(shí)現(xiàn)。

容器(collection)scala.collection包中容器的宏觀層次結(jié)構(gòu)

序列(Sequence)序列(Sequence):元素可以按照特定的順序訪問的容器。序列中每個(gè)元素均帶有一個(gè)從0開始計(jì)數(shù)的固定索引位置。序列容器的根是collection.Seq特質(zhì)。其具有兩個(gè)子特質(zhì)LinearSeq和IndexedSeq。LinearSeq序列具有高效的head和tail操作,而IndexedSeq序列具有高效的隨機(jī)存儲(chǔ)操作。實(shí)現(xiàn)了特質(zhì)LinearSeq的常用序列有列表(List)和隊(duì)列(Queue)。實(shí)現(xiàn)了特質(zhì)IndexedSeq的常用序列有可變數(shù)組(ArrayBuffer)和向量(Vector)。

序列---列表(List)列表:一種共享相同類型的不可變的對(duì)象序列。定義在scala.collection.immutable包中不同于Java的java.util.List,scala的List一旦被定義,其值就不能改變,因此聲明List時(shí)必須初始化varstrList=List("BigData","Hadoop","Spark")列表有頭部和尾部的概念,可以分別使用head和tail方法來獲取head返回的是列表第一個(gè)元素的值tail返回的是除第一個(gè)元素外的其它值構(gòu)成的新列表,這體現(xiàn)出列表具有遞歸的鏈表結(jié)構(gòu)strList.head將返回字符串”BigData”,strList.tail返回List("Hadoop","Spark")

序列---列表(List)Scala還定義了一個(gè)空列表對(duì)象Nil,借助Nil,可以將多個(gè)元素用操作符::串起來初始化一個(gè)列表valintList=1::2::3::Nil與valintList=List(1,2,3)等效構(gòu)造列表常用的方法是通過在已有列表前端增加元素,使用的操作符為::,例如:valotherList="Apache"::strList執(zhí)行該語句后strList保持不變,而otherList將成為一個(gè)新的列表:List("Apache","BigData","Hadoop","Spark")注意:除了head、tail操作是常數(shù)時(shí)間O(1),其它按索引訪問的操作都需要從頭開始遍歷,因此是線性時(shí)間復(fù)雜度O(N)。2.2.4.4序列---向量(vector)Vetor可以實(shí)現(xiàn)所有訪問操作都是常數(shù)時(shí)間。2.2.4.4序列---ListBuffer和ArrayBufferListBuffer和ArrayBuffer是List和Vector對(duì)應(yīng)的可變版本,這兩個(gè)序列都位于scala.collection.mutable中。常用操作符:+=Insert-=remove2.2.4.4序列---RangeRange類:一種特殊的、帶索引的不可變數(shù)字等差序列。其包含的值為從給定起點(diǎn)按一定步長(zhǎng)增長(zhǎng)(減小)到指定終點(diǎn)的所有數(shù)值。Range可以支持創(chuàng)建不同數(shù)據(jù)類型的數(shù)值序列,包括Int、Long、Float、Double、Char、BigInt和BigDecimal等(1)創(chuàng)建一個(gè)從1到5的數(shù)值序列,包含區(qū)間終點(diǎn)5,步長(zhǎng)為12.2.4.4序列---Range(2)創(chuàng)建一個(gè)從1到5的數(shù)值序列,不包含區(qū)間終點(diǎn)5,步長(zhǎng)為1(3)創(chuàng)建一個(gè)從1到10的數(shù)值序列,包含區(qū)間終點(diǎn)10,步長(zhǎng)為2(4)創(chuàng)建一個(gè)Float類型的數(shù)值序列,從0.5f到5.9f,步長(zhǎng)為0.3f

集合(Set)集合(set):不重復(fù)元素的容器(collection)。列表中的元素是按照插入的先后順序來組織的,但是,“集合”中的元素并不會(huì)記錄元素的插入順序,而是以“哈?!狈椒▽?duì)元素的值進(jìn)行組織,所以,它允許你快速地找到某個(gè)元素集合包括可變集和不可變集,分別位于scala.collection.mutable包和scala.collection.immutable包,缺省情況下創(chuàng)建的是不可變集varmySet=Set("Hadoop","Spark")mySet+="Scala"

如果要聲明一個(gè)可變集,則需要提前引入scala.collection.mutable.Setimportscala.collection.mutable.SetvalmyMutableSet=Set("Database","BigData")myMutableSet+="CloudComputing"

映射(Map)映射(Map):一系列鍵值對(duì)的容器。鍵是唯一的,但值不一定是唯一的??梢愿鶕?jù)鍵來對(duì)值進(jìn)行快速的檢索Scala的映射包含了可變的和不可變的兩種版本,分別定義在包scala.collection.mutable和scala.collection.immutable里。默認(rèn)情況下,Scala中使用不可變的映射。如果想使用可變映射,必須明確地導(dǎo)入scala.collection.mutable.Mapvaluniversity=Map("XMU"->"XiamenUniversity","THU"->"TsinghuaUniversity","PKU"->"PekingUniversity")

映射(Map)如果要獲取映射中的值,可以通過鍵來獲取對(duì)于這種訪問方式,如果給定的鍵不存在,則會(huì)拋出異常,為此,訪問前可以先調(diào)用contains方法確定鍵是否存在

映射(Map)可變的映射也可以使用+=操作來添加新的元素

迭代器(Iterator)迭代器(Iterator)不是一個(gè)容器,而是提供了按順序訪問容器元素的數(shù)據(jù)結(jié)構(gòu)。

迭代器包含兩個(gè)基本操作:next和hasNext。next可以返回迭代器的下一個(gè)元素,hasNext用于檢測(cè)是否還有下一個(gè)元素建議:除next和hasnext方法外,在對(duì)一個(gè)迭代器調(diào)用了某個(gè)方法后,不要再次使用該迭代器。2.3面向?qū)ο缶幊袒A(chǔ)2.3.1類2.3.2對(duì)象2.3.3繼承2.3.4參數(shù)化類型2.3.5特質(zhì)2.3.6模式匹配2.3.7包2.3.1類

類的定義

類成員的可見性

方法的定義

構(gòu)造器

類的定義類的定義:字段用val或var關(guān)鍵字進(jìn)行定義方法定義:def方法名(參數(shù)列表):返回結(jié)果類型={方法體}

類的定義使用new關(guān)鍵字創(chuàng)建一個(gè)類的實(shí)例。

類成員的可見性Scala類中所有成員的默認(rèn)可見性為公有,任何作用域內(nèi)都能直接訪問公有成員。除了默認(rèn)的公有可見性,Scala也提供private和protected,其中,private成員只對(duì)本類型和嵌套類型可見;protected成員對(duì)本類型和其繼承類型都可見。為了避免直接暴露public字段,建議將字段設(shè)置為private,對(duì)于private字段,Scala采用類似Java中的getter和setter方法,定義了兩個(gè)成對(duì)的方法value和value_=進(jìn)行讀取和修改。

類成員的可見性Scala語法中有如下規(guī)范,當(dāng)編譯器看到以value和value_=這種成對(duì)形式出現(xiàn)的方法時(shí),它允許用戶去掉下劃線_,而采用類似賦值表達(dá)式的形式

方法的定義基本語法:def方法名(參數(shù)列表):返回結(jié)果類型={方法體}方法參數(shù)前不能加上val或var,所有的方法參數(shù)都是不可變類型。無參數(shù)的方法定義時(shí)可以省略括號(hào),這時(shí)調(diào)用時(shí)也不能帶有括號(hào);如果定義時(shí)帶有括號(hào),則調(diào)用時(shí)可以帶括號(hào),也可以不帶括號(hào)。方法名后面的圓括號(hào)()可以用大括號(hào){}來代替。如果方法只有一個(gè)參數(shù),可以省略點(diǎn)號(hào)(.)而采用中綴操作符調(diào)用方法。如果方法體只有一條語句,可以省略方法體兩邊的大括號(hào)

方法的定義

方法的定義當(dāng)方法的返回結(jié)果類型可以從最后的表達(dá)式推斷出時(shí),可以省略結(jié)果類型;如果方法返回類型為Unit,可以同時(shí)省略返回結(jié)果類型和等號(hào),但不能省略大括號(hào)。Scala允許方法重載。只要方法的完整簽名(包括方法名、參數(shù)類型列表、返回類型)是唯一的,多個(gè)方法可以使用相同的方法名。構(gòu)造器Scala類的定義主體就是類的構(gòu)造器,稱為主構(gòu)造器。在類名之后用圓括號(hào)列出主構(gòu)造器的參數(shù)列表。主構(gòu)造器的參數(shù)前可以使用val或var關(guān)鍵字,Scala內(nèi)部將自動(dòng)為這些參數(shù)創(chuàng)建私有字段,并提供對(duì)應(yīng)的訪問方法如果不希望將構(gòu)造器參數(shù)成為類的字段,只需要省略關(guān)鍵字var或者val

構(gòu)造器Scala類可以包含零個(gè)或多個(gè)輔助構(gòu)造器(auxiliaryconstructor)。輔助構(gòu)造器使用this進(jìn)行定義,this的返回類型為Unit。每個(gè)輔助構(gòu)造器的第一個(gè)表達(dá)式必須是調(diào)用一個(gè)此前已經(jīng)定義的輔助構(gòu)造器或主構(gòu)造器,調(diào)用的形式為“this(參數(shù)列表)”

構(gòu)造器2.3.2對(duì)象

單例對(duì)象

伴生對(duì)象

應(yīng)用程序?qū)ο骯pply方法和update方法

單例對(duì)象Scala采用單例對(duì)象(singletonobject)來實(shí)現(xiàn)與Java靜態(tài)成員同樣的功能。使用object關(guān)鍵字定義單例對(duì)象。單例對(duì)象的使用與一個(gè)普通的類實(shí)例一樣:

單例對(duì)象---伴生對(duì)象和孤立對(duì)象當(dāng)一個(gè)單例對(duì)象和它的同名類一起出現(xiàn)時(shí),這時(shí)的單例對(duì)象被稱為這個(gè)同名類的“伴生對(duì)象”

(companionobject)。相應(yīng)的類被稱為這個(gè)單例對(duì)象的“伴生類”類和它的伴生對(duì)象必須存在于同一個(gè)文件中,可以相互訪問私有成員。沒有同名類的單例對(duì)象,被稱為孤立對(duì)象(standaloneobject)。一般情況下,Scala程序的入口點(diǎn)main方法就是定義在一個(gè)孤立對(duì)象里。

單例對(duì)象---伴生對(duì)象和孤立對(duì)象apply方法和update方法思考下行代碼的執(zhí)行過程:Scala自動(dòng)調(diào)用Array類的伴生對(duì)象Array中的一個(gè)稱為apply的方法,來創(chuàng)建一個(gè)Array對(duì)象myStrArr。apply方法調(diào)用約定:用括號(hào)傳遞給類實(shí)例或單例對(duì)象名一個(gè)或多個(gè)參數(shù)時(shí),Scala會(huì)在相應(yīng)的類或?qū)ο笾胁檎曳椒麨閍pply且參數(shù)列表與傳入的參數(shù)一致的方法,并用傳入的參數(shù)來調(diào)用該apply方法。apply方法和update方法例:類中的apply方法apply方法和update方法伴生對(duì)象中的apply方法:將所有類的構(gòu)造方法以apply方法的形式定義在伴生對(duì)象中,這樣伴生對(duì)象就像生成類實(shí)例的工廠,而這些apply方法也被稱為工廠方法。apply方法和update方法為什么要設(shè)計(jì)apply方法?保持對(duì)象和函數(shù)之間使用的一致性。面向?qū)ο螅骸皩?duì)象.方法”VS數(shù)學(xué):“函數(shù)(參數(shù))”Scala中一切都是對(duì)象,包括函數(shù)也是對(duì)象。Scala中的函數(shù)既保留括號(hào)調(diào)用樣式,也可以使用點(diǎn)號(hào)調(diào)用形式,其對(duì)應(yīng)的方法名即為apply。Scala的對(duì)象也可以看成函數(shù),前提是該對(duì)象提供了apply方法apply方法和update方法update方法的調(diào)用約定:當(dāng)對(duì)帶有括號(hào)并包括一到若干參數(shù)的對(duì)象進(jìn)行賦值時(shí),編譯器將調(diào)用對(duì)象的update方法,并將括號(hào)里的參數(shù)和等號(hào)右邊的值一起作為update方法的輸入?yún)?shù)來執(zhí)行調(diào)用。2.3.3繼承

抽象類

擴(kuò)展類

類層次結(jié)構(gòu)Option類

抽象類如果一個(gè)類包含沒有實(shí)現(xiàn)的成員,則必須使用abstract關(guān)鍵詞進(jìn)行修飾,定義為抽象類。關(guān)于上面的定義,說明幾點(diǎn):

(1)定義一個(gè)抽象類,需要使用關(guān)鍵字abstract。

(2)定義一個(gè)抽象類的抽象方法,也不需要關(guān)鍵字abstract,只要把方法體空著,不寫方法體就可以。

(3)抽象類中定義的字段,只要沒有給出初始化值,就表示是一個(gè)抽象字段,但是,抽象字段必須要聲明類型,否則編譯會(huì)報(bào)錯(cuò)。

擴(kuò)展類(子類)Scala只支持單一繼承,而不支持多重繼承。在類定義中使用extends關(guān)鍵字表示繼承關(guān)系。定義子類時(shí),需要注意:重載父類的抽象成員(包括字段和方法)時(shí),override關(guān)鍵字是可選的;而重載父類的非抽象成員時(shí),override關(guān)鍵字是必選的。只能重載val類型的字段,而不能重載var類型的字段。因?yàn)関ar類型本身就是可變的,所以,可以直接修改它的值,無需重載;子類不僅僅可以派生自抽象類,還可以派生自非抽象類,如果某個(gè)類不希望被其它類派生出子類,則需要在類定義的class關(guān)鍵字前加上final關(guān)鍵字。子類如果沒有顯式地指明父類,則其默認(rèn)的父類為AnyRef。

擴(kuò)展類編譯執(zhí)行后,結(jié)果為:

類層級(jí)結(jié)構(gòu)

類層級(jí)結(jié)構(gòu)Null是所有引用類型的子類,其唯一的實(shí)例為null,表示一個(gè)“空”對(duì)象,可以賦值給任何引用類型的變量,但不能賦值給值類型的變量。Nothing是所有其它類型的子類,包括Null。Nothing沒有實(shí)例,主要用于異常處理函數(shù)的返回類型。

Option類Scala提供null是為了實(shí)現(xiàn)在JVM與其它Java庫的兼容性,但是,除非明確需要與Java庫進(jìn)行交互,否則,Scala建議盡量避免使用這種可能帶來bug的null,而改用Option類。Option是一個(gè)抽象類,有一個(gè)具體的子類Some和一個(gè)對(duì)象None,其中,前者表示有值的情形,后者表示沒有值。當(dāng)方法不確定是否有對(duì)象返回時(shí),可以讓方法Option[T],其中,T為類型參數(shù)。對(duì)于這類方法,如果確實(shí)有T類型的對(duì)象需要返回,會(huì)將該對(duì)象包裝成一個(gè)Some對(duì)象并返回;如果沒有值需要返回,將返回None。

Option類2.3.4特質(zhì)(trait)

特質(zhì)概述

特質(zhì)的定義

把特質(zhì)混入類中

把多個(gè)特質(zhì)混入類中

特質(zhì)概述Java中提供了接口,允許一個(gè)類實(shí)現(xiàn)任意數(shù)量的接口。

Scala中沒有接口的概念,而是提供了“特質(zhì)(trait)”,它不僅實(shí)現(xiàn)了接口的功能,還具備了很多其他的特性Scala的特質(zhì)是代碼重用的基本單元,可以同時(shí)擁有抽象方法和具體方法Scala中,一個(gè)類只能繼承自一個(gè)超類,卻可以實(shí)現(xiàn)多個(gè)特質(zhì),從而重用特質(zhì)中的方法和字段,實(shí)現(xiàn)了多重繼承

特質(zhì)的定義特質(zhì)的定義:使用關(guān)鍵字trait。特質(zhì)既可以包含抽象成員,也可以包含非抽象成員。包含抽象成員時(shí),也不需要abstract關(guān)鍵字。特質(zhì)可以使用extends繼承其它的特質(zhì),并且還可以繼承類。特質(zhì)的定義體就相當(dāng)于主構(gòu)造器,與類不同的是,不能給特質(zhì)的主構(gòu)造器提供參數(shù)列表,而且也不能為特質(zhì)定義輔助構(gòu)造器。

把特質(zhì)混入類中可以使用extends或with關(guān)鍵字把特質(zhì)混入類中。如果特質(zhì)中包含抽象成員,則該類必須為這些抽象成員提供具體實(shí)現(xiàn),除非該類被定義為抽象類。

把特質(zhì)混入類中特質(zhì)也可以當(dāng)做類型使用,即可以定義具有某種特質(zhì)類型的變量,并使用任何混入了相應(yīng)特質(zhì)的類的實(shí)例進(jìn)行初始化。

把特質(zhì)混入類中當(dāng)使用extends關(guān)鍵字混入特質(zhì)時(shí),相應(yīng)的類就隱式地繼承了特質(zhì)的超類。如果想把特質(zhì)混入到需要顯式指定了父類的類里,則可以用extends指明待繼承的父類,再用with混入特質(zhì)。

把多個(gè)特質(zhì)混入類中如果要混入多個(gè)特質(zhì),可以連續(xù)使用多個(gè)with。2.3.5模式匹配match語句case類的匹配match語句最常見的模式匹配是match語句,match語句用在當(dāng)需要從多個(gè)分支中進(jìn)行選擇的場(chǎng)景。通配符_相當(dāng)于Java中的default分支。match結(jié)構(gòu)中不需要break語句來跳出判斷,Scala從前往后匹配到一個(gè)分支后,會(huì)自動(dòng)跳出判斷。match語句case后面的表達(dá)式可以是任何類型的常量,而不要求是整數(shù)類型。match語句除了匹配特定的常量,還能匹配某種類型的所有值。match語句可以在match表達(dá)式的case中使用守衛(wèi)式(guard)添加一些過濾邏輯執(zhí)行結(jié)果:case類的匹配case類是一種特殊的類,它們經(jīng)過優(yōu)化以被用于模式匹配。當(dāng)定義一個(gè)類時(shí),如果在class關(guān)鍵字前加上case關(guān)鍵字,則該類稱為case類。Scala為case類自動(dòng)重載了許多實(shí)用的方法,包括toString、equals和hashcode方法。Scala為每一個(gè)case類自動(dòng)生成一個(gè)伴生對(duì)象,其包括模板代碼一個(gè)apply方法,因此,實(shí)例化case類的時(shí)候無需使用new關(guān)鍵字;一個(gè)unapply方法,該方法包含一個(gè)類型為伴生類的參數(shù),返回的結(jié)果是Option類型,對(duì)應(yīng)的類型參數(shù)是N元組,N是伴生類中主構(gòu)造器參數(shù)的個(gè)數(shù)。Unapply方法用于對(duì)對(duì)象進(jìn)行解構(gòu)操作,在case類模式匹配中,該方法被自動(dòng)調(diào)用,并將待匹配的對(duì)象作為參數(shù)傳遞給它。case類的匹配例如,假設(shè)有如下定義的一個(gè)case類:則編譯器自動(dòng)生成的伴生對(duì)象是:case類的匹配每一個(gè)case子句中的Car(…),都會(huì)自動(dòng)調(diào)用Car.unapply(car),并將提取到的值與Car后面括號(hào)里的參數(shù)進(jìn)行一一匹配比較。第一個(gè)case和第二個(gè)case是與特定的值進(jìn)行匹配。第三個(gè)case由于Car后面跟的參數(shù)是變量,因此將匹配任意的參數(shù)值。2.3.6包

包的定義

引用包成員

包的定義為了解決程序中命名沖突問題,Scala也和Java一樣采用包(package)來層次化、模塊化地組織程序。包可以包含類、對(duì)象和特質(zhì)的定義,但是不能包含函數(shù)或變量的定義。為了在任意位置訪問MyClass類,需要使用autodepartment.MyClass。Scala的包和源文件之間并沒有強(qiáng)制的一致層次關(guān)聯(lián)關(guān)系。

包的定義通過在關(guān)鍵字package后面加大括號(hào),可以將程序的不同部分放在不同的包里。這樣可以實(shí)現(xiàn)包的嵌套,相應(yīng)的作用域也是嵌套的

引用包成員可以用import子句來引用包成員,這樣可以簡(jiǎn)化包成員的訪問方式使用通配符下劃線(_)引入類或?qū)ο蟮乃谐蓡TScala隱式地添加了一些引用到每個(gè)程序前面,相當(dāng)于每個(gè)Scala程序都隱式地以如下代碼開始:2.4函數(shù)式編程基礎(chǔ)2.4.1函數(shù)定義與使用2.4.2針對(duì)集合的操作2.4.3函數(shù)式編程實(shí)例WordCount2.4.1函數(shù)定義與使用

函數(shù)式編程簡(jiǎn)介

匿名函數(shù)

占位符語法

高階函數(shù)

閉包

函數(shù)式編程簡(jiǎn)介函數(shù)式編程將計(jì)算視為數(shù)學(xué)上的函數(shù)計(jì)算函數(shù)成為了和普通的值一樣的“頭等公民”,可以像任何其他數(shù)據(jù)類型的值一樣被傳遞和操作函數(shù)式編程成為越來越流行的編程范式大數(shù)據(jù)應(yīng)用和并發(fā)需求的驅(qū)動(dòng);純函數(shù)的行為表現(xiàn)出與上下文無關(guān)的透明性和無副作用性,避免了多線程并發(fā)應(yīng)用中最復(fù)雜的狀態(tài)同步問題。Scala在架構(gòu)層面上提倡上層采用面向?qū)ο缶幊?,而底層采用函?shù)式編程。

匿名函數(shù)定義函數(shù)最通用的方法是作為某個(gè)類或者對(duì)象的成員,這種函數(shù)被稱為方法,其定義的基本語法為:def方法名(參數(shù)列表):結(jié)果類型={方法體}

匿名函數(shù)匿名函數(shù)(函數(shù)字面量):函數(shù)變量的值counter的類型是“(Int)=>Int”,表示具有一個(gè)整數(shù)類型參數(shù)并返回一個(gè)整數(shù)的函數(shù);“{value=>value+1}”為函數(shù)字面量,作為counter的初始化值,“=>”前面的value是參數(shù)名,“=>”后面是具體的運(yùn)算語句或表達(dá)式,使用類型推斷系統(tǒng),可以省略函數(shù)類型

匿名函數(shù)

占位符語法當(dāng)函數(shù)的每個(gè)參數(shù)在函數(shù)字面量?jī)?nèi)僅出現(xiàn)一次,可以省略“=>”并用下劃線“_”作為參數(shù)的占位符來簡(jiǎn)化函數(shù)字面量的表示,第一個(gè)下劃線代表第一個(gè)參數(shù),第二個(gè)下劃線代表第二個(gè)參數(shù),依此類推。

高階函數(shù)高階函數(shù):當(dāng)一個(gè)函數(shù)包含其它函數(shù)作為其參數(shù)或者返回結(jié)果為一個(gè)函數(shù)時(shí),該函數(shù)被稱為高階函數(shù)。例:假設(shè)需要分別計(jì)算從一個(gè)整數(shù)到另一個(gè)整數(shù)的“連加和”、“平方和”以及“2的冪次和”。方案一:不采用高階函數(shù)

高階函數(shù)方案二:采用高階函數(shù)

閉包閉包:當(dāng)函數(shù)的執(zhí)行依賴于聲明在函數(shù)外部的一個(gè)或多個(gè)變量時(shí),則稱這個(gè)函數(shù)為閉包。

閉包閉包可以捕獲閉包之外對(duì)自由變量的變化,反過來,閉包對(duì)捕獲變量作出的改變?cè)陂]包之外也可見。2.4.2針對(duì)容器的操作

遍歷操作

映射操作

過濾操作

規(guī)約操作

拆分操作

遍歷操作Scala容器的標(biāo)準(zhǔn)遍歷方法foreach簡(jiǎn)化寫法:“l(fā)istforeach(i=>println(i))”或“l(fā)istforeachprintln”

遍歷操作簡(jiǎn)化寫法:

映射操作映射是指通過對(duì)容器中的元素進(jìn)行某些運(yùn)算來生成一個(gè)新的容器。兩個(gè)典型的映射操作是map方法和flatMap方法。map方法(一對(duì)一映射):將某個(gè)函數(shù)應(yīng)用到集合中的每個(gè)元素,映射得到一個(gè)新的元素,map方法會(huì)返回一個(gè)與原容器類型大小都相同的新容器,只不過元素的類型可能不同。

映射操作flatMap方法(一對(duì)多映射):將某個(gè)函數(shù)應(yīng)用到容器中的元素時(shí),對(duì)每個(gè)元素都會(huì)返回一個(gè)容器(而不是一個(gè)元素),然后,flatMap把生成的多個(gè)容器“拍扁”成為一個(gè)容器并返回。返回的容器與原容器類型相同,但大小可能不同,其中元素的類型也可能不同。

過濾操作過濾:遍歷一個(gè)容器,從中獲取滿足指定條件的元素,返回一個(gè)新的容器。filter方法:接受一個(gè)返回布爾值的函數(shù)f作為參數(shù),并將f作用到每個(gè)元素上,將f返回真值的元素組成一個(gè)新容器返回。

過濾操作filterNot方法過濾出不符合條件的元素;exists方法判斷是否存在滿足給定條件的元素;find方法返回第一個(gè)滿足條件的元素。

規(guī)約操作規(guī)約操作是對(duì)容器元素進(jìn)行兩兩運(yùn)算,將其“規(guī)約”為一個(gè)值。reduce方法:接受一個(gè)二元函數(shù)f作為參數(shù),首先將f作用在某兩個(gè)元素上并返回一個(gè)值,然后再將f作用在上一個(gè)返回值和容器的下一個(gè)元素上,再返回一個(gè)值,依此類推,最后容器中的所有值會(huì)被規(guī)約為一個(gè)值。

規(guī)約操作reduceLeft和reduceRight:前者從左到右進(jìn)行遍歷,后者從右到左進(jìn)行遍歷

規(guī)約操作

規(guī)約操作fold方法:一個(gè)雙參數(shù)列表的函數(shù),從提供的初始值開始規(guī)約。第一個(gè)參數(shù)列表接受一個(gè)規(guī)約的初始值,第二個(gè)參數(shù)列表接受與reduce中一樣的二元函數(shù)參數(shù)。foldLeft和foldRight:前者從左到右進(jìn)行遍歷,后者從右到左進(jìn)行遍歷。

規(guī)約操作

拆分操作拆分操作是把一個(gè)容器里的元素按一定的規(guī)則分割成多個(gè)子容器。常用的拆分方法有partition、groupedBy、grouped和sliding。partition方法:接受一個(gè)布爾函數(shù)對(duì)容器元素進(jìn)行遍歷,以二元組的形式返回滿足條件和不滿足條件的兩個(gè)集合。groupedBy方法:接受一個(gè)返回U類型的函數(shù)對(duì)容器元素進(jìn)行遍歷,將返回值相同的元素作為一個(gè)子容器,并與該相同的值構(gòu)成一個(gè)鍵值對(duì),最后返回的是一個(gè)映射。grouped和sliding方法:接受一個(gè)整型參數(shù)n,將容器拆分為多個(gè)與原容器類型相同的子容器,并返回由這些子容器構(gòu)成的迭代器。其中,grouped按從左到右的方式將容器劃分為多個(gè)大小為n的子容器(最后一個(gè)的大小可能小于n);sliding使用一個(gè)長(zhǎng)度為n的滑動(dòng)窗口,從左到右將容器截取為多個(gè)大小為n的子容器。

拆分操作2.4.3函數(shù)式編程實(shí)例(詞頻統(tǒng)計(jì))

第3章Spark的設(shè)計(jì)與運(yùn)行原理

《Spark編程基礎(chǔ)》提綱3.1Spark概述3.2Spark生態(tài)系統(tǒng)3.3Spark運(yùn)行架構(gòu)3.4Spark的部署方式3.1Spark概述3.1.1Spark簡(jiǎn)介3.1.2Scala簡(jiǎn)介3.1.3Spark與Hadoop的比較3.1.1Spark簡(jiǎn)介Spark最初由美國(guó)加州伯克利大學(xué)(UCBerkeley)的AMP實(shí)驗(yàn)室于2009年開發(fā),是基于內(nèi)存計(jì)算的大數(shù)據(jù)并行計(jì)算框架,可用于構(gòu)建大型的、低延遲的數(shù)據(jù)分析應(yīng)用程序2013年Spark加入Apache孵化器項(xiàng)目后發(fā)展迅猛,如今已成為Apache軟件基金會(huì)最重要的三大分布式計(jì)算系統(tǒng)開源項(xiàng)目之一(Hadoop、Spark、Storm)Spark在2014年打破了Hadoop保持的基準(zhǔn)排序紀(jì)錄Spark/206個(gè)節(jié)點(diǎn)/23分鐘/100TB數(shù)據(jù)Hadoop/2000個(gè)節(jié)點(diǎn)/72分鐘/100TB數(shù)據(jù)Spark用十分之一的計(jì)算資源,獲得了比Hadoop快3倍的速度3.1.1Spark簡(jiǎn)介Spark具有如下幾個(gè)主要特點(diǎn):運(yùn)行速度快:使用DAG執(zhí)行引擎以支持循環(huán)數(shù)據(jù)流與內(nèi)存計(jì)算容易使用:支持使用Scala、Java、Python和R語言進(jìn)行編程,可以通過SparkShell進(jìn)行交互式編程通用性:Spark提供了完整而強(qiáng)大的技術(shù)棧,包括SQL查詢、流式計(jì)算、機(jī)器學(xué)習(xí)和圖算法組件運(yùn)行模式多樣:可運(yùn)行于獨(dú)立的集群模式中,可運(yùn)行于Hadoop中,也可運(yùn)行于AmazonEC2等云環(huán)境中,并且可以訪問HDFS、Cassandra、HBase、Hive等多種數(shù)據(jù)源

3.1.1Spark簡(jiǎn)介圖

谷歌趨勢(shì):Spark與Hadoop對(duì)比Spark如今已吸引了國(guó)內(nèi)外各大公司的注意,如騰訊、淘寶、百度、亞馬遜等公司均不同程度地使用了Spark來構(gòu)建大數(shù)據(jù)分析應(yīng)用,并應(yīng)用到實(shí)際的生產(chǎn)環(huán)境中3.1.2Scala簡(jiǎn)介Scala是一門現(xiàn)代的多范式編程語言,運(yùn)行于Java平臺(tái)(JVM,Java虛擬機(jī)),并兼容現(xiàn)有的Java程序Scala的特性:Scala具備強(qiáng)大的并發(fā)性,支持函數(shù)式編程,可以更好地支持分布式系統(tǒng)Scala語法簡(jiǎn)潔,能提供優(yōu)雅的APIScala兼容Java,運(yùn)行速度快,且能融合到Hadoop生態(tài)圈中

Scala是Spark的主要編程語言,但Spark還支持Java、Python、R作為編程語言Scala的優(yōu)勢(shì)是提供了REPL(Read-Eval-PrintLoop,交互式解釋器),提高程序開發(fā)效率3.1.3Spark與Hadoop的對(duì)比Hadoop存在如下一些缺點(diǎn):表達(dá)能力有限磁盤IO開銷大延遲高任務(wù)之間的銜接涉及IO開銷在前一個(gè)任務(wù)執(zhí)行完成之前,其他任務(wù)就無法開始,難以勝任復(fù)雜、多階段的計(jì)算任務(wù)

3.1.3Spark與Hadoop的對(duì)比Spark在借鑒HadoopMapReduce優(yōu)點(diǎn)的同時(shí),很好地解決了MapReduce所面臨的問題相比于HadoopMapReduce,Spark主要具有如下優(yōu)點(diǎn):Spark的計(jì)算模式也屬于MapReduce,但不局限于Map和Reduce操作,還提供了多種數(shù)據(jù)集操作類型,編程模型比HadoopMapReduce更靈活Spark提供了內(nèi)存計(jì)算,可將中間結(jié)果放到內(nèi)存中,對(duì)于迭代運(yùn)算效率更高Spark基于DAG的任務(wù)調(diào)度執(zhí)行機(jī)制,要優(yōu)于HadoopMapReduce的迭代執(zhí)行機(jī)制

3.1.3Spark與Hadoop的對(duì)比圖Hadoop與Spark的執(zhí)行流程對(duì)比3.1.3Spark與Hadoop的對(duì)比圖Hadoop與Spark執(zhí)行邏輯回歸的時(shí)間對(duì)比使用Hadoop進(jìn)行迭代計(jì)算非常耗資源Spark將數(shù)據(jù)載入內(nèi)存后,之后的迭代計(jì)算都可以直接使用內(nèi)存中的中間結(jié)果作運(yùn)算,避免了從磁盤中頻繁讀取數(shù)據(jù)3.1.3Spark與Hadoop的對(duì)比MapReduceSpark數(shù)據(jù)存儲(chǔ)結(jié)構(gòu):磁盤HDFS文件系統(tǒng)的split使用內(nèi)存構(gòu)建彈性分布式數(shù)據(jù)集RDD對(duì)數(shù)據(jù)進(jìn)行運(yùn)算和cache編程范式:Map+ReduceDAG:Transformation+Action計(jì)算中間結(jié)果落到磁盤,IO及序列化、反序列化代價(jià)大計(jì)算中間結(jié)果在內(nèi)存中維護(hù)存取速度比磁盤高幾個(gè)數(shù)量級(jí)Task以進(jìn)程的方式維護(hù),需要數(shù)秒時(shí)間才能啟動(dòng)任務(wù)Task以線程的方式維護(hù)對(duì)于小數(shù)據(jù)集讀取能夠達(dá)到亞秒級(jí)的延遲3.2Spark生態(tài)系統(tǒng)在實(shí)際應(yīng)用中,大數(shù)據(jù)處理主要包括以下三個(gè)類型:復(fù)雜的批量數(shù)據(jù)處理:通常時(shí)間跨度在數(shù)十分鐘到數(shù)小時(shí)之間基于歷史數(shù)據(jù)的交互式查詢:通常時(shí)間跨度在數(shù)十秒到數(shù)分鐘之間基于實(shí)時(shí)數(shù)據(jù)流的數(shù)據(jù)處理:通常時(shí)間跨度在數(shù)百毫秒到數(shù)秒之間當(dāng)同時(shí)存在以上三種場(chǎng)景時(shí),就需要同時(shí)部署三種不同的軟件比如:MapReduce/Impala/Storm這樣做難免會(huì)帶來一些問題:不同場(chǎng)景之間輸入輸出數(shù)據(jù)無法做到無縫共享,通常需要進(jìn)行數(shù)據(jù)格式的轉(zhuǎn)換不同的軟件需要不同的開發(fā)和維護(hù)團(tuán)隊(duì),帶來了較高的使用成本比較難以對(duì)同一個(gè)集群中的各個(gè)系統(tǒng)進(jìn)行統(tǒng)一的資源協(xié)調(diào)和分配3.2Spark生態(tài)系統(tǒng)Spark的設(shè)計(jì)遵循“一個(gè)軟件棧滿足不同應(yīng)用場(chǎng)景”的理念,逐漸形成了一套完整的生態(tài)系統(tǒng)既能夠提供內(nèi)存計(jì)算框架,也可以支持SQL即席查詢、實(shí)時(shí)流式計(jì)算、機(jī)器學(xué)習(xí)和圖計(jì)算等Spark可以部署在資源管理器YARN之上,提供一站式的大數(shù)據(jù)解決方案因此,Spark所提供的生態(tài)系統(tǒng)足以應(yīng)對(duì)上述三種場(chǎng)景,即同時(shí)支持批處理、交互式查詢和流數(shù)據(jù)處理3.2Spark生態(tài)系統(tǒng)Spark的生態(tài)系統(tǒng)主要包含了SparkCore、SparkSQL、SparkStreaming、MLLib和GraphX等組件圖BDAS架構(gòu)Spark生態(tài)系統(tǒng)已經(jīng)成為伯克利數(shù)據(jù)分析軟件棧BDAS(BerkeleyDataAnalyticsStack)的重要組成部分3.2Spark生態(tài)系統(tǒng)應(yīng)用場(chǎng)景時(shí)間跨度其他框架Spark生態(tài)系統(tǒng)中的組件復(fù)雜的批量數(shù)據(jù)處理小時(shí)級(jí)MapReduce、HiveSpark基于歷史數(shù)據(jù)的交互式查詢分鐘級(jí)、秒級(jí)Impala、Dremel、DrillSparkSQL基于實(shí)時(shí)數(shù)據(jù)流的數(shù)據(jù)處理毫秒、秒級(jí)Storm、S4SparkStreaming基于歷史數(shù)據(jù)的數(shù)據(jù)挖掘-MahoutMLlib圖結(jié)構(gòu)數(shù)據(jù)的處理-Pregel、HamaGraphX表1Spark生態(tài)系統(tǒng)組件的應(yīng)用場(chǎng)景3.3Spark運(yùn)行架構(gòu)3.3.1基本概念3.3.2架構(gòu)設(shè)計(jì)3.3.3Spark運(yùn)行基本流程3.3.4RDD的設(shè)計(jì)與運(yùn)行原理3.3.1基本概念RDD:是ResillientDistributedDataset(彈性分布式數(shù)據(jù)集)的簡(jiǎn)稱,是分布式內(nèi)存的一個(gè)抽象概念,提供了一種高度受限的共享內(nèi)存模型DAG:是DirectedAcyclicGraph(有向無環(huán)圖)的簡(jiǎn)稱,反映RDD之間的依賴關(guān)系Executor:是運(yùn)行在工作節(jié)點(diǎn)(WorkerNode)的一個(gè)進(jìn)程,負(fù)責(zé)運(yùn)行TaskApplication:用戶編寫的Spark應(yīng)用程序Task:運(yùn)行在Executor上的工作單元

Job:一個(gè)Job包含多個(gè)RDD及作用于相應(yīng)RDD上的各種操作Stage:是Job的基本調(diào)度單位,一個(gè)Job會(huì)分為多組Task,每組Task被稱為Stage,或者也被稱為TaskSet,代表了一組關(guān)聯(lián)的、相互之間沒有Shuffle依賴關(guān)系的任務(wù)組成的任務(wù)集3.3.2架構(gòu)設(shè)計(jì)圖Spark運(yùn)行架構(gòu)Spark運(yùn)行架構(gòu)包括集群資源管理器(ClusterManager)、運(yùn)行作業(yè)任務(wù)的工作節(jié)點(diǎn)(WorkerNode)、每個(gè)應(yīng)用的任務(wù)控制節(jié)點(diǎn)(Driver)和每個(gè)工作節(jié)點(diǎn)上負(fù)責(zé)具體任務(wù)的執(zhí)行進(jìn)程(Executor)資源管理器可以自帶或Mesos或YARN與HadoopMapReduce計(jì)算框架相比,Spark所采用的Executor有兩個(gè)優(yōu)點(diǎn):一是利用多線程來執(zhí)行具體的任務(wù),減少任務(wù)的啟動(dòng)開銷二是Executor中有一個(gè)BlockManager存儲(chǔ)模塊,會(huì)將內(nèi)存和磁盤共同作為存儲(chǔ)設(shè)備,有效減少IO開銷3.3.2架構(gòu)設(shè)計(jì)圖Spark中各種概念之間的相互關(guān)系一個(gè)Application由一個(gè)Driver和若干個(gè)Job構(gòu)成,一個(gè)Job由多個(gè)Stage構(gòu)成,一個(gè)Stage由多個(gè)沒有Shuffle關(guān)系的Task組成當(dāng)執(zhí)行一個(gè)Application時(shí),Driver會(huì)向集群管理器申請(qǐng)資源,啟動(dòng)Executor,并向Executor發(fā)送應(yīng)用程序代碼和文件,然后在Executor上執(zhí)行Task,運(yùn)行結(jié)束后,執(zhí)行結(jié)果會(huì)返回給Driver,或者寫到HDFS或者其他數(shù)據(jù)庫中3.3.3Spark運(yùn)行基本流程圖Spark運(yùn)行基本流程圖(1)首先為應(yīng)用構(gòu)建起基本的運(yùn)行環(huán)境,即由Driver創(chuàng)建一個(gè)SparkContext,進(jìn)行資源的申請(qǐng)、任務(wù)的分配和監(jiān)控(2)資源管理器為Executor分配資源,并啟動(dòng)Executor進(jìn)程(3)SparkContext根據(jù)RDD的依賴關(guān)系構(gòu)建DAG圖,DAG圖提交給DAGScheduler解析成Stage,然后把一個(gè)個(gè)TaskSet提交給底層調(diào)度器TaskScheduler處理;Executor向SparkContext申請(qǐng)Task,TaskScheduler將Task發(fā)放給Executor運(yùn)行,并提供應(yīng)用程序代碼(4)Task在Executor上運(yùn)行,把執(zhí)行結(jié)果反饋給TaskScheduler,然后反饋給DAGScheduler,運(yùn)行完畢后寫入數(shù)據(jù)并釋放所有資源

SparkContext對(duì)象代表了和一個(gè)集群的連接3.3.3Spark運(yùn)行基本流程總體而言,Spark運(yùn)行架構(gòu)具有以下特點(diǎn):(1)每個(gè)Application都有自己專屬的Executor進(jìn)程,并且該進(jìn)程在Application運(yùn)行期間一直駐留。Executor進(jìn)程以多線程的方式運(yùn)行Task(2)Spark運(yùn)行過程與資源管理器無關(guān),只要能夠獲取Executor進(jìn)程并保持通信即可(3)Task采用了數(shù)據(jù)本地性和推測(cè)執(zhí)行等優(yōu)化機(jī)制3.3.4RDD運(yùn)行原理1.RDD設(shè)計(jì)背景2.RDD概念3.RDD特性4.RDD之間的依賴關(guān)系5.階段的劃分6.RDD運(yùn)行過程3.3.4RDD運(yùn)行原理1.RDD設(shè)計(jì)背景許多迭代式算法(比如機(jī)器學(xué)習(xí)、圖算法等)和交互式數(shù)據(jù)挖掘工具,共同之處是,不同計(jì)算階段之間會(huì)重用中間結(jié)果目前的MapReduce框架都是把中間結(jié)果寫入到HDFS中,帶來了大量的數(shù)據(jù)復(fù)制、磁盤IO和序列化開銷RDD就是為了滿足這種需求而出現(xiàn)的,它提供了一個(gè)抽象的數(shù)據(jù)架構(gòu),我們不必?fù)?dān)心底層數(shù)據(jù)的分布式特性,只需將具體的應(yīng)用邏輯表達(dá)為一系列轉(zhuǎn)換處理,不同RDD之間的轉(zhuǎn)換操作形成依賴關(guān)系,可以實(shí)現(xiàn)管道化,避免中間數(shù)據(jù)存儲(chǔ)3.3.4RDD運(yùn)行原理2.RDD概念一個(gè)RDD就是一個(gè)分布式對(duì)象集合,本質(zhì)上是一個(gè)只讀的分區(qū)記錄集合,每個(gè)RDD可分成多個(gè)分區(qū),每個(gè)分區(qū)就是一個(gè)數(shù)據(jù)集片段,并且一個(gè)RDD的不同分區(qū)可以被保存到集群中不同的節(jié)點(diǎn)上,從而可以在集群中的不同節(jié)點(diǎn)上進(jìn)行并行計(jì)算RDD提供了一種高度受限的共享內(nèi)存模型,即RDD是只讀的記錄分區(qū)的集合,不能直接修改,只能基于穩(wěn)定的物理存儲(chǔ)中的數(shù)據(jù)集創(chuàng)建RDD,或者通過在其他RDD上執(zhí)行確定的轉(zhuǎn)換操作(如map、join和groupby)而創(chuàng)建得到新的RDD3.3.4RDD運(yùn)行原理RDD提供了一組豐富的操作以支持常見的數(shù)據(jù)運(yùn)算,分為“動(dòng)作”(Action)和“轉(zhuǎn)換”(Transformation)兩種類型RDD提供的轉(zhuǎn)換接口都非常簡(jiǎn)單,都是類似map、filter、groupBy、join等粗粒度的數(shù)據(jù)轉(zhuǎn)換操作,而不是針對(duì)某個(gè)數(shù)據(jù)項(xiàng)的細(xì)粒度修改(不適合網(wǎng)頁爬蟲)表面上RDD的功能很受限、不夠強(qiáng)大,實(shí)際上RDD已經(jīng)被實(shí)踐證明可以高效地表達(dá)許多框架的編程模型(比如MapReduce、SQL、Pregel)Spark用Scala語言實(shí)現(xiàn)了RDD的API,程序員可以通過調(diào)用API實(shí)現(xiàn)對(duì)RDD的各種操作3.3.4RDD運(yùn)行原理RDD典型的執(zhí)行過程如下:RDD讀入外部數(shù)據(jù)源進(jìn)行創(chuàng)建RDD經(jīng)過一系列的轉(zhuǎn)換(Transformation)操作,每一次都會(huì)產(chǎn)生不同的RDD,供給下一個(gè)轉(zhuǎn)換操作使用最后一個(gè)RDD經(jīng)過“動(dòng)作”操作進(jìn)行轉(zhuǎn)換,并輸出到外部數(shù)據(jù)源

圖RDD執(zhí)行過程的一個(gè)實(shí)例這一系列處理稱為一個(gè)Lineage(血緣關(guān)系),即DAG拓?fù)渑判虻慕Y(jié)果優(yōu)點(diǎn):惰性調(diào)用、管道化、避免同步等待、不需要保存中間結(jié)果、每次操作變得簡(jiǎn)單動(dòng)作轉(zhuǎn)換轉(zhuǎn)換轉(zhuǎn)換轉(zhuǎn)換轉(zhuǎn)換創(chuàng)建創(chuàng)建3.3.4RDD運(yùn)行原理Spark采用RDD以后能夠?qū)崿F(xiàn)高效計(jì)算的原因主要在于:(1)高效的容錯(cuò)性現(xiàn)有容錯(cuò)機(jī)制:數(shù)據(jù)復(fù)制或者記錄日志RDD:血緣關(guān)系、重新計(jì)算丟失分區(qū)、無需回滾系統(tǒng)、重算過程在不同節(jié)點(diǎn)之間并行、只記錄粗粒度的操作(2)中間結(jié)果持久化到內(nèi)存,數(shù)據(jù)在內(nèi)存中的多個(gè)RDD操作之間進(jìn)行傳遞,避免了不必要的讀寫磁盤開銷(3)存放的數(shù)據(jù)可以是Java對(duì)象,避免了不必要的對(duì)象序列化和反序列化3.RDD特性3.3.4RDD運(yùn)行原理4.RDD之間的依賴關(guān)系Shuffle操作什么是Shu

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論