hive是一個著名的離線處理的數(shù)據(jù)倉庫,可以通過類SQL語言輕松的訪問大量的數(shù)據(jù)集,也可以訪問HDFS中的文件,但是其底層的實現(xiàn)是MapReduce,所以具有較高的可擴展性。但是hive不是RDBMS數(shù)據(jù)庫。
hive具有明顯的自己特色,它不支持數(shù)據(jù)更新,不支持事務和索引,但是具有了更小的分區(qū)---桶。同時其具有了并發(fā)處理大數(shù)據(jù)文件的能力。
我們可以認為Hive是MapReduce的翻譯器。
Hive的缺點
HQL并非完全是SQL語法,很多復雜的語法無法實現(xiàn),比如join操作,只支持等值連接,迭代的算法無法實現(xiàn)。
同時hive生成的mapReduce效率不會太高,基本上一個操作生成一個Map Reduce,一條語句可能生成很多Map Reduce ,一般可以使用Tez進行優(yōu)化,但是效率要求高的地方一般需要自己寫MapReduce來實現(xiàn)。
Hive架構
Hive和mySQL一樣是C/S架構
client端包括 JDBC/ODBC Client和Thrift Client兩類
Server端包括 CLI Thrift Server Metastore WUI Driver
Driver
Driver 每一個Hive服務都需要調用Driver來完成HQL語句的翻譯和執(zhí)行。通俗地說,Driver就是HQL編譯器,它解析和優(yōu)化HQL語句,將其轉換成一個Hive Job(可以是MapReduce,也可以是Spark等其他任務)并提交給Hadoop集群。
Metastore
Metastore是Hive元數(shù)據(jù)的存儲地。在功能上Metastore分為兩個部分:服務和存儲.hive服務和存儲部署的三種模式:
1.內嵌模式
內嵌模式是Hive Metastore的最簡單的部署方式,使用Hive內嵌的Derby數(shù)據(jù)庫來存儲元數(shù)據(jù)。但是Derby只能接受一個Hive會話的訪問,試圖啟動第二個Hive會話就會導致Metastore連接失敗。
2.本地模式
本地模式是Metastore的默認模式(懶人專用模式)。該模式下,單Hive會話(一個Hive 服務JVM)以組件方式調用Metastore和Driver。我們可以采用MySQL作為Metastore的數(shù)據(jù)庫。下面列出部署細節(jié):
在hive-site.xml中設置MySQL的Connection URL、用戶名和密碼以及ConnectionDriverName;
將MySQL的JDBC驅動Jar文件放到Hive的lib目錄下。
3.遠程模式
遠程模式將Metastore分離出來,成為一個獨立的Hive服務(Metastore服務還可以部署多個)。這樣的模式可以將數(shù)據(jù)庫層完全置于防火墻后,客戶就不再需要用戶名和密碼登錄數(shù)據(jù)庫,避免了認證信息的泄漏。
- hive.metastore.local false為遠程模式
- hive.metastore.uris 遠端模式下Metastore的URI列表

就如上文所示一樣Hive類似與hiveQL轉化的Mapreduce的語言解釋器。
用戶提交hiveQL會被提交給驅動器driver,驅動器將語句交給解釋器進行分析,解釋器compiler根據(jù)語句去元數(shù)據(jù)集metastore請求需要的數(shù)據(jù),元數(shù)據(jù)集給解釋器返回數(shù)據(jù),解釋器將分析好的任務再次返回啟動器,驅動器給執(zhí)行器發(fā)布執(zhí)行命令。最后執(zhí)行器根據(jù)得到的執(zhí)行機會去和hadoop集群交互。
MapReduce實現(xiàn)HiveQL
1.mapreduce實現(xiàn)join

實現(xiàn)的過程是在Map階段將來自哪個表的數(shù)據(jù)打上標簽,在reduce階段,按標簽區(qū)分不同的列,按key來進行數(shù)據(jù)的合并。
2.MapReduce實現(xiàn)groupy

在map階段將字段組合為key值,將value值設為統(tǒng)計的次數(shù),在reduce階段直接進行合并。
3.Mapreduce實現(xiàn)distinct

當只有一個distinct字段時,如果不考慮Map階段的Hash GroupBy,只需要將GroupBy字段和Distinct字段組合為map輸出key,利用mapreduce的排序,同時將GroupBy字段作為reduce的key,在reduce階段保存LastKey即可完成去重.
類似與groupby但是不執(zhí)行合并,只是取最后一個數(shù)即可。
了解了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ù)模型

分區(qū)表:
分區(qū):把數(shù)據(jù)放在不同的磁盤文件中,就認為是不同的分區(qū),數(shù)據(jù)庫對不同的分區(qū)會進行單獨的管理,優(yōu)化,最終的目的是加快我們數(shù)據(jù)查詢的速度,在hive中,把不同的分區(qū)分在表中不同的子文件夾中.
桶表:
桶表和分區(qū)表的區(qū)別在于:不是按照業(yè)務字段來進行分區(qū),對里面的記錄做一個hash,記錄做完hash之后就沒有規(guī)律了,可以簡單的認為數(shù)據(jù)做完hash之后都不相同,然后我們讓數(shù)據(jù)進行模10,數(shù)據(jù)就被分成了十份,模100就被分成100份,因為hash值幾乎各不相同,所以模后的結果,分成10份或者100份,每一份的數(shù)據(jù)量幾乎是一樣多的,當你hash之后然后模一個數(shù)字,分的那些數(shù)據(jù)量,每一份應該是差不多的,如果這樣的話,我們把這樣的數(shù)據(jù)存起來,模5,10,100 模的這個數(shù)字叫做桶,模幾就分成幾個桶,桶實際上就是模的數(shù)字,我們的記錄就被劃分到這個桶里面了,那么hive在進行查詢的時候就會按照5個桶或者10個桶來進行處理,這樣的話,好處是各個map運行的時間差不多.

Hive發(fā)展
目前Hive的底層已經變?yōu)榱薚ez,Tez相比與MapReduce有很多的優(yōu)勢,提供了多種算子,可以將多個作業(yè)合并為一個作業(yè),減少了IO,充分利用了內存的資源。

Impala
底層計算引擎不再采用MR,而是使用與商用并行關系數(shù)據(jù)庫 類似的分布式查詢引擎;
Impala可直接處理存儲在HDFS上的數(shù)據(jù),并將結果集再次寫 入HDFS;
具有良好的擴展性和容錯性;
適合快速交互式查詢