Hive學(xué)習(xí)筆記

hive簡(jiǎn)介

解釋一:Hive是一個(gè)數(shù)據(jù)倉(cāng)庫(kù)基礎(chǔ)工具在Hadoop中用來(lái)處理結(jié)構(gòu)化數(shù)據(jù)皱炉。它架構(gòu)在Hadoop之上,總歸為大數(shù)據(jù),并使得查詢和分析方便另萤。并提供簡(jiǎn)單的sql查詢功能梯影,可以將sql語(yǔ)句轉(zhuǎn)換為MapReduce任務(wù)進(jìn)行運(yùn)行

解釋二:Hive 是建立在 Hadoop 上的數(shù)據(jù)倉(cāng)庫(kù)基礎(chǔ)構(gòu)架巫员。它提供了一系列的工具,可以用來(lái)進(jìn)行數(shù)據(jù)提取轉(zhuǎn)化加載(ETL)甲棍,這是一種可以存儲(chǔ)简识、查詢和分析存儲(chǔ)在 Hadoop 中的大規(guī)模數(shù)據(jù)的機(jī)制。Hive 定義了簡(jiǎn)單的類 SQL 查詢語(yǔ)言,稱為 QL七扰,它允許熟悉 SQL 的用戶查詢數(shù)據(jù)奢赂。同時(shí),這個(gè)語(yǔ)言也允許熟悉 MapReduce 開發(fā)者的開發(fā)自定義的 mapper 和 reducer 來(lái)處理內(nèi)建的 mapper 和 reducer 無(wú)法完成的復(fù)雜的分析工作颈走。

  • Hive是SQL解析引擎膳灶,它將SQL語(yǔ)句轉(zhuǎn)譯為M/R Job然后再Hadoop執(zhí)行
  • QL語(yǔ)句在底層被轉(zhuǎn)化為相應(yīng)的MapReduce操作
  • Hive的表其實(shí)就是HDFS的目錄,按表名把文件夾分開立由。如果是分區(qū)表轧钓,分區(qū)值是子文件夾,可以直接在M/R Job里使用這些數(shù)

通俗來(lái)講就是傳統(tǒng)mysql無(wú)法處理大數(shù)據(jù)锐膜,而大數(shù)據(jù)文件系統(tǒng)HDFS不能使用SQL毕箍,Hive就是一種可以用類SQL語(yǔ)句對(duì)大數(shù)據(jù)文件系統(tǒng)中的結(jié)構(gòu)化數(shù)據(jù)進(jìn)行操作的工具

Hive的系統(tǒng)架構(gòu)

Hive系統(tǒng)架構(gòu)圖

(JobTracker是Hadoop1.x中的ResouceManager + AppMaster
TaskTracker相當(dāng)于NodeManager + YarnChild)

  • 用戶接口,包括CLI道盏,JDBC/ODBC霉晕,WebUI
  • metastore,Hive將元數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中(metastore)捞奕,目前只支持 mysql牺堰、derby(Derby引擎的缺點(diǎn):一次只能打開一個(gè)會(huì)話。使用Mysql作為外置存儲(chǔ)引擎颅围,多用戶同時(shí)訪問)伟葫。Hive 中的元數(shù)據(jù)包括表名、列院促、分區(qū)及其屬性筏养、表的屬性(是否為外部表等)、表數(shù)據(jù)所在目錄等
  • Driver 解釋器常拓、編譯器渐溶、優(yōu)化器完成 HQL 查詢語(yǔ)句從詞法分析、語(yǔ)法分析弄抬、編譯茎辐、優(yōu)化以及查詢計(jì)劃(plan)的生成。生成的查詢計(jì)劃存儲(chǔ)在HDFS 中掂恕,并在隨后有 MapReduce 調(diào)用執(zhí)行
  • Hive的數(shù)據(jù)存儲(chǔ)在HDFS中拖陆,大部分的查詢由MapReduce完成(包含 * 的查詢,比如select * from tb不會(huì)生成MapReduce任務(wù))

