Hive知識(shí)匯總

兩種Hive表

hive存儲(chǔ):數(shù)據(jù)+元數(shù)據(jù)

托管表(內(nèi)部表)

創(chuàng)建表:

hive> create table test2(id int,name String,tel String)
    > ROW FORMAT DELIMITED
    > FIELDS TERMINATED BY ',';

準(zhǔn)備數(shù)據(jù)文件my.txt

1,scc0,20,131888888888
2,scc1,22,13222222222
3,scc2,21,183938384983

灌數(shù)據(jù):

load data local inpath '/usr/local/src/my.txt' into table test2;

查看數(shù)據(jù):

hive> select * from test2;
OK
1   scc0    20
2   scc1    22
3   scc2    21
Time taken: 0.132 seconds, Fetched: 3 row(s)

hdfs中的warehouse文件夾下面會(huì)多一個(gè)文件夾叫做test2。里面的文件名叫做my.txt
刪除表:

hive> drop table test2;
OK
Time taken: 0.43 seconds

warehouse文件夾下的test2以及里面的所有文件被刪除。內(nèi)部表刪除會(huì)同時(shí)刪除元數(shù)據(jù)和數(shù)據(jù)文件。在建表的時(shí)候可以指定location,創(chuàng)建的內(nèi)部表默認(rèn)是存在warehouse/[tablename],也可以指定目錄存放。

create table test2(id int,name String,tel String) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' location '/scc/tmpdir';

外部表

創(chuàng)建表:
多加一個(gè)關(guān)鍵詞external

create table test3(id int,name String,tel String) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

也可以指定location。默認(rèn)還是放在warehouse/[tablename]
灌數(shù)據(jù)方式同上。
查看方式同上。
刪除命令同上:
刪除后查詢:

hive> show tables;
OK
haha
Time taken: 0.034 seconds, Fetched: 1 row(s)

表中已經(jīng)不再存在test3, 但是HDFS中的目錄以及文件均存在。說明外部表在刪除的時(shí)候僅僅刪除了元數(shù)據(jù),并未刪除存儲(chǔ)文件。

分區(qū)和桶

表大于分區(qū)大于桶
參考此鏈接

1. 先說分區(qū)

在HDFS中,分區(qū)的表現(xiàn)為表的子目錄。
在創(chuàng)建分區(qū)的命令上,分區(qū)表現(xiàn)為指定分區(qū)partitioned by (partitio-name string)
在查詢方式上,分區(qū)就相當(dāng)于表的字段。

創(chuàng)建帶分區(qū)(以時(shí)間time為分區(qū))的表:
create table tbhaspar(id int,name string,tel string) partitioned by(time string)  row format delimited fields terminated by ',';
準(zhǔn)備數(shù)據(jù):

(下面數(shù)據(jù)中不含time字段,也可以帶有time字段,如果按照下面灌數(shù)據(jù)的方式,帶有的time字段的數(shù)據(jù)會(huì)被分區(qū)名覆蓋掉)

1,scc0,131888888888
2,scc1,13222222222
3,scc2,183938384983
4,scc3,16222232222
5,scc4,17222222222
灌數(shù)據(jù):
load data local inpath '/usr/local/src/my.txt' into table tbhaspar partition (time='03-01'); 
load data local inpath '/usr/local/src/my.txt' into table tbhaspar partition (time='03-02'); 
load data local inpath '/usr/local/src/my.txt' into table tbhaspar partition (time='03-03'); 
查詢

(創(chuàng)建表的時(shí)候指定了3個(gè)字段1個(gè)分區(qū),接下來的查詢結(jié)果就好像是看到了4個(gè)字段):

hive> select * from tbhaspar;
OK
1   scc0    131888888888    03-01
2   scc1    13222222222 03-01
3   scc2    183938384983    03-01
4   scc3    16222232222 03-01
5   scc4    17222222222 03-01
1   scc0    131888888888    03-02
2   scc1    13222222222 03-02
3   scc2    183938384983    03-02
4   scc3    16222232222 03-02
5   scc4    17222222222 03-02
1   scc0    131888888888    03-03
2   scc1    13222222222 03-03
3   scc2    183938384983    03-03
4   scc3    16222232222 03-03
5   scc4    17222222222 03-03
Time taken: 0.081 seconds, Fetched: 15 row(s)

