Hive和SparkSQL:基於 Hadoop 的資料倉庫工具
Hive
前言
Hive 是基於 Hadoop 的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供完整的 SQL 查詢功能,將類 SQL 語句轉換為 MapReduce 任務執行。
資料組織格式
下面是直接儲存在HDFS上的資料組織方式
- Table:每個表儲存在HDFS上的一個目錄下
- Partition(可選):每個Partition儲存再Table的子目錄下
- Bucket(可選):某個Partition根據某個列的hash值雜湊到不同的Bucket中,每個Bucket是一個檔案
使用者可以指定Partition方式和Bucket方式,使得在執行過程中可以不用掃描某些分割槽。看上去Hive是先指定Partition方式,再在相同的Partition內部呼叫hash函式;GreenPlum是先指定Hash方式,在Hash分片內部,指定不同的分割槽方式。
Hive 架構
由上圖可知,hdfs和 mapreduce 是 hive 架構的根基。
- MetaStore:儲存和管理Hive的元資料,使用關係資料庫來儲存元資料資訊。
- 直譯器和編譯器:將SQL語句生成語法樹,然後再生成DAG,成為邏輯計劃
- 優化器:只提供了基於規則的優化
- 列過濾:只查詢投影列
- 行過濾:子查詢where語句包含的partition
- 謂詞下推:減少後面的資料量
- Join方式
- Map join:一大一小的表,將小表廣播(指定後在執行前統計,沒有資料直方圖)
- shuffle join:按照hash函式,將兩張表的資料傳送給join
- sort merge join:排序,按照順序切割資料,相同的範圍傳送給相同的節點(執行前在後臺建立立兩張排序表,或者建表的時候指定)
- 執行器:執行器將DAG轉換為MR任務
Hive 特點
- Hive 最大的特點是 Hive 通過類 SQL 來分析大資料,而避免了寫 MapReduce 程式來分析資料,這樣使得分析資料更容易
- Hive 是將資料對映成資料庫和一張張的表,庫和表的元資料資訊一般存在關係型資料庫上(比如 MySQL)
- Hive 本身並不提供資料的儲存功能,資料一般都是儲存在 HDFS 上的(對資料完整性、格式要求並不嚴格)
- Hive 很容易擴充套件自己的儲存能力和計算能力,這個是繼承自 hadoop 的(適用於大規模的平行計算)
- Hive 是專為 OLAP 設計,不支援事務
Hive 流程
執行流程詳細解析
Step 1:UI(user interface) 呼叫 executeQuery 介面,傳送 HQL 查詢語句給 Driver
Step 2:Driver 為查詢語句建立會話控制代碼,並將查詢語句傳送給 Compiler, 等待其進行語句解析並生成執行計劃
Step 3 and 4:Compiler 從 metastore 獲取相關的元資料
Step 5:元資料用於對查詢樹中的表示式進行型別檢查,以及基於查詢謂詞調整分割槽,生成計劃
Step 6 (6.1,6.2,6.3):由 Compiler 生成的執行計劃是階段性的 DAG,每個階段都可能會涉及到 Map/Reduce job、元資料的操作、HDFS 檔案的操作,Execution Engine 將各個階段的 DAG 提交給對應的元件執行。
Step 7, 8 and 9:在每個任務(mapper / reducer)中,查詢結果會以臨時檔案的方式儲存在 HDFS 中。儲存查詢結果的臨時檔案由 Execution Engine 直接從 HDFS 讀取,作為從 Driver Fetch API 的返回內容。
容錯(依賴於 Hadoop 的容錯能力)
- Hive 的執行計劃在 MapReduce 框架上以作業的方式執行,每個作業的中間結果檔案寫到本地磁碟,從而達到作業的容錯性。
- 最終輸出檔案寫到 HDFS 檔案系統,利用 HDFS 的多副本機制來保證資料的容錯性。
Hive缺陷
- MapReduce:
- Map任務結束後,要寫磁碟
- 一個MapReduce任務結束後,需要將中間結果持久化到HDFS
- DAG生成MapReduce任務時,會產生無謂的Map任務
- Hadoop在啟動MapReduce任務要消耗5-10秒,需要多次啟動MapReduce任務
SparkSQL
SparkSQL在架構上和Hive類似,只是底層把MapReduce替換為Spark
除了替換底層執行引擎,SparkSQL還做了3個方面的優化
- 可以基於記憶體的列簇儲存方案
- 對SQL語句提供基於代價優化
- 資料共同分片
基於代價優化
SparkSQL會根據資料的分佈,統計分片大小,熱點資料等等的資料直方圖。根據資料直方圖可以完成:
- 根據表的大小動態改變操作符型別(join型別,aggeragate型別)
- 根據表的大小決定併發數(DAG節點分裂個數)
資料共同分片
通過建立表的時候,指定資料的分佈方式,類似於GreenPlum指定distribute。這樣join的時候不用網路交換。