**1.1.1 **Hive優(yōu)化
- MapJoin
如果不指定MapJoin或者不符合MapJoin的條件斩启,那么Hive解析器會將Join操作轉(zhuǎn)換成Common Join序调,即:在Reduce階段完成join。容易發(fā)生數(shù)據(jù)傾斜兔簇》⒕睿可以用MapJoin把小表全部加載到內(nèi)存在map端進行join,避免reducer處理垄琐。
- 行列過濾
列處理:在SELECT中边酒,只拿需要的列,如果有狸窘,盡量使用分區(qū)過濾墩朦,少用SELECT *。
行處理:在分區(qū)剪裁中翻擒,當使用外關(guān)聯(lián)時氓涣,如果將副表的過濾條件寫在Where后面鹃操,那么就會先全表關(guān)聯(lián),之后再過濾春哨。
采用分桶技術(shù)
采用分區(qū)技術(shù)
合理設(shè)置Map數(shù)
a. 通常情況下,作業(yè)會通過input的目錄產(chǎn)生一個或者多個map任務(wù)恩伺。
主要的決定因素有:input的文件總個數(shù)赴背,input的文件大小,集群設(shè)置的文件塊大小晶渠。
b. 是不是map數(shù)越多越好凰荚?
答案是否定的。如果一個任務(wù)有很多小文件(遠遠小于塊大小128m)褒脯,則每個小文件也會被當做一個塊便瑟,用一個map任務(wù)來完成,而一個map任務(wù)啟動和初始化的時間遠遠大于邏輯處理的時間番川,就會造成很大的資源浪費到涂。而且,同時可執(zhí)行的map數(shù)是受限的颁督。
c. 是不是保證每個map處理接近128m的文件塊践啄,就高枕無憂了?
答案也是不一定沉御。比如有一個127m的文件屿讽,正常會用一個map去完成,但這個文件只有一個或者兩個小字段吠裆,卻有幾千萬的記錄伐谈,如果map處理的邏輯比較復雜,用一個map任務(wù)去做试疙,肯定也比較耗時诵棵。
針對上面的問題2和3,我們需要采取兩種方式來解決:即減少map數(shù)和增加map數(shù)效斑;
- 小文件進行合并
在Map執(zhí)行前合并小文件非春,減少Map數(shù):CombineHiveInputFormat具有對小文件進行合并的功能(系統(tǒng)默認的格式)。HiveInputFormat沒有對小文件合并功能缓屠。
- 合理設(shè)置Reduce數(shù)
Reduce個數(shù)并不是越多越好
a. 過多的啟動和初始化Reduce也會消耗時間和資源奇昙;
b. 另外,有多少個Reduce敌完,就會有多少個輸出文件储耐,如果生成了很多個小文件,那么如果這些小文件作為下一個任務(wù)的輸入滨溉,則也會出現(xiàn)小文件過多的問題什湘;
在設(shè)置Reduce個數(shù)的時候也需要考慮這兩個原則:處理大數(shù)據(jù)量利用合適的Reduce數(shù)长赞;使單個Reduce任務(wù)處理數(shù)據(jù)量大小要合適;
- 常用參數(shù)
// 輸出合并小文件
SET hive.merge.mapfiles = true; -- 默認true闽撤,在map-only任務(wù)結(jié)束時合并小文件
SET hive.merge.mapredfiles = true; -- 默認false得哆,在map-reduce任務(wù)結(jié)束時合并小文件
SET hive.merge.size.per.task = 268435456; -- 默認256M
SET hive.merge.smallfiles.avgsize = 16777216; -- 當輸出文件的平均大小小于該值時,啟動一個獨立的map-reduce任務(wù)進行文件merge
原網(wǎng)址:https://blog.csdn.net/liyaohhh/article/details/50697519
hive在實際的應(yīng)用過程中哟旗,大部份分情況都會涉及到不同的表格的連接贩据,
例如在進行兩個table的join的時候,利用MR的思想會消耗大量的內(nèi)存闸餐,磁盤的IO饱亮,大幅度的影響性能,因為shuffle真的好令人擔心啊舍沙,總之近上,就是各種問題都是由他產(chǎn)生的。
下面介紹一下涉及hive在join的時候的優(yōu)化方式拂铡。
第一:在map端產(chǎn)生join
mapJoin的主要意思就是壹无,當鏈接的兩個表是**一個比較小的表和一個特別大的表**的時候,我們把比較小的table直接放到內(nèi)存中去感帅,然后再對比較大的表格進行map操作格遭。
join就發(fā)生在map操作的時候,每當掃描一個大的table中的數(shù)據(jù)留瞳,就要去去查看小表的數(shù)據(jù)拒迅,哪條與之相符,繼而進行連接她倘。
這里的join并不會涉及reduce操作璧微。map端join的優(yōu)勢就是在于沒有shuffle,真好硬梁。在實際的應(yīng)用中前硫,我們這樣設(shè)置:
set hive.auto.convert.join=true;
這樣設(shè)置,hive就會自動的識別比較小的表荧止,繼而用mapJoin來實現(xiàn)兩個表的聯(lián)合屹电。
看看下面的兩個表格的連接。這里的dept相對來講是比較小的跃巡。我們看看會發(fā)生什么危号,如圖所示:
注意看啦,這里的第一句話就是運行本地的map join任務(wù)素邪,繼而轉(zhuǎn)存文件到XXX.hashtable下面外莲,在給這個文件里面上傳一個文件進行map join,之后才運行了MR代碼去運行計數(shù)任務(wù)。
說白了偷线,在本質(zhì)上map join根本就沒有運行MR進程磨确,僅僅是在內(nèi)存就進行了兩個表的聯(lián)合。具體運行如下圖:
第二:common join
common join也叫做shuffle join声邦,reduce join操作乏奥。這種情況下生再兩個table的大小相當,但是又不是很大的情況下使用的亥曹。
具體流程就是在map端進行數(shù)據(jù)的切分英融,一個block對應(yīng)一個map操作,然后進行shuffle操作歇式,把對應(yīng)的block shuffle到reduce端去,再逐個進行聯(lián)合胡野,
這里優(yōu)勢會涉及到數(shù)據(jù)的傾斜材失,大幅度的影響性能有可能會運行speculation,
這塊兒在后續(xù)的數(shù)據(jù)傾斜會講到硫豆。因為平常我們用到的數(shù)據(jù)量小龙巨,所以這里就不具體演示了。
第三:SMBJoin
smb是sort merge bucket操作熊响,首先進行排序旨别,繼而合并,然后放到所對應(yīng)的bucket中去汗茄,bucket是hive中和分區(qū)表類似的技術(shù)秸弛,就是按照key進行hash,相同的hash值都放到相同的buck中去洪碳。在進行兩個表聯(lián)合的時候递览。我們首先進行分桶,在join會大幅度的對性能進行優(yōu)化瞳腌。也就是說绞铃,在進行聯(lián)合的時候,是table1中的一小部分和table1中的一小部分進行聯(lián)合嫂侍,table聯(lián)合都是等值連接儿捧,相同的key都放到了同一個bucket中去了,那么在聯(lián)合的時候就會大幅度的減小無關(guān)項的掃描挑宠。
具體的看看一個例子:
set hive.auto.convert.sortmerge.join=true;
set hive.optimize.bucketmapjoin = true;
set hive.optimize.bucketmapjoin.sortedmerge = true;
set hive.auto.convert.sortmerge.join.noconditionaltask=true;
create table emp_info_bucket(ename string,deptno int)
partitioned by (empno string)
clustered by(deptno) into 4 buckets;
insert overwrite table emp_info_bucket
partition (empno=7369)
select ename ,deptno from emp
create table dept_info_bucket(deptno string,dname string,loc string)
clustered by (deptno) into 4 buckets;
insert overwrite table dept_info_bucket
select * from dept;
select * from emp_info_bucket emp join dept_info_bucket dept
on(emp.deptno==dept.deptno);//正常的情況下菲盾,應(yīng)該是啟動smbjoin的但是這里的數(shù)據(jù)量太小啦,還是啟動了mapjoin