Hive和普通關(guān)系數(shù)據(jù)庫(kù)的異同

  1. 查詢語(yǔ)言懊亡。由于SQL被廣泛的應(yīng)用在數(shù)據(jù)倉(cāng)庫(kù)中依啰,因此,專門針對(duì)Hive的特性設(shè)計(jì)了類SQL的查詢語(yǔ)言HQL店枣。熟悉SQL開發(fā)就很容易入手Hive開發(fā)速警。
  2. 數(shù)據(jù)倉(cāng)庫(kù)位置叹誉。Hive是建立在Hadoop之上的,所有Hive的數(shù)據(jù)都是存儲(chǔ)在HDFS中的闷旧。而數(shù)據(jù)庫(kù)則可以將數(shù)據(jù)保存在塊設(shè)備或者本地文件系統(tǒng)中桂对。
  3. 數(shù)據(jù)格式。 Hive中沒有定義專門的數(shù)據(jù)格式鸠匀,數(shù)據(jù)格式可以由用戶指定,用戶定義數(shù)據(jù)格式需要指定三個(gè)屬性逾柿,列分隔符(通常為空格)缀棍、行分隔符(“\n”)以及讀取文件數(shù)據(jù)的方法(Hive中默認(rèn)有三個(gè)文件格式TextFile,SequenceFile以及RCFile)。由于在加載數(shù)據(jù)的過程中机错,不需要從用戶數(shù)據(jù)格式到Hive定義的數(shù)據(jù)格式的轉(zhuǎn)換爬范,因此,Hive在加載的過程中不會(huì)對(duì)數(shù)據(jù)本身進(jìn)行任何修改弱匪,而只是將數(shù)據(jù)內(nèi)容復(fù)制或者移動(dòng)到相應(yīng)的HDFS目錄中青瀑。
  4. 數(shù)據(jù)更新。由于Hive是針對(duì)數(shù)據(jù)倉(cāng)庫(kù)應(yīng)用設(shè)計(jì)的萧诫,而數(shù)據(jù)倉(cāng)庫(kù)的內(nèi)容是讀多寫少的斥难。因此,Hive中不支持對(duì)數(shù)據(jù)的改寫和添加帘饶,所有的數(shù)據(jù)都是在加載的時(shí)候中確定好的哑诊。而數(shù)據(jù)庫(kù)中的數(shù)據(jù)通常是需要經(jīng)常進(jìn)行修改的,因此可以使用 INSERT INTO … VALUES 添加數(shù)據(jù)及刻,使用 UPDATE … SET修改數(shù)據(jù)镀裤。
  5. 索引。Hive在加載數(shù)據(jù)的過程中不會(huì)對(duì)數(shù)據(jù)進(jìn)行任何處理缴饭,甚至不會(huì)對(duì)數(shù)據(jù)進(jìn)行掃描暑劝,因此也沒有對(duì)數(shù)據(jù)中的某些Key建立索引。Hive要訪問數(shù)據(jù)中滿足條件的特定值時(shí)颗搂,需要暴力掃描整個(gè)數(shù)據(jù)担猛,因此訪問延遲較高。由于 MapReduce 的引入丢氢, Hive 可以并行訪問數(shù)據(jù)毁习,因此即使沒有索引,對(duì)于大數(shù)據(jù)量的訪問卖丸,Hive 仍然可以體現(xiàn)出優(yōu)勢(shì)纺且。數(shù)據(jù)庫(kù)中,通常會(huì)針對(duì)一個(gè)或者幾個(gè)列建立索引稍浆,因此對(duì)于少量的特定條件的數(shù)據(jù)的訪問载碌,數(shù)據(jù)庫(kù)可以有很高的效率猜嘱,較低的延遲。由于數(shù)據(jù)的訪問延遲較高嫁艇,決定了 Hive 不適合在線數(shù)據(jù)查詢朗伶。
  6. 執(zhí)行。Hive中大多數(shù)查詢的執(zhí)行是通過 Hadoop 提供的 MapReduce 來(lái)實(shí)現(xiàn)的(類似 select * from tbl的查詢不需要MapReduce)步咪。而數(shù)據(jù)庫(kù)通常有自己的執(zhí)行引擎论皆。
  7. 執(zhí)行延遲。Hive 在查詢數(shù)據(jù)的時(shí)候猾漫,由于沒有索引点晴,需要掃描整個(gè)表,因此延遲較高悯周。另外一個(gè)導(dǎo)致 Hive 執(zhí)行延遲高的因素是 MapReduce框架粒督。由于MapReduce 本身具有較高的延遲,因此在利用MapReduce 執(zhí)行Hive查詢時(shí)禽翼,也會(huì)有較高的延遲屠橄。相對(duì)的,數(shù)據(jù)庫(kù)的執(zhí)行延遲較低闰挡。當(dāng)然锐墙,這個(gè)低是有條件的,即數(shù)據(jù)規(guī)模較小长酗,當(dāng)數(shù)據(jù)規(guī)模大到超過數(shù)據(jù)庫(kù)的處理能力的時(shí) 候贮匕,Hive的并行計(jì)算顯然能體現(xiàn)出優(yōu)勢(shì)。
  8. 可擴(kuò)展性花枫。由于Hive是建立在Hadoop之上的刻盐,因此Hive的可擴(kuò)展性是和Hadoop的可擴(kuò)展性是一致的。而數(shù)據(jù)庫(kù)由于 ACID 語(yǔ)義的嚴(yán)格限制劳翰,擴(kuò)展行非常有限敦锌。目前最先進(jìn)的并行數(shù)據(jù)庫(kù) Oracle 在理論上的擴(kuò)展能力也只有100臺(tái)左右。
  9. 規(guī)模佳簸。由于Hive建立在集群上并可以利用MapReduce進(jìn)行并行計(jì)算乙墙,因此可以支持很大規(guī)模的數(shù)據(jù);對(duì)應(yīng)的生均,數(shù)據(jù)庫(kù)可以支持的數(shù)據(jù)規(guī)模較小听想。