查看表信息:
hive> describe tbhaspar;
OK
id                      int                                         
name                    string                                      
tel                     string                                      
time                    string                                      
         
# Partition Information      
# col_name              data_type               comment             
         
time                    string                                      
Time taken: 0.09 seconds, Fetched: 9 row(s)

指定分區(qū)查詢

(下面的查詢方式,好像分區(qū)真的是一個(gè)字段):

select * from tbhaspar where time = '03-01';

對(duì),上面說的都是靜態(tài)分區(qū),下面看看動(dòng)態(tài)分區(qū)。

動(dòng)態(tài)分區(qū)

可以根據(jù)查詢得到的數(shù)據(jù)動(dòng)態(tài)分配到分區(qū)里。其實(shí)動(dòng)態(tài)分區(qū)與靜態(tài)分區(qū)區(qū)別就是不指定分區(qū)目錄,由系統(tǒng)自己選擇。
該功能需要手動(dòng)開啟:

hive> set hive.exec.dynamic.partition=true;
  1. 創(chuàng)建一個(gè)跟剛才一樣的分區(qū)表id,name,tel partition=time
  2. 灌數(shù)據(jù)。灌數(shù)據(jù)的方式只能通過從別的表查詢得到,不能直接從local文件加載。我們下面從剛才的靜態(tài)分區(qū)表進(jìn)行加載(當(dāng)然我們此時(shí)把分區(qū)表當(dāng)成未分區(qū)表來用,現(xiàn)實(shí)中都是先把數(shù)據(jù)加載到普通表,然后再讀取并加載到動(dòng)態(tài)分區(qū)中)。
hive> insert  overwrite  table  tbhasdypar partition(time) select * from tbhaspar; 

執(zhí)行完就開始調(diào)MR了。。等一會(huì)兒看結(jié)果!直接就分區(qū)了!很帥!


image

2. 再說桶

桶是更細(xì)粒度的數(shù)據(jù)范圍劃分。桶的作用體現(xiàn)之一:MR階段可以大大減少Join操作(別人這么說的,我不知道)。
Hive采用對(duì)列值哈希,然后除以桶的個(gè)數(shù)求余的方式?jīng)Q定該條記錄存放在哪個(gè)桶當(dāng)中。

建一個(gè)帶桶的表

按照id分成3個(gè)桶。

hive> create table buck2 (id int,name string) clustered by (id) sorted by(id) into 3 buckets row format delimited fields terminated by ',' stored as textfile;  
灌數(shù)據(jù)

先看一眼我們要灌的數(shù)據(jù)

image
hive> insert overwrite table buck2 select id,name from tbhaspar;
看結(jié)果

看結(jié)果之前,先設(shè)置一下這個(gè):

set mapreduce.job.reduces=4;

為什么?因?yàn)榉謪^(qū)的效果就是在MapReduce中體現(xiàn)出來的。我們?cè)O(shè)置多個(gè)Reduce觀察一下排序結(jié)果。

image

HDFS的buck2下面多了三個(gè)文件夾,對(duì)應(yīng)值hash得到的三種余數(shù)。
執(zhí)行:

hive> select * from buck2 ;

下圖結(jié)果中,正好是三個(gè)桶,而且是hash分桶,很明顯。

image

上面是一個(gè)無序結(jié)果。下面的命令可以查看有序的結(jié)果。會(huì)在每個(gè)reduce里面排序。

hive> select * from buck2 sort by id ;

Hive避免MapReduce

把這個(gè)屬性設(shè)置為true

hive.exec.mode.local.auto=true

hive在運(yùn)行的時(shí)候嘗試先使用本地模式運(yùn)行 否則幾乎所有的操作都會(huì)觸發(fā)MR

分區(qū)查詢-strict嚴(yán)格模式

hive.mapred.mode=strict

上述參數(shù) 嚴(yán)格模式下 如果針對(duì)分區(qū)表的查詢,where子句沒有添加分區(qū)過濾的話,任務(wù)禁止提交。

hive.mapred.mode=nonstrict

