Hive: 基於 Hadoop 的數據倉庫工具
前言
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 架構
由上圖可知,hadoop 和 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的時候不用網絡交換。