Hive數(shù)據(jù)類型

在對(duì)Hive進(jìn)行操作之前,首先要明白Hive數(shù)據(jù)類型有哪些马胧。

  • tinyint/smallint/int/bigint
  • float/double
  • boolean
  • DECIMAL -用戶可以指定范圍和小數(shù)點(diǎn)位數(shù)
  • STRING -在特定的字符集中的一個(gè)字符串序列
  • VARCHAR -在特定的字符集中的一個(gè)有最大長(zhǎng)度限制的字符串序列
  • CHAR -在特定的字符集中的一個(gè)指定長(zhǎng)度的字符串序列
  • BINARY -一個(gè)二進(jìn)制位序列
  • 結(jié)構(gòu)體類型(Stuct): 使用點(diǎn)(.)來(lái)訪問類型內(nèi)部的元素汉买。例如,有一列c佩脊,它是一個(gè)結(jié)構(gòu)體類型{a INT; b INT}蛙粘,字段a可以使用表達(dá)式c.a來(lái)訪問垫卤。
  • Map(key-value鍵值對(duì)):使用['元素名']來(lái)訪問元素。例如出牧,有一個(gè)MapM穴肘,包含'group'->gid的映射,則gid的值可以使用M['group']來(lái)訪問舔痕。
  • 數(shù)組:數(shù)組中的元素是相同的類型评抚。可以使用[n]來(lái)訪問數(shù)組元素伯复,n是數(shù)組下標(biāo)慨代,以0開始。例如有一個(gè)數(shù)組A边翼,有元素['a','b','c'],則A[1]返回'b'鸣剪。

Hive實(shí)踐操作

配置Hive

上一階段配置CDH的時(shí)候就一起配置了Hive组底,也可以使用Apache Hadoop單獨(dú)配置
這里出現(xiàn)一個(gè)問題筐骇,hive啟動(dòng)不起來(lái)债鸡,一直等待在界面沒反應(yīng),去master:10002查看了一下hive服務(wù)铛纬,發(fā)現(xiàn)無(wú)響應(yīng)厌均,說明hive沒有啟動(dòng)起來(lái),所以去管理界面查看情況告唆,運(yùn)行狀態(tài)不良

想了一下棺弊,這個(gè)問題可能是有幾次強(qiáng)制關(guān)機(jī)造成的,只有重新安裝CDH擒悬。所以千萬(wàn)不能強(qiáng)制關(guān)掉CDH集群模她,因?yàn)檫@樣會(huì)導(dǎo)致各種各樣的玄學(xué)問題。懂牧。侈净。

