Hive是一個構建在Hadoop之上的數(shù)據(jù)倉庫軟件,它可以使已經(jīng)存儲的數(shù)據(jù)結構化,它提供類似sql的查詢語句HiveQL對數(shù)據(jù)進行分析處理。
Hive將HQL轉換為MapReduce的流程
了解了MapReduce實現(xiàn)SQL基本操作之后,我們來看看Hive是如何將SQL轉化為MapReduce任務的,整個編譯過程分為六個階段:
Antlr定義SQL的語法規(guī)則,完成SQL詞法,語法解析,將SQL轉化為抽象語法樹AST Tree
遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock
遍歷QueryBlock,翻譯為執(zhí)行操作樹OperatorTree
邏輯層優(yōu)化器進行OperatorTree變換,合并不必要的ReduceSinkOperator,減少shuffle數(shù)據(jù)量
遍歷OperatorTree,翻譯為MapReduce任務
物理層優(yōu)化器進行MapReduce任務的變換,生成最終的執(zhí)行計劃
Hive與關系數(shù)據(jù)庫Mysql的區(qū)別
產(chǎn)品定位
Hive是數(shù)據(jù)倉庫,是為海量數(shù)據(jù)的離線分析設計的,不支持OLTP(聯(lián)機事務處理)所需的關鍵功能ACID,而更接近于OLAP(聯(lián)機分析技術),適合離線處理大數(shù)據(jù)集;
而MySQL是關系型數(shù)據(jù)庫,是為實時業(yè)務設計的。
可擴展性
Hive中的數(shù)據(jù)存儲在HDFS(Hadoop的分布式文件系統(tǒng)),metastore元數(shù)據(jù)一般存儲在獨立的關系型數(shù)據(jù)庫中,而MySQL則是服務器本地的文件系統(tǒng);因此Hive具有良好的可擴展性,數(shù)據(jù)庫由于ACID語義的嚴格限制,擴展性十分有限。
讀寫模式
Hive為讀時模式,數(shù)據(jù)的驗證則是在查詢時進行的,這有利于大數(shù)據(jù)集的導入,讀時模式使數(shù)據(jù)的加載非常迅速,數(shù)據(jù)的加載僅是文件復制或移動。MySQL為寫時模式,數(shù)據(jù)在寫入數(shù)據(jù)庫時對照模式檢查。寫時模式有利于提升查詢性能,因為數(shù)據(jù)庫可以對列進行索引。
數(shù)據(jù)更新
Hive是針對數(shù)據(jù)倉庫應用設計的,而數(shù)倉的內容是讀多寫少的,Hive中不支持對數(shù)據(jù)進行改寫,所有數(shù)據(jù)都是在加載的時候確定好的;而數(shù)據(jù)庫中的數(shù)據(jù)通常是需要經(jīng)常進行修改的。
索引
Hive支持索引,但是Hive的索引與關系型數(shù)據(jù)庫中的索引并不相同,比如,Hive不支持主鍵或者外鍵。Hive提供了有限的索引功能,可以為一些字段建立索引,一張表的索引數(shù)據(jù)存儲在另外一張表中。由于數(shù)據(jù)的訪問延遲較高,Hive不適合在線數(shù)據(jù)查詢;數(shù)據(jù)庫在少量的特定條件的數(shù)據(jù)訪問中,索引可以提供較低的延遲。
計算模型
Hive使用的模型是MapReduce(也可以 on spark),而MySQL使用的是自己設計的Executor計算模
Hive的數(shù)據(jù)存儲格式
Hive中的數(shù)據(jù)存儲格式分為TextFile、SequenceFile和RCFile三種,其中TextFile是默認的存儲格式,通過簡單的分隔符可以對csv等類型的文件進行解析。而ORCFile是我們常用的一種存儲格式,因為ORCFile是列式存儲格式,更加適合大數(shù)據(jù)查詢的場景。
Hive表類型
Hive幾種基本表類型:內部表、外部表、分區(qū)表、分桶表。
內部表:內部表的數(shù)據(jù),會存放在 HDFS 中的特定的位置中,我們在安裝Hive的配置中是在/hive/warehouse。;當刪除表時,數(shù)據(jù)文件也會一并刪除;適用于臨時創(chuàng)建的中間表
外部表:適用于想要在 Hive 之外使用表的數(shù)據(jù)的情況.當你刪除 External Table 時,只是刪除了表的元數(shù)據(jù),它的數(shù)據(jù)并沒有被刪除。適用于數(shù)據(jù)多部門共享。建表時使用create external table。 指定external關鍵字即可。
分區(qū)表:分區(qū)表創(chuàng)建表的時候需要指定分區(qū)字段,分區(qū)字段與普通字段的區(qū)別:分區(qū)字段會在HDFS表目錄下生成一個分區(qū)字段名稱的目錄,而普通字段則不會,查詢的時候可以當成普通字段來使用,一般不直接和業(yè)務直接相關。
分桶表:將內部表,外部表和分區(qū)表進一步組織成桶表,可以將表的列通過Hash算法進一步分解成不同的文件存儲。
對于內部表和外部表的概念和使用我們很容易理解,我們需要重點關注一下分區(qū)表和分桶表。我們?yōu)槭裁匆⒎謪^(qū)表和分桶表呢?HQL通過where字句來限制條件提取數(shù)據(jù),那么遍歷一張大表,不如將這張大表拆分成多個小表,并通過合適的索引來掃描表中的一小部分,分區(qū)和分桶都是采用了這種理念。
分區(qū)會創(chuàng)建物理目錄,并且可以具有子目錄(通常會按照時間、地區(qū)分區(qū)),目錄名以=創(chuàng)建,分區(qū)名會作為表中的偽列,這樣通過where字句中加入分區(qū)的限制可以在僅掃描對應子目錄下的數(shù)據(jù)。通過partitioned by(field1 type,…)
分桶可以繼續(xù)在分區(qū)的基礎上再劃分小表,分桶根據(jù)哈希值來確定數(shù)據(jù)的分布(即MapReducer中的分區(qū)!),比如分區(qū)下的一部分數(shù)據(jù)可以根據(jù)分桶再分為多個桶,這樣在查詢時先計算對應列的哈希值并計算桶號,只需要掃描對應桶中的數(shù)據(jù)即可。通過 clustered by( field ) into n buckets
Hive自定義函數(shù)
當Hive提供的內置函數(shù)無法滿足你的業(yè)務處理需要時,此時就可以考慮使用用戶自定義函數(shù),Hive中包含三類自定義函數(shù):
UDF:普通的用戶自定義函數(shù)。接受單行輸入,并產(chǎn)生單行輸出。如轉換字符串大小寫,獲取字符串長度等
UDAF:用戶定義聚集函數(shù)(User-defined aggregate function)。接受多行輸入,并產(chǎn)生單行輸出。比如MAX,COUNT函數(shù)。
UDTF:用戶定義表生成函數(shù)(User-defined table-generating function)。接受單行輸入,并產(chǎn)生多行輸出(即一個表),不是特別常用