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

下載本文檔

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

文檔簡介

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

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

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

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

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

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

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

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

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

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

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

第2章Scala語言基礎

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

—JamesGosling

2.1.4Scala的安裝和使用方法

安裝Java

安裝Scala

使用Scala解釋器

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

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

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

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

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

第1個Scala程序:HelloWorld通過編譯打包的方式運行Scala程序使用scalac命令進行編譯(編譯的結(jié)果為java字節(jié)碼)使用scala或者java運行字節(jié)碼文件2.2Scala基礎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。對于字符串,Scala用java.lang.String類來表示字符串

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

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

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

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

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

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

讀寫文件

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

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

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

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

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

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

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

{語句塊}for推導式

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

{

valf=newFileReader("input.txt")

//文件操作}

catch

{

caseex:FileNotFoundException=>

//文件不存在時的操作

caseex:IOException=>

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

{

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

Scala不支持Java中的“受檢查異?!?checkedexception),將所有異常都當作“不受檢異?!保ɑ蚍Q為運行時異常)

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

對循環(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ù)組。可以不給出數(shù)組類型,Scala會自動根據(jù)提供的初始化數(shù)據(jù)來推斷出數(shù)組的類型

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

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

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

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

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

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

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

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

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

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

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

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

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

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

類的定義

類成員的可見性

方法的定義

構(gòu)造器

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

類的定義使用new關鍵字創(chuàng)建一個類的實例。

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

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

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

方法的定義

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

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

構(gòu)造器2.3.2對象

單例對象

伴生對象

應用程序?qū)ο骯pply方法和update方法

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

單例對象---伴生對象和孤立對象當一個單例對象和它的同名類一起出現(xiàn)時,這時的單例對象被稱為這個同名類的“伴生對象”

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

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

抽象類

擴展類

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

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

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

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

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

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

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

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

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

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

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

特質(zhì)概述

特質(zhì)的定義

把特質(zhì)混入類中

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

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

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

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

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

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

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

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

包的定義

引用包成員

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

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

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

函數(shù)式編程簡介

匿名函數(shù)

占位符語法

高階函數(shù)

閉包

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

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

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

匿名函數(shù)

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

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

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

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

閉包閉包可以捕獲閉包之外對自由變量的變化,反過來,閉包對捕獲變量作出的改變在閉包之外也可見。2.4.2針對容器的操作

遍歷操作

映射操作

過濾操作

規(guī)約操作

拆分操作

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

遍歷操作簡化寫法:

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

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

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

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

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

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

規(guī)約操作

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

規(guī)約操作

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

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

第3章Spark的設計與運行原理

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

3.1.1Spark簡介圖

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

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

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

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

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

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

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

溫馨提示

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

評論

0/150

提交評論