建立內(nèi)表、外表

  1. 在導(dǎo)入數(shù)據(jù)到外部表僧凤,數(shù)據(jù)并沒有移動(dòng)到自己的數(shù)據(jù)倉(cāng)庫(kù)目錄下(如果指定了location的話)畜侦,也就是說外部表中的數(shù)據(jù)并不是由它自己來(lái)管理的!而內(nèi)部表則不一樣躯保;
  2. 在刪除內(nèi)部表的時(shí)候旋膳,Hive將會(huì)把屬于表的元數(shù)據(jù)和數(shù)據(jù)全部刪掉;而刪除外部表的時(shí)候途事,Hive僅僅刪除外部表的元數(shù)據(jù)溺忧,數(shù)據(jù)是不會(huì)刪除的咏连!
  3. 在創(chuàng)建內(nèi)部表或外部表時(shí)加上location 的效果是一樣的,只不過表目錄的位置不同而已鲁森,加上partition用法也一樣祟滴,只不過表目錄下會(huì)有分區(qū)目錄而已,load data local inpath直接把本地文件系統(tǒng)的數(shù)據(jù)上傳到hdfs上歌溉,有l(wèi)ocation上傳到location指定的位置上垄懂,沒有的話上傳到hive默認(rèn)配置的數(shù)據(jù)倉(cāng)庫(kù)中。

數(shù)據(jù)選擇Sogou用戶查詢語(yǔ)料信息痛垛,下載之后由于編碼有問題草慧,還需要進(jìn)行編碼轉(zhuǎn)為為utf8。
iconv -f gbk -t utf8 -c SogouQ.sample > SogouQ.sample2
因?yàn)橥獗斫⑿枰鞔_行列分隔符匙头,而數(shù)據(jù)當(dāng)中存在列分隔符不一致的情況漫谷,需要利用sed命令進(jìn)行轉(zhuǎn)換。

替換前
使用命令cat SogouQ.sample2 | sed -e 's/ /\t/g' >>Sogou可以將空格替換為\t蹂析,替換規(guī)則為sed 's/要被取代的字串/新的字串/g'再配合管道和追加到Sogou文件中就完成了替換舔示。
替換后

  • 首先和mysql一樣需要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)


  • 建立對(duì)應(yīng)的外表



  • 同時(shí)建立內(nèi)表



這里指定了外部表的具體存儲(chǔ)位置為/tmp/sogou文件夾,方便以后查看电抚。由于原始數(shù)據(jù)里行分隔符為\t惕稻,所以創(chuàng)建時(shí)要匹配為\t。

  • 導(dǎo)入數(shù)據(jù)到表
    load data local inpath '/usr/tmp/Sogou' into table sogou;這里的路徑指的是本機(jī)上的文件路徑蝙叛。
  • 查看導(dǎo)入數(shù)據(jù)情況


    外表

    內(nèi)表

外表和內(nèi)表都導(dǎo)入成功了俺祠,那么來(lái)看一下兩個(gè)表在hdfs中存儲(chǔ)位置有什么區(qū)別。

  • 刪除表



    可以看到內(nèi)表的表信息和數(shù)據(jù)全部都被刪除了借帘。



    然而外部表的數(shù)據(jù)全部都還在蜘渣。

hive sql

hive的大多數(shù)查詢都會(huì)轉(zhuǎn)化為MapReduce程序,可以導(dǎo)master:8088查看相應(yīng)的MapReduce程序肺然。


  • group by
    group by和sql里面的使用方法相似宋梧,都是用于對(duì)某個(gè)或多個(gè)列的值進(jìn)行分組查詢。
    select rank,count(url) from sogou group by rank having rank < 10;用于查詢排名前10的url個(gè)數(shù)
  1. select后面的非聚合列必須出現(xiàn)在group by中(比如上面的rank)
  2. 除了普通列就是一些聚合操作(比如上面的count(rank))
  • Order by
    Order by會(huì)對(duì)輸入做全局排序狰挡,因此只有一個(gè)Reducer(多個(gè)Reducer無(wú)法保證全局有序)捂龄,然而只有一個(gè)Reducer,會(huì)導(dǎo)致當(dāng)輸入規(guī)模較大時(shí)加叁,消耗較長(zhǎng)的計(jì)算時(shí)間倦沧。
    Order by語(yǔ)法如下:
