1. 程式人生 > >大資料框架學習:從 Hadoop 到 Spark

大資料框架學習:從 Hadoop 到 Spark

Hadoop

1. Hadoop是什麼

Hadoop軟體庫是一個利用簡單的程式設計模型在大量計算機叢集上對大型資料集進行分散式處理的框架。

特點:部署成本低、擴充套件方便、程式設計模型簡單。

Hadoop 實現了在行業標準的伺服器上進行可靠、可縮放的分散式計算,讓你能夠以較低的預算跟蹤數 PB 以上的資料,而不必需要超級計算機和其他昂貴的專門硬體。

Hadoop 還能夠從單臺伺服器擴充套件到數千臺計算機,檢測和處理應用程式層上的故障,從而提高可靠性。

2. Hadoop的組成部分 (Hadoop 2.0)

1、Hadoop Common: The common utilities that support the other Hadoop modules.

2、Hadoop Distributed File System (HDFS:tm:): A distributed file system that provides high-throughput access to application data.

3、Hadoop YARN: A framework for job scheduling and cluster resource management.

4、Hadoop MapReduce: A YARN-based system for parallel processing of large data sets.

我們平常接觸比較多的也是 HDFS、YARN、MapReduce;

具體的場景,HDFS,比如通過客戶端訪問叢集, YARN,MapReduce,我們看提交的任務的執行情況。

3. Hadoop架構

Hadoop的發展 Hadoop1.0 vs Hadoop 2.0

在 Hadoop 1.0 時代,Hadoop 的兩大核心元件 HDFS NameNode 和 JobTracker都存在著單點問題,這其中以NameNode的單點問題尤為嚴重。因為NameNode儲存了整個HDFS的元資料資訊,一旦NameNode掛掉,整個HDFS就無法訪問,同時Hadoop生態系統中依賴於HDFS的各個元件,包括MapReduce、Hive、Pig以及HBase等也都無法正常工作,並且重新啟動NameNode和進行資料恢復的過程也會比較耗時。這些問題在給Hadoop的使用者帶來困擾的同時,也極大地限制了Hadoop的使用場景,使得Hadoop在很長的時間內僅能用作離線儲存和離線計算,無法應用到對可用性和資料一致性要求很高的線上應用場景中。 Hadoop1.0HDFS由一個NameNode和多個DataNode 組成, MapReduce的執行過程由一個JobTracker和多個TaskTracker 組成。

Hadoop2.0針對Hadoop1.0中的單NameNode制約HDFS的擴充套件性問題,提出了HDFSFederation(聯盟),它讓多個NameNode分管不同的目錄進而實現訪問隔離和橫向擴充套件,同時它徹底解決了NameNode單點故障問題。它將JobTracker中的資源管理和作業控制功能分開,分別由元件ResourceManager和ApplicationMaster實現,其中,ResourceManager負責所有應用程式的資源分配,而ApplicationMaster僅負責管理一個應用程式,進而誕生了全新的通用資源管理框架YARN。基於YARN,使用者可以執行各種型別的應用程式(不再像1.0那樣僅侷限於MapReduce一類應用),從離線計算的MapReduce到線上計算(流式處理)的Storm等YARN不僅限於MapReduce一種框架使用,也可以供其他框架使用,比如Tez、Spark、Storm。

圖 HDFS1.0

圖 HDFS2.0

Hadoop 1.0

Hadoop 2.0

這個圖裡面有Hadoop的構成,以及Hadoop相關專案的一些構成,比如Hive、Pig,Spark。它們都是依賴於MapReduce之上的,比如Hive Sql 會轉換成 MapReduce程式去執行。

4. MapReduce原理及過程

傳統的分散式程式設計(如MPI)非常複雜,使用者需要關注的細節非常多,比如資料分片、資料傳輸、節點間通訊等,因而設計分散式程式的門檻非常高。

Hadoop的一個重要設計目標便是簡化分散式程式設計,將所有並行程式均需要關注的設計細節抽象成公共模組並交由系統實現,而使用者只需專注於自己的應用程式邏輯實現,這樣簡化了分散式程式設計且提高了開發效率。

Map Task 先將對應的 split 迭代解析成一個個 key/value 對,依次呼叫使用者自定義的map()函式進行處理,最終將臨時結果存放到本地磁碟上,其中臨時資料被分成若干個partition,每個 partition 將被一個 Reduce Task 處理。

Reduce Task 執行過程如圖2-8所示。該過程分為三個階段①從遠端節點上讀取MapTask中間結果(稱為“Shuffle階段”);②按照 key 對key/value對進行排序(稱為“Sort階段”);③依次讀取 <key, valuelist>,呼叫使用者自定義的 reduce() 函式處理,並將最終結果存到HDFS上(稱為“Reduce 階段”)。

一般的場景是需要多個MapReduce進行迭代計算(如HiveSQL),Map Reduce過程都會有寫磁碟的操作,而且兩個MapReduce之間還需要訪問HDFS。

