#Spark入門#這個系列課程,是綜合於我從2017年3月分到今年7月份為止學習並使用Spark的使用心得感悟,暫定於每周更新,以后可能會上傳講課視頻和PPT,目前先在博客園把稿子打好。注意:這只是一個草稿,里面關於知識的誤解還請各大網友監督,我們互相進步。總而言之,網絡上的知識學會斷舍離,學會帶着辯證的眼光去學習就能進步。
談到Spark,實際上從16年本科實習的時候就已經開始接觸,那個時候是從Pig入門大數據Hadoop的,有興趣的朋友可以看Hadoop家族之Pig入門;當時大家基本都在使用Pig,Pig我也沒有接觸太深,大概兩個月后開始跟着當時的師父(當時是實習的碩士,后來就業去了阿里)學了Spark,整個公司就他在寫Spark,他是一個我很佩服的人,屬於全棧工程師類型的人,前后端數據分析以及數據挖掘的算法都會,所以就跟着使用Python寫着Spark的一些入門程序,可見我另外一個博客Spark2.0系列RDDVs.DataSetVs.DataFrame,實際上這里關於Dataset的介紹是非常不全面的,接下來我也會在這個Spark入門系列講的更為詳細一點。目前看來,大數據相關的職位那么吃香,很多學計算機的,學數學的,學統計的,半路上培訓的,各種各樣的人都來投Spark工程師的崗位,因為薪資高的原因吧,但是真正喜歡這個職業的又有幾個,希望大家能一直堅持下去,見證大數據技術的更新迭代!
第一個問題,什么是HadoopTM?實際上這個答案Hadoop官網已經給的很明確:
Hadoop是Apache軟件基金會支持可靠的、可擴展的一個開源的分布式計算框架的工程。(PS:Apache軟件基金會真是扛下了開源世界的半壁江山,旗下支持的開源的大數據項目大家有興趣可以去官網訪問一下。)
具體而言,Apache Hadoop軟件庫是一個允許使用簡單編程模型跨計算機集群處理大型數據集合的框架,其設計的初衷是將單個服務器擴展成上千個機器組成的一個集群為大數據提供計算服務,其中每個機器都提供本地計算和存儲服務。
Hadoop工程包括以下模塊:
- Hadoop Common:支持其他Hadoop模塊的通用工具。
- Hadoop Distributed File System(HDFSTM):提供高吞吐量的訪問應用數據的一個分布式文件系統。
- Hadoop YARN:一種作業調度和集群資源管理的框架。
- Hadoop MapReduce:一種基於Yarn來處理大數據集合的系統。
Apache中其他Hadoop相關的項目包括:
- AmbariTM:一種用於提供、管理和監督Apache Hadoop集群的基於Web UI的且易於使用的Hadoop管理工具。
- AvroTM:一種數據序列化系統。
- CassandraTM:一種無單點故障的可擴展的分布式數據庫。
- ChukwaTM:一種用於管理大型分布式系統的數據收集系統。
- HBaseTM:一種支持存儲大型表的結構化存儲的可擴展的分布式數據庫。
- HiveTM:一種提供數據匯總和特定查詢的數據倉庫。
- MahoutTM:一種可擴展的機器學習和數據挖掘庫(Scala語言實現,可結合Spark后端)。
- PigTM:一種高級的數據流語言且支持並行計算的執行框架(2017年發布的最新版本0.17.0是添加了Spark上的Pig應用)。
- SparkTM:一種用於Hadoop數據的快速通用計算引擎。Spark提供一種支持廣泛應用的簡單而易懂的編程模型,包括ETL( Extract-Transform-Load)、機器學習、流處理以及圖計算。
- TezTM:一種建立在Hadoop YARN上數據流編程框架,它提供了一個強大而靈活的引擎來任意構建DAG(Directed-acyclic-graph)任務去處理用於批處理和交互用例的數據。
- ZooKeeperTM:一種給分布式應用提供高性能的協同服務系統。
第二個問題,既然Hadoop生態家族這么龐大,我們為什么要選擇Spark作為對於大數據進行數據分析和數據挖掘的基本計算框架?
這個問題的答案實際上Spark官網已經給的很明確了,我就照樣搬磚過來。
- 速度快
Apache Spark擁有先進的DAG調度器、查詢優化器以及物理執行引擎從而高性能的實現批處理和流數據處理。
- 易用性(可以使用Java,Scala,Python,R以及SQL快速的寫Spark應用)
Spark提供80個以上高級算子便於執行並行應用,並且可以使用Scala、Python、R以及SQL的shell端交互式運行Spark應用。
#通過Spark的Python的DataFrame的API讀取JSON文件 df = spark.read.json("logs.json") df.where("age > 21").show()
- 通用性(支持SQL,流數據處理以及復雜分析)
Spark擁有一系列庫,包括SQL和DataFrame,用於機器學習的MLib,支持圖計算GraphX以及流計算模塊Streaming。你可以在一個應用中同時組合這些庫。
- 支持多種模式運行(平台包括Hadoop,Apache Mesos,Kubernete,standalone或者雲上,也可以獲取各種數據源上的數據)
Spark可以直接運行以自身的standalone集群模式運行,也可以在亞馬遜EC2上運行,不過企業級用的比較多的是Hadoop Yarn模式,當然也有Mesos和Kubernetes模式。可以獲取不限於來自於HDFS、Apache Cassandra、Apache HBase和Apache Hive等上百種數據源。
那么,第三個問題,Hadoop和Spark之間的關系是什么?
首先要從Hadoop的MapReduce編程框架說起,如果說MapReduce是第一代計算引擎,那么Spark就是第二代計算引擎。
MapReduce將復雜的並行計算過程高度的抽象到了兩個函數:Map函數和Reduce函數。
MapReduce的核心是“分而治之”策略。數據在其MapReduce的生命周期中過程中需要經過六大保護神的洗禮,分別是:Input、Split、Map、Shuffule、Reduce和Output。
MapReduce框架采用Master/Slave架構,一個Master對應多個Slave,Master運行JobTracker,Slave運行TaskTracker;JobTracker充當一個管理者,負責Client端提交的任務能夠由手下的TaskTracker執行完成,而TaskTracker充當普通員工執行的Task分為Map Task(Split and Map)和Reduce Task(Shuffle and Reduce)。
現在,我們普通的開發人員只要會用MapReduce的API就可以實現高大上的並行計算了,但是對於非科班畢業的數據分析(例如我這樣半路出家的統計學畢業)人員而言,MapReduce存在的局限性不僅僅是在於其代碼的又長又臭,固定的框架等,總而言之其短板可見以下列表:
- 抽象層次低,具體的Map和Reduce實現起來代碼量大並且對於數據挖掘算法中復雜的分析需要大量的Job來支持,且Job之間的依賴需要開發者定義,導致開發的難度高而代碼的可讀性不強;
- 中間結果也存放在HDFS文件系統中,導致中間結果不能復用(需要重新從磁盤中讀取),不適宜數據挖掘算法中的大量迭代操作,ReduceTask需要等待所有的MapTask執行完畢才可以開始;
- 只適合批處理場景,不支持交互式查詢和數據的實時處理。
要知道,我們通常意義上的Hadoop往往是Hadoop生態圈,意味着很多技術對Hadoop本身具有的局限進行了擴展和改進,從而有了Pig、Hive將SQL語言翻譯成MapReduce程序,讓我們從繁瑣的MapReduce程序中釋放出來。如果說Pig這類的類SQL語言解決了MapReduce中存在的大量手寫代碼,那么Tez就解決是去除了Map和Reduce兩個任務之間的屏障從而提升了整體的性能,從而將多個MapReduce任務在一個Tez任務中處理完。
隨着大數據處理的應用場景越來越多,人們對Hadoop的要求也越來越高,開發出的對應的系統也越來越多,人們迫切的需要一個綜合的計算框架,Spark應運而生,我們可以看看Spark可以干些什么。
那么為什么Spark能做到這些?
首先,我們需要理解Spark中的三大概念:
- RDD(Resilient Distributed Dataset)。實際上對與開發人員而已它是以一種對象的形式作為數據的一種表現形式而存在,可以理解為一種你可以操作的只讀的分布式數據集,之所以稱之為有彈性,在於:
- RDD可以在內存和磁盤存儲間手動或自動切換;
- RDD擁有Lineage(血統)信息,及存儲着它的父RDD以及父子之間的關系,當數據丟失時,可通過Lineage關系重新計算並恢復結果集,使其具備高容錯性;
- 當血統鏈太長時,用戶可以建立checkpoint將數據存放到磁盤上持久化存儲加快容錯速度(建議通過saveAsTextFile等方式存儲到文件系統),而persist方式可以將數據存儲到內存中用於后續計算的復用;
- RDD的數據重新分片可以手動設置。在Spark中執行重新分片操作的方法有repartition和coalesce兩個方法,這兩個方法都是手動設置RDD的分區數量,repartition只是coalesce接口中參數shuffle=true的實現;是否重新分區對性能影響比較大,如果分區數量大,可以減少每個分區的占存,減少OOM(內存溢出)的風險,但如果分區數量過多同時產生了過多的碎片,消耗過多的線程去處理數據,從而浪費計算資源。
- Transformations。轉換發生在當你將現有的RDD轉換成其他的RDD的時候。比如當你打開一個文件然后讀取文件內容並通過map方法將字符串類型RDD轉換成另外一個數組類型RDD就是一種轉換操作,常用的轉換操作有map,filer,flatMap,union,distinct,groupByKey等。
- Actions。動作發生在你需要系統返回一個結果的時候。比如你需要知道RDD的第一行數據是什么樣的內容,比如你想知道RDD一共有多少行這樣類似的操作就是一種動作,常用的動作操作有reduce,collect,count,first,take(),saveAsTextFile(),foreach()等。
有意思的是Spark使用“lazy evaluation”,意味着執行Transformations操作的時候實際上系統並沒有發生任何操作,只有在遇到Actions操作的時候Spark才開始真正從頭運行程序執行一系列轉換並返回結果。因為有了這種惰性求值方式加上RDD的血緣依賴關系導致程序在一系列連續的運算中形成了DAG,而這種DAG(Directed Acyclic Graph)可以優化整個執行計划(參照上圖中的Tez)。
最后再強調一下,為什么要選擇Spark?
- 首先,Spark通過RDD的lineage血統依賴關系提供了一個完備的數據恢復機制;
- 其次,Spark通過使用DAG優化整個計算過程;
- 最后,Spark對RDD進行Transformation和Action的一系列算子操作使得並行計算在粗粒度上就可以簡單執行,而且Spark生態系統提供了一系列的開發包使得數據科學家可以執行一系列的SQL、ML、Streaming以及Graph操作,而且還支持很多其他的第三方包括一些交互式框架類似於Apache Zeppelin,地理數據可視化框架GeoSpark以及一些比較流行的深度學習框架Sparking-water,Deeplearning4j,SparkNet等。
我們都知道Spark最初是由UC伯克利大學的AMP實驗室研究出來的,強烈推薦這個實驗室的Projects!Happy Coding!