select col,col2...  
from tableName  
where condition  
order by col1,col2 [asc|desc] 
  1. order by后面可以有多列進(jìn)行排序,默認(rèn)按字典排序它匕。
  2. order by為全局排序展融。
  3. order by需要reduce操作,且只有一個(gè)reduce豫柬,無(wú)法配置(因?yàn)槎鄠€(gè)reduce無(wú)法完成全局排序)告希。
    select * from sogou order by rank desc limit 5;獲取排名前5的所有信息
  • sort by
    hive使用order by會(huì)默認(rèn)設(shè)置reduce的個(gè)數(shù)=1扑浸,既然reducer的個(gè)數(shù)都是1了,結(jié)果自然全排序燕偶!但是reducer個(gè)數(shù)為1會(huì)導(dǎo)致效率非常的低喝噪,所以提供了一個(gè)新的排序方式sort by。
    它會(huì)保證每個(gè)reducer的輸出文件是有序的指么,要想實(shí)現(xiàn)全排序酝惧,還得加一個(gè)order by的過程,就是對(duì)sort by的reduce輸出結(jié)果再進(jìn)行一次排序伯诬。要想用hive實(shí)現(xiàn)全排序:要么用order by晚唇,但這樣默認(rèn)了reducer個(gè)數(shù)為1,效率低下盗似。要么用sort by+order by哩陕,sort by過程可以設(shè)置reducer個(gè)數(shù)(n),order by過程用n個(gè)reducer的輸出文件進(jìn)行一次全排序赫舒,得到最終的結(jié)果悍及。
    select * from sogou sort by rank desc limit 5;這里是對(duì)rank進(jìn)行排序,但是不是全局排序号阿,而是對(duì)每一個(gè)reducer內(nèi)部進(jìn)行排序并鸵,那么怎樣hive如何將所有數(shù)據(jù)劃分給若干個(gè)reducer呢鸳粉?這就要用到下面的distribute了扔涧。
  • distribute by
    distribute by是控制map的輸出在reducer是如何劃分的。hive會(huì)根據(jù)distribute by后面列届谈,對(duì)應(yīng)reduce的個(gè)數(shù)進(jìn)行分發(fā)枯夜,默認(rèn)是采用hash算法。舉個(gè)例子
    select * from sogou distribute by rank sort by rank,time desc limit 5;

表示將rank哈希后(這里并不是簡(jiǎn)單的把rank相同的數(shù)據(jù)劃分為一個(gè)cluster艰山,而是對(duì)rank值哈希后再對(duì)cluster個(gè)數(shù)進(jìn)行求余)相同的數(shù)據(jù)全部送到一個(gè)reducer進(jìn)行處理湖雹,這就是因?yàn)橹付薲istribute by rank,再配合sort by這樣的話就可以統(tǒng)計(jì)出每個(gè)rank排名中所有數(shù)據(jù)的時(shí)間順序了曙搬。這里需要注意的是distribute by必須要寫在sort by之前摔吏。

  • cluster by
    cluster by的功能就是distribute by和sort by相結(jié)合,如下2組語(yǔ)句是等價(jià)的:
    select * from sogou cluster by rank
    select * from sogou cluster by distribute by rank sort by rank

注意被cluster by指定的列只能是升序纵装,不能指定asc和desc征讲。

Java、Python調(diào)用Hive

和下面Python調(diào)用一樣橡娄,只需要下載相應(yīng)的jar诗箍,跟著官方文檔即可。

pyhive

首先安裝連接hive需要的依賴

pip install sasl
pip install thrift
pip install thrift-sasl
pip install PyHive

然后就可以按照固定的格式開啟連接了

from pyhive import hive

conn = hive.Connection(host='192.168.233.100',port=10000,username='root',database='mytest')
cursor = conn.cursor()
cursor.execute('select * from sogou limit 10')
for result in cursor.fetchall():
    print(result)

但是報(bào)錯(cuò)了
thrift.transport.TTransport.TTransportException: Could not start SASL: b'Error in sasl_client_start (-4) SASL(-4): no mechanism available: Unable to find a callback: 2'
查看hive的日志
java.lang.RuntimeException: org.apache.thrift.transport.TSaslTransportException: No data or no sasl data in the stream
網(wǎng)上找了一下也沒什么好的解決方案挽唉,看這個(gè)報(bào)錯(cuò)信息應(yīng)該是windows系統(tǒng)底層的問題滤祖,所以換到centos里執(zhí)行剛剛的python程序筷狼。
成功連接hive并得到查詢結(jié)果。

Java Hive

UDF匠童、UDAF埂材、UDTF

