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

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

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

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

當(dāng)只有一個(gè)distinct字段時(shí),如果不考慮Map階段的Hash GroupBy,只需要將GroupBy字段和Distinct字段組合為map輸出key,利用mapreduce的排序,同時(shí)將GroupBy字段作為reduce的key,在reduce階段保存LastKey即可完成去重.
類(lèi)似與groupby但是不執(zhí)行合并,只是取最后一個(gè)數(shù)即可。
了解了MapReduce實(shí)現(xiàn)SQL基本操作之后,我們來(lái)看看Hive是如何將SQL轉(zhuǎn)化為MapReduce任務(wù)的,整個(gè)編譯過(guò)程分為六個(gè)階段:
Antlr定義SQL的語(yǔ)法規(guī)則,完成SQL詞法,語(yǔ)法解析,將SQL轉(zhuǎn)化為抽象語(yǔ)法樹(shù)AST Tree
遍歷AST Tree,抽象出查詢(xún)的基本組成單元QueryBlock
遍歷QueryBlock,翻譯為執(zhí)行操作樹(shù)OperatorTree
邏輯層優(yōu)化器進(jìn)行OperatorTree變換,合并不必要的ReduceSinkOperator,減少shuffle數(shù)據(jù)量
遍歷OperatorTree,翻譯為MapReduce任務(wù)
物理層優(yōu)化器進(jìn)行MapReduce任務(wù)的變換,生成最終的執(zhí)行計(jì)劃
Hive數(shù)據(jù)模型

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

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

Impala
底層計(jì)算引擎不再采用MR,而是使用與商用并行關(guān)系數(shù)據(jù)庫(kù) 類(lèi)似的分布式查詢(xún)引擎;
Impala可直接處理存儲(chǔ)在HDFS上的數(shù)據(jù),并將結(jié)果集再次寫(xiě) 入HDFS;
具有良好的擴(kuò)展性和容錯(cuò)性;
適合快速交互式查詢(xún)