任務提交

Hadoop 1.0

Yarn

5. Hive HQL 原理

大家因為相互選擇走到了一起,然後成就了彼此。但不是天生就是為了彼此。

HiveQL通過CLI/webUI或者thrift、odbc或jdbc介面的外部介面提交,經過complier編譯器,運用Metastore中的雲資料進行型別檢測和語法分析,生成一個邏輯方案(logicalplan),然後通過簡單的優化處理,產生一個以有向無環圖DAG資料結構形式展現的map-reduce任務

整個編譯過程分為六個階段:

1、Antlr定義SQL的語法規則,完成SQL詞法,語法解析,將SQL轉化為抽象語法樹AST Tree;

2、遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock;

3、遍歷QueryBlock,翻譯為執行操作樹OperatorTree;

4、邏輯層優化器進行OperatorTree變換,合併不必要的ReduceSinkOperator,減少shuffle資料量;

5、遍歷OperatorTree,翻譯為MapReduce任務;

6、物理層優化器進行MapReduce任務的變換,生成最終的執行計劃。

TDW Hive 轉換為 MapReduce舉例:

TDW Hive Sql 轉化為 MapReduce,可以在IDE裡先看下SQL的執行計劃,每個Stage都是由一個MapReduce組成,當然,一個Stage也可能沒有Reduce。 兩個Stage之間,上一個reduce的資料會寫到HDFS上。

6、DAG計算框架 Tez

對於需要多個MapReduce作業迭代計算的場景,因為每個MapReduce都要讀寫HDFS會造成磁碟和網路IO的浪費,而Tez作為一個DAG框架,可以將多個有依賴的MapReduce作業轉化為一個作業,從而提高效能。

Spark 基於記憶體的計算框架

1、核心概念 RDD

RDD 彈性分散式資料集(RDD,Resilient Distributed Datasets),是一個容錯的、並行的資料結構,可以讓使用者顯式地將資料儲存到磁碟和記憶體中,並能控制資料的分割槽。RDD還提供了一組豐富的操作來操作這些資料。Spark對於資料的處理,都是圍繞著RDD進行的。

RDD只能通過在穩定的儲存器或其他RDD的資料上的確定性操作來建立。

val hdfsURL="hdfs://**/**/**/**/ds=20170101/*gz"
val hdfsRdd = sparkSession.sparkContext.textFile(hdfsURL)

2、RDD的操作:RDD轉換和動作

Transformation 操作是延遲計算的,也就是說從一個RDD 轉換生成另一個 RDD 的轉換操作不是馬上執行,需要等到有 Action 操作的時候才會真正觸發運算。

Action 行動運算元:這類運算元會觸發 SparkContext 提交 Job 作業。

3、執行過程

寬窄依賴

窄依賴允許在一個叢集節點上以流水線的方式(pipeline)計算所有父分割槽。例如,逐個元素地執行map、然後filter操作;而寬依賴則需要首先計算好所有父分割槽資料,然後在節點之間進行Shuffle,這與MapReduce類似。第二,窄依賴能夠更有效地進行失效節點的恢復,即只需重新計算丟失RDD分割槽的父分割槽,而且不同節點之間可以平行計算;而對於一個寬依賴關係的Lineage圖,單個節點失效可能導致這個RDD的所有祖先丟失部分分割槽,因而需要整體重新計算。

4、 與MapReduce對比,提升效率的地方

MapReduce是一個Map和一個Reduce組成一個stage,當然也有沒有reduce的stage,(如簡單的不涉及到reduce的查詢)

Spark也類似,每一個寬依賴(需要shuffle,類似Reduce)的地方就是兩個Stage的分界線。

可以看到 Spark的stage思想跟 Tez的很像,不像MapReduce那樣必須成對的MapReduce一起出現,可以在map階段做很多事情,減少不必要的網路IO和寫HDFS的時間。同時一個Stage內,資料的處理也是基於記憶體的,減少了本地磁碟的IO。

5、 DataSet 結構化的RDD

在Spark中,DataFrame是一種以RDD為基礎的分散式資料集,類似於傳統資料庫中的二維表格。DataFrame與RDD的主要區別在於,前者帶有schema元資訊,即DataFrame所表示的二維表資料集的每一列都帶有名稱和型別。這使得Spark SQL得以洞察更多的結構資訊,從而對藏於DataFrame背後的資料來源以及作用於DataFrame之上的變換進行了針對性的優化,最終達到大幅提升執行時效率的目標。反觀RDD,由於無從得知所存資料元素的具體內部結構,SparkCore只能在stage層面進行簡單、通用的流水線優化。

6、Spark 使用

SparkSQL的前身是Shark,而Shark的前身是Hadoop中的hive。

受限於絡子,目前好像只能用Scala開發。

Python Sql的任務,如果SQL支援Spark SQL的語法,會使用Spark引擎執行任務。