Hive中,除了提供豐富的內(nèi)置函數(shù)之外俏让,還允許用戶使用Java開發(fā)自定義的UDF函數(shù)楞遏。UDF有幾種:

  • (普通)UDF:操作作用于單個(gè)數(shù)據(jù)行,且產(chǎn)生一個(gè)數(shù)據(jù)行作為輸出首昔。
  • 用戶自定義聚合函數(shù)(UDAF):接受多個(gè)輸入數(shù)據(jù)行寡喝,并產(chǎn)生一個(gè)輸出數(shù)據(jù)行。
  • 用戶自定義生表函數(shù)(UDTF):接受一個(gè)數(shù)據(jù)行勒奇,然后返回產(chǎn)生多個(gè)數(shù)據(jù)行

開發(fā)自定義UDF函數(shù)有兩種方式
繼承org.apache.hadoop.hive.ql.exec.UDF
繼承org.apache.hadoop.hive.ql.udf.generic.GenericUDF预鬓;
如果是針對(duì)簡(jiǎn)單的數(shù)據(jù)類型(比如String、Integer等)可以使用UDF赊颠,如果是針對(duì)復(fù)雜的數(shù)據(jù)類型(比如Array格二、Map、Struct等)竣蹦,可以使用GenericUDF顶猜,另外,GenericUDF還可以在函數(shù)開始之前和結(jié)束之后做一些初始化和關(guān)閉的處理操作痘括。

UDF

使用自定義UDF時(shí)长窄,只需要繼承org.apache.hadoop.hive.ql.exec.UDF,并定義public Object evaluate(Object args) {} 方法即可纲菌。例如:

package li;


import org.apache.hadoop.hive.ql.exec.UDF;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashMd5 {
    public String evaluate(String password) {
        try {
            // 得到一個(gè)信息摘要器
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[] result = digest.digest(password.getBytes());
            StringBuffer buffer = new StringBuffer();
            // 把每一個(gè)byte 做一個(gè)與運(yùn)算 0xff;
            for (byte b : result) {
                // 與運(yùn)算
                int number = b & 0xff;// 加鹽
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }

            // 標(biāo)準(zhǔn)的md5加密后的結(jié)果
            return buffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }

    }
}

evaluate方法就是要進(jìn)行處理的函數(shù)內(nèi)容挠日。這個(gè)函數(shù)的意思是將輸入的內(nèi)容轉(zhuǎn)為它的MD5值。
用IDEA把剛剛寫好的Java文件打成jar包(這里特別需要注意編譯成jar包的環(huán)境JDK要和hive平臺(tái)的JDK一致翰舌,所以我把JDK變?yōu)榱?.6)


然后就可以在hive交互界面使用命令add jar /usr/tmp/myudf.jar
這里的路徑是把jar包存放在linux文件下的路徑嚣潜。
接著生成函數(shù)方法
create temporary function md5 as 'li.HashMd5';
因?yàn)槲抑皇菫榱藴y(cè)試,所以用的temporary椅贱,表示該方法的作用時(shí)間只是這次session懂算,as后面跟著的是你寫入自定義函數(shù)的類的完整類名
隨后就可以寫測(cè)試hive sql來(lái)看看是否成功了。
select rank,md5(rank) from sogou limit 10;
這里第一次報(bào)錯(cuò)了
Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:dr
錯(cuò)誤顯示想要訪問/user下的內(nèi)容庇麦,但是權(quán)限不夠计技,因?yàn)槲沂窃趓oot用戶下進(jìn)入的hive交互界面,所以有些文件不能執(zhí)行操作女器,所以切換至hdfs用戶就可以了酸役。

這里可以看到同樣的值得到了同樣的MD5值,所以驗(yàn)證成功。

UDAF

UDAF 接受多個(gè)輸入數(shù)據(jù)行涣澡,并產(chǎn)生一個(gè)輸出數(shù)據(jù)行贱呐。
一個(gè)計(jì)算函數(shù)必須實(shí)現(xiàn)以下5個(gè)方法:

  • init(): 該方法負(fù)責(zé)初始化計(jì)算函數(shù)并重設(shè)它的內(nèi)部狀態(tài) 。
  • iterate(): 每次對(duì)一個(gè)新值進(jìn)行聚合計(jì)算時(shí)會(huì)調(diào)用該方法入桂。
  • terminatePartial(): Hive需要部分聚合結(jié)果時(shí)會(huì)調(diào)用該方法奄薇。
  • merge(): Hive需要將部分聚合結(jié)果和另外部分聚合結(jié)果合并時(shí)會(huì)調(diào)用該方法。
  • terminate(): 需要最終結(jié)果時(shí)會(huì)調(diào)用該方法



    和上面自定義UDF的方法類似抗愁,也是編寫代碼后臺(tái)添加功能馁蒂。