上述參數(shù) 取消嚴(yán)格模式

Hive數(shù)據(jù)傾斜問題 以及解決思路

MR階段,Map產(chǎn)生的數(shù)據(jù)是根據(jù)Hash算法生成的key,按key選擇合適的reduce,會(huì)因?yàn)閿?shù)據(jù)特殊性引起的key聚集,造成某些Reduce任務(wù)繁重,某些reduce幾乎沒有任務(wù)。
配置參數(shù)
hive.map.aggr=true//Map 端部分聚合,相當(dāng)于Combiner
hive.groupby.skewindata=true
原理就是:將數(shù)據(jù)隨機(jī)分成兩個(gè)Job,第一個(gè)job隨機(jī)分到不同的reduce,很有可能出現(xiàn)相同的key在不同的reduce里面。第二個(gè)Job可以根據(jù)預(yù)處理的反饋,將key分配到對(duì)應(yīng)的reduce中,基本上同一個(gè)key都在一個(gè)reduce里面。整體上可以減少數(shù)據(jù)處理時(shí)間,做到負(fù)載均衡。
SQL調(diào)節(jié)

  1. 如果兩個(gè)表都是大表,那么可以對(duì)key較少的那部分,可以賦一個(gè)隨機(jī)的key,值為null。傾斜的數(shù)據(jù)可以分配到不同的reduce上,null值也不會(huì)影響最后的結(jié)果計(jì)算。
  2. 如果表一大一小(約定1000條記錄一下),內(nèi)存加載較小的表在map端完成redcue操作。
    還有其他方法,沒使用過,略去不表。

Hive中的order by,sort by,distribute by, cluster by作用以及用法

  1. order by:在查詢的時(shí)候sql指定,進(jìn)行全局排序。不管會(huì)有多少個(gè)map節(jié)點(diǎn),只會(huì)在一個(gè)reduce節(jié)點(diǎn)內(nèi)進(jìn)行處理,所以會(huì)很慢。并且,如果手動(dòng)設(shè)置了嚴(yán)格模式,還是必須要指定limit條數(shù)的,因?yàn)閿?shù)據(jù)量非常大,可能不會(huì)出結(jié)果。
  2. sort by:原理類似于歸并排序。在每個(gè)reduce節(jié)點(diǎn)進(jìn)行排序,做到局部有序,最后進(jìn)行全局排序的時(shí)候就可以提升不少的效率。
  3. distribute by:都是和sort by 一起使用,并且先于它。作用是將指定的字段值相同的,分配到同一個(gè)reduce進(jìn)行處理。參考這個(gè)鏈接- distribute by和sort by一起使用
  1. cluster by:是2,3的合并
    cluster by id等價(jià)于distibute by id sort by id
    和3中語句等價(jià)的語句:
select mid, money, name from store cluster by mid sort by money  

Hive文件存儲(chǔ)、壓縮格式

  1. text file
    默認(rèn)設(shè)置。建表時(shí)會(huì)把數(shù)據(jù)文件拷貝到hdfs上不進(jìn)行處理。
  2. sequence file
    二進(jìn)制存儲(chǔ)。分割,壓縮比較方便。使用<key,value>存儲(chǔ),key是空的。
    三種壓縮可選,None,Record,Block。Record效率低一些,一般用Block
  3. rc file行列存儲(chǔ) 不好用
  4. orc file 3的升級(jí)版。性能很好,存儲(chǔ)效率比text file節(jié)省很多。
    從本地加載數(shù)據(jù)只用用text file格式。然后才可以通過text file轉(zhuǎn)換成2,3,4的格式。
    text file文件可以直接通過cat 查看。而2,3,4的源文件無法直接查看,只能借助表查詢才能查看其中的內(nèi)容。

=====================
我的其他相關(guān)文章:

  1. Hive知識(shí)匯總
  2. 大數(shù)據(jù)研發(fā)相關(guān)-面試拾遺(備戰(zhàn)積累的知識(shí)點(diǎn))
  3. 2018年春招面試實(shí)戰(zhàn)記錄-大數(shù)據(jù)開發(fā)相關(guān)崗位
  4. HadoopMR-Spark-HBase-Hive
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容