package li;


import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.FloatWritable;

@SuppressWarnings("deprecation")
public class Mean extends UDAF {
    public static class MeanFloatUDAFEvaluator implements UDAFEvaluator {
        public static class PartialResult {
            float sum;
            long count;
        }

        private PartialResult partialresult;

        @Override
        public void init() {
            // TODO Auto-generated method stub
            partialresult = null;
        }

        public boolean iterate(FloatWritable value) {
            if (value == null) {
                return true;
            }
            if (partialresult == null) {
                partialresult = new PartialResult();
            }

            partialresult.sum += value.get();
            ++partialresult.count;
            return true;
        }

        public PartialResult terminatePartial() {
            return partialresult;
        }

        public boolean merge(PartialResult other) {
            if (other == null) {
                return true;
            }
            if (partialresult == null) {
                partialresult = new PartialResult();
            }

            partialresult.sum += other.sum;
            partialresult.count += other.count;

            return true;
        }

        public FloatWritable terminate() {
            if (partialresult == null) {
                return null;
            }
            return new FloatWritable(partialresult.sum / partialresult.count);
        }
    }
}

然后添加jar和臨時(shí)方法
add jar /usr/tmp/myudf.jar
create temporary function my_mean as 'li.Mean';
可以再show functions里面看到自己的方法了。

分區(qū)蜘腌、分桶

Hive使用select語(yǔ)句進(jìn)行查詢的時(shí)候一般會(huì)掃描整個(gè)表內(nèi)容沫屡,會(huì)消耗很多時(shí)間做沒必要的工作。Hive可以在創(chuàng)建表的時(shí)候指定分區(qū)空間撮珠,這樣在做查詢的時(shí)候就可以很好的提高查詢的效率沮脖。
Hive中的每個(gè)分區(qū)對(duì)應(yīng)數(shù)據(jù)庫(kù)中相應(yīng)分區(qū)列的一個(gè)索引,每個(gè)分區(qū)對(duì)應(yīng)著表下的一個(gè)目錄芯急,在HDFS上的表現(xiàn)形式與表在HDFS上的表現(xiàn)形式相同勺届,都是以子目錄的形式存在。

  • 創(chuàng)建分區(qū)表
 create table t1(
    > id int,
    > name string
    > )
    > partitioned by (pt varchar(8))
    > ;

這里表示將字段pt作為分區(qū)的目標(biāo)字段

  • 裝載數(shù)據(jù)進(jìn)分區(qū)表
    首先創(chuàng)建測(cè)試數(shù)據(jù)data
1,a
2,b
3,c

load data local inpath '/usr/tmp/data' overwrite into table t1 partition (pt='001');
所有數(shù)據(jù)都被裝載到分區(qū)001中去了娶耍;再次將數(shù)據(jù)裝載進(jìn)分區(qū)002中去免姿。
load data local inpath '/usr/tmp/data' overwrite into table t1 partition (pt='002');


通過這里可以看出成功將數(shù)據(jù)裝載進(jìn)了不同的分區(qū),下面再看一下在HDFS中分區(qū)是如何實(shí)現(xiàn)的榕酒。
進(jìn)入到hive默認(rèn)存儲(chǔ)地址/user/hive/warehouse

在這里我們可以清晰的看到hive首先為這個(gè)數(shù)據(jù)庫(kù)創(chuàng)建了一個(gè)文件夾胚膊,然后為每一個(gè)分區(qū)創(chuàng)建一個(gè)子目錄,將屬于各自分區(qū)的數(shù)據(jù)就存放在各自分區(qū)的目錄下奈应。

也可以查看有哪些分區(qū)和刪除指定分區(qū)(會(huì)同時(shí)刪除分區(qū)中數(shù)據(jù))

hive>partitions t1;
OK
pt=001
pt=002
hive> alter table t1 drop partition(pt=001);
Dropped the partition pt=001
OK

對(duì)于每一個(gè)表或者是分區(qū)澜掩,Hive可以進(jìn)一步組織成购披,也就是說桶是更為細(xì)粒度的數(shù)據(jù)范圍劃分杖挣。Hive是針對(duì)某一列進(jìn)行分桶。Hive采用對(duì)列值哈希刚陡,然后除以桶的個(gè)數(shù)求余的方式?jīng)Q定該條記錄存放在哪個(gè)桶中惩妇。分桶的好處是可以獲得更高的查詢處理效率。使取樣更高效筐乳。分桶比分區(qū)歌殃,更高的查詢效率。

  • 建立桶表
create table bucket_test(
     id int,
     name string
     )
     clustered by(id) into 4 buckets
     row format delimited fields terminated by '\t'
     sorted as textfile;

裝入數(shù)據(jù)
load data local inpath '/usr/tmp/data' overwrite into table bucket_test;


數(shù)據(jù)成功裝入后蝙云,就去目錄中看一看桶的結(jié)構(gòu)氓皱。發(fā)現(xiàn)分桶沒有成功。查了一下資料,說是設(shè)置hive分桶為true
set hive.enforce.bucketing = true;
但是還是不行波材。仔細(xì)思考了一下股淡,應(yīng)該是導(dǎo)入數(shù)據(jù)的方式有問題,我這里用load導(dǎo)入數(shù)據(jù)使得hive可能不會(huì)逐一檢索數(shù)據(jù)并根據(jù)哈希值存入桶廷区,應(yīng)該用insert方式導(dǎo)入數(shù)據(jù)唯灵,hive才會(huì)逐一根據(jù)數(shù)據(jù)指定列的哈希值存入不同的桶。

insert overwrite table bucketed_user
    > select id,name from t1;

這樣就將數(shù)據(jù)庫(kù)分為了4個(gè)桶隙轻。仔細(xì)觀察會(huì)發(fā)現(xiàn)每個(gè)桶不是文件夾埠帕,而是文件,這點(diǎn)和分區(qū)不一樣玖绿。當(dāng)從桶表中進(jìn)行查詢時(shí)敛瓷,hive會(huì)根據(jù)分桶的字段進(jìn)行計(jì)算分析出數(shù)據(jù)存放的桶中,然后直接到對(duì)應(yīng)的桶中去取數(shù)據(jù)斑匪,這樣做就很好的提高了效率琐驴。

  • 索引和分區(qū)最大的區(qū)別就是索引不分割數(shù)據(jù)庫(kù),分區(qū)分割數(shù)據(jù)庫(kù)秤标。
  • 分區(qū)和分桶最大的區(qū)別就是分桶隨機(jī)分割數(shù)據(jù)庫(kù)绝淡,分區(qū)是非隨機(jī)分割數(shù)據(jù)庫(kù)。
  • 其次兩者的另一個(gè)區(qū)別就是分桶是對(duì)應(yīng)不同的文件(細(xì)粒度)苍姜,分區(qū)是對(duì)應(yīng)不同的文件夾(粗粒度)牢酵。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市衙猪,隨后出現(xiàn)的幾起案子馍乙,更是在濱河造成了極大的恐慌蕴掏,老刑警劉巖撩银,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嵌言,死亡現(xiàn)場(chǎng)離奇詭異央渣,居然都是意外死亡青自,警方通過查閱死者的電腦和手機(jī)嫂侍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門当叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)破喻,“玉大人订咸,你說我怎么就攤上這事曼尊。” “怎么了脏嚷?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵骆撇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我父叙,道長(zhǎng)神郊,這世上最難降的妖魔是什么肴裙? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮涌乳,結(jié)果婚禮上践宴,老公的妹妹穿的比我還像新娘。我一直安慰自己爷怀,他們只是感情好阻肩,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著运授,像睡著了一般烤惊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吁朦,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天柒室,我揣著相機(jī)與錄音,去河邊找鬼逗宜。 笑死雄右,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纺讲。 我是一名探鬼主播擂仍,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼熬甚!你這毒婦竟也來(lái)了逢渔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乡括,失蹤者是張志新(化名)和其女友劉穎肃廓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诲泌,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盲赊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敷扫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哀蘑。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呻澜,靈堂內(nèi)的尸體忽然破棺而出递礼,到底是詐尸還是另有隱情惨险,我是刑警寧澤羹幸,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站辫愉,受9級(jí)特大地震影響栅受,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一屏镊、第九天 我趴在偏房一處隱蔽的房頂上張望依疼。 院中可真熱鬧,春花似錦而芥、人聲如沸律罢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)误辑。三九已至,卻和暖如春歌逢,著一層夾襖步出監(jiān)牢的瞬間巾钉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工秘案, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砰苍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓阱高,卻偏偏與公主長(zhǎng)得像赚导,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赤惊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容