Hive性能優(yōu)化

Hive性能優(yōu)化

1.概述
  繼續(xù)《那些年使用Hive踩過的坑》一文中的剩余部分崇堰,本篇博客贅述了在工作中總結(jié)Hive的常用優(yōu)化手段和在工作中使用Hive出現(xiàn)的問題。下面開始本篇文章的優(yōu)化介紹鳍烁。
2.介紹
  首先,我們來看看Hadoop的計(jì)算框架特性刊棕,在此特性下會衍生哪些問題钢猛?
數(shù)據(jù)量大不是問題察郁,數(shù)據(jù)傾斜是個問題衍慎。
jobs數(shù)比較多的作業(yè)運(yùn)行效率相對比較低,比如即使有幾百行的表皮钠,如果多次關(guān)聯(lián)多次匯總稳捆,產(chǎn)生十幾個jobs,耗時(shí)很長麦轰。原因是map reduce作業(yè)初始化的時(shí)間是比較長的乔夯。
sum,count,max,min等UDAF,不怕數(shù)據(jù)傾斜問題,hadoop在map端的匯總合并優(yōu)化款侵,使數(shù)據(jù)傾斜不成問題末荐。
count(distinct ),在數(shù)據(jù)量大的情況下,效率較低新锈,如果是多count(distinct )效率更低甲脏,因?yàn)閏ount(distinct)是按group by 字段分組,按distinct字段排序妹笆,一般這種分布方式是很傾斜的块请。舉個例子:比如男uv,女uv,像淘寶一天30億的pv拳缠,如果按性別分組负乡,分配2個reduce,每個reduce處理15億數(shù)據(jù)。

面對這些問題脊凰,我們能有哪些有效的優(yōu)化手段呢?下面列出一些在工作有效可行的優(yōu)化手段:
好的模型設(shè)計(jì)事半功倍。
解決數(shù)據(jù)傾斜問題狸涌。
減少job數(shù)切省。
設(shè)置合理的map reduce的task數(shù),能有效提升性能帕胆。(比如朝捆,10w+級別的計(jì)算,用160個reduce懒豹,那是相當(dāng)?shù)睦速M(fèi)芙盘,1個足夠)。
了解數(shù)據(jù)分布脸秽,自己動手解決數(shù)據(jù)傾斜問題是個不錯的選擇儒老。set hive.groupby.skewindata=true;這是通用的算法優(yōu)化,但算法優(yōu)化有時(shí)不能適應(yīng)特定業(yè)務(wù)背景记餐,開發(fā)人員了解業(yè)務(wù)驮樊,了解數(shù)據(jù),可以通過業(yè)務(wù)邏輯精確有效的解決數(shù)據(jù)傾斜問題片酝。
數(shù)據(jù)量較大的情況下囚衔,慎用count(distinct),count(distinct)容易產(chǎn)生傾斜問題雕沿。
對小文件進(jìn)行合并练湿,是行至有效的提高調(diào)度效率的方法,假如所有的作業(yè)設(shè)置合理的文件數(shù)审轮,對云梯的整體調(diào)度效率也會產(chǎn)生積極的正向影響肥哎。
優(yōu)化時(shí)把握整體,單個作業(yè)最優(yōu)不如整體最優(yōu)断国。

而接下來贤姆,我們心中應(yīng)該會有一些疑問,影響性能的根源是什么稳衬?
3.性能低下的根源
  hive性能優(yōu)化時(shí)霞捡,把HiveQL當(dāng)做M/R程序來讀,即從M/R的運(yùn)行角度來考慮優(yōu)化性能薄疚,從更底層思考如何優(yōu)化運(yùn)算性能碧信,而不僅僅局限于邏輯代碼的替換層面。
  RAC(Real Application Cluster)真正應(yīng)用集群就像一輛機(jī)動靈活的小貨車街夭,響應(yīng)快砰碴;Hadoop就像吞吐量巨大的輪船,啟動開銷大板丽,如果每次只做小數(shù)量的輸入輸出呈枉,利用率將會很低趁尼。所以用好Hadoop的首要任務(wù)是增大每次任務(wù)所搭載的數(shù)據(jù)量。
  Hadoop的核心能力是parition和sort猖辫,因而這也是優(yōu)化的根本酥泞。
  觀察Hadoop處理數(shù)據(jù)的過程,有幾個顯著的特征:
數(shù)據(jù)的大規(guī)模并不是負(fù)載重點(diǎn)啃憎,造成運(yùn)行壓力過大是因?yàn)檫\(yùn)行數(shù)據(jù)的傾斜芝囤。
jobs數(shù)比較多的作業(yè)運(yùn)行效率相對比較低,比如即使有幾百行的表辛萍,如果多次關(guān)聯(lián)對此匯總悯姊,產(chǎn)生幾十個jobs,將會需要30分鐘以上的時(shí)間且大部分時(shí)間被用于作業(yè)分配贩毕,初始化和數(shù)據(jù)輸出悯许。M/R作業(yè)初始化的時(shí)間是比較耗時(shí)間資源的一個部分。
在使用SUM耳幢,COUNT岸晦,MAX,MIN等UDAF函數(shù)時(shí)睛藻,不怕數(shù)據(jù)傾斜問題启上,Hadoop在Map端的匯總合并優(yōu)化過,使數(shù)據(jù)傾斜不成問題店印。
COUNT(DISTINCT)在數(shù)據(jù)量大的情況下冈在,效率較低,如果多COUNT(DISTINCT)效率更低按摘,因?yàn)镃OUNT(DISTINCT)是按GROUP BY字段分組包券,按DISTINCT字段排序,一般這種分布式方式是很傾斜的炫贤;比如:男UV溅固,女UV,淘寶一天30億的PV兰珍,如果按性別分組侍郭,分配2個reduce,每個reduce處理15億數(shù)據(jù)。
數(shù)據(jù)傾斜是導(dǎo)致效率大幅降低的主要原因掠河,可以采用多一次 Map/Reduce 的方法亮元, 避免傾斜。

最后得出的結(jié)論是:避實(shí)就虛唠摹,用 job 數(shù)的增加爆捞,輸入量的增加,占用更多存儲空間勾拉,充分利用空閑 CPU 等各種方法煮甥,分解數(shù)據(jù)傾斜造成的負(fù)擔(dān)盗温。
4.配置角度優(yōu)化
  我們知道了性能低下的根源,同樣成肘,我們也可以從Hive的配置解讀去優(yōu)化肌访。Hive系統(tǒng)內(nèi)部已針對不同的查詢預(yù)設(shè)定了優(yōu)化方法,用戶可以通過調(diào)整配置進(jìn)行控制艇劫, 以下舉例介紹部分優(yōu)化的策略以及優(yōu)化控制選項(xiàng)。
4.1列裁剪
  Hive 在讀數(shù)據(jù)的時(shí)候惩激,可以只讀取查詢中所需要用到的列店煞,而忽略其它列。 例如风钻,若有以下查詢:
SELECT a,b FROM q WHERE e<10;

在實(shí)施此項(xiàng)查詢中顷蟀,Q 表有 5 列(a,b骡技,c鸣个,d,e)布朦,Hive 只讀取查詢邏輯中真實(shí)需要 的 3 列 a囤萤、b、e是趴,而忽略列 c涛舍,d;這樣做節(jié)省了讀取開銷唆途,中間表存儲開銷和數(shù)據(jù)整合開銷富雅。
  裁剪所對應(yīng)的參數(shù)項(xiàng)為:hive.optimize.cp=true(默認(rèn)值為真)
4.2分區(qū)裁剪
  可以在查詢的過程中減少不必要的分區(qū)。 例如肛搬,若有以下查詢:
SELECT * FROM (SELECTT a1,COUNT(1) FROM T GROUP BY a1) subq WHERE subq.prtn=100; #(多余分區(qū)) SELECT * FROM T1 JOIN (SELECT * FROM T2) subq ON (T1.a1=subq.a2) WHERE subq.prtn=100;

查詢語句若將“subq.prtn=100”條件放入子查詢中更為高效没佑,可以減少讀入的分區(qū) 數(shù)目。 Hive 自動執(zhí)行這種裁剪優(yōu)化温赔。
  分區(qū)參數(shù)為:hive.optimize.pruner=true(默認(rèn)值為真)
4.3JOIN操作
  在編寫帶有 join 操作的代碼語句時(shí)蛤奢,應(yīng)該將條目少的表/子查詢放在 Join 操作符的左邊。 因?yàn)樵?Reduce 階段让腹,位于 Join 操作符左邊的表的內(nèi)容會被加載進(jìn)內(nèi)存远剩,載入條目較少的表 可以有效減少 OOM(out of memory)即內(nèi)存溢出。所以對于同一個 key 來說骇窍,對應(yīng)的 value 值小的放前瓜晤,大的放后,這便是“小表放前”原則腹纳。 若一條語句中有多個 Join痢掠,依據(jù) Join 的條件相同與否驱犹,有不同的處理方法。
4.3.1JOIN原則
  在使用寫有 Join 操作的查詢語句時(shí)有一條原則:應(yīng)該將條目少的表/子查詢放在 Join 操作符的左邊足画。原因是在 Join 操作的 Reduce 階段雄驹,位于 Join 操作符左邊的表的內(nèi)容會被加載進(jìn)內(nèi)存,將條目少的表放在左邊淹辞,可以有效減少發(fā)生 OOM 錯誤的幾率医舆。對于一條語句中有多個 Join 的情況,如果 Join 的條件相同象缀,比如查詢:
INSERT OVERWRITE TABLE pv_users SELECT pv.pageid, u.age FROM page_view p JOIN user u ON (pv.userid = u.userid) JOIN newuser x ON (u.userid = x.userid);

如果 Join 的 key 相同蔬将,不管有多少個表,都會則會合并為一個 Map-Reduce
一個 Map-Reduce 任務(wù)央星,而不是 ‘n’ 個
在做 OUTER JOIN 的時(shí)候也是一樣

如果 Join 的條件不相同霞怀,比如:
INSERT OVERWRITE TABLE pv_users SELECT pv.pageid, u.age FROM page_view p JOIN user u ON (pv.userid = u.userid) JOIN newuser x on (u.age = x.age);

Map-Reduce 的任務(wù)數(shù)目和 Join 操作的數(shù)目是對應(yīng)的,上述查詢和以下查詢是等價(jià)的:
INSERT OVERWRITE TABLE tmptable SELECT * FROM page_view p JOIN user u ON (pv.userid = u.userid); INSERT OVERWRITE TABLE pv_users SELECT x.pageid, x.age FROM tmptable x JOIN newuser y ON (x.age = y.age);

4.4MAP JOIN操作
  Join 操作在 Map 階段完成莉给,不再需要Reduce毙石,前提條件是需要的數(shù)據(jù)在 Map 的過程中可以訪問到。比如查詢:
INSERT OVERWRITE TABLE pv_users SELECT /*+ MAPJOIN(pv) */ pv.pageid, u.age FROM page_view pv JOIN user u ON (pv.userid = u.userid);

可以在 Map 階段完成 Join颓遏,如圖所示:


  相關(guān)的參數(shù)為:
hive.join.emit.interval = 1000
hive.mapjoin.size.key = 10000
hive.mapjoin.cache.numrows = 10000

4.5GROUP BY操作
  進(jìn)行GROUP BY操作時(shí)需要注意一下幾點(diǎn):
Map端部分聚合

事實(shí)上并不是所有的聚合操作都需要在reduce部分進(jìn)行徐矩,很多聚合操作都可以先在Map端進(jìn)行部分聚合傅联,然后reduce端得出最終結(jié)果薄风。
  這里需要修改的參數(shù)為:
  hive.map.aggr=true(用于設(shè)定是否在 map 端進(jìn)行聚合咏闪,默認(rèn)值為真) hive.groupby.mapaggr.checkinterval=100000(用于設(shè)定 map 端進(jìn)行聚合操作的條目數(shù))
有數(shù)據(jù)傾斜時(shí)進(jìn)行負(fù)載均衡

此處需要設(shè)定 hive.groupby.skewindata樊零,當(dāng)選項(xiàng)設(shè)定為 true 是赞别,生成的查詢計(jì)劃有兩 個 MapReduce 任務(wù)捅僵。在第一個 MapReduce 中慷妙,map 的輸出結(jié)果集合會隨機(jī)分布到 reduce 中眷昆, 每個 reduce 做部分聚合操作演训,并輸出結(jié)果弟孟。這樣處理的結(jié)果是,相同的 Group By Key 有可 能分發(fā)到不同的 reduce 中样悟,從而達(dá)到負(fù)載均衡的目的拂募;第二個 MapReduce 任務(wù)再根據(jù)預(yù)處 理的數(shù)據(jù)結(jié)果按照 Group By Key 分布到 reduce 中(這個過程可以保證相同的 Group By Key 分布到同一個 reduce 中),最后完成最終的聚合操作窟她。
4.6合并小文件
  我們知道文件數(shù)目小陈症,容易在文件存儲端造成瓶頸,給 HDFS 帶來壓力震糖,影響處理效率录肯。對此,可以通過合并Map和Reduce的結(jié)果文件來消除這樣的影響吊说。
  用于設(shè)置合并屬性的參數(shù)有:
是否合并Map輸出文件:hive.merge.mapfiles=true(默認(rèn)值為真)
是否合并Reduce 端輸出文件:hive.merge.mapredfiles=false(默認(rèn)值為假)
合并文件的大新塾健:hive.merge.size.per.task=25610001000(默認(rèn)值為 256000000)

5.程序角度優(yōu)化
5.1熟練使用SQL提高查詢
  熟練地使用 SQL优炬,能寫出高效率的查詢語句。
  場景:有一張 user 表厅贪,為賣家每天收到表蠢护,user_id,ds(日期)為 key养涮,屬性有主營類目葵硕,指標(biāo)有交易金額,交易筆數(shù)贯吓。每天要取前10天的總收入贬芥,總筆數(shù),和最近一天的主營類目宣决。   解決方法 1
  如下所示:常用方法

復(fù)制代碼

INSERT OVERWRITE TABLE t1 SELECT user_id,substr(MAX(CONCAT(ds,cat),9) AS main_cat) FROM users WHERE ds=20120329 // 20120329 為日期列的值,實(shí)際代碼中可以用函數(shù)表示出當(dāng)天日期 GROUP BY user_id; INSERT OVERWRITE TABLE t2 SELECT user_id,sum(qty) AS qty,SUM(amt) AS amt FROM users WHERE ds BETWEEN 20120301 AND 20120329 GROUP BY user_id SELECT t1.user_id,t1.main_cat,t2.qty,t2.amt FROM t1 JOIN t2 ON t1.user_id=t2.user_id
復(fù)制代碼

下面給出方法1的思路昏苏,實(shí)現(xiàn)步驟如下:
  第一步:利用分析函數(shù)尊沸,取每個 user_id 最近一天的主營類目,存入臨時(shí)表 t1贤惯。
  第二步:匯總 10 天的總交易金額洼专,交易筆數(shù),存入臨時(shí)表 t2孵构。
  第三步:關(guān)聯(lián) t1屁商,t2,得到最終的結(jié)果颈墅。
  解決方法 2
  如下所示:優(yōu)化方法 
SELECT user_id,substr(MAX(CONCAT(ds,cat)),9) AS main_cat,SUM(qty),SUM(amt) FROM users WHERE ds BETWEEN 20120301 AND 20120329 GROUP BY user_id

在工作中我們總結(jié)出:方案 2 的開銷等于方案 1 的第二步的開銷蜡镶,性能提升,由原有的 25 分鐘完成恤筛,縮短為 10 分鐘以內(nèi)完成官还。節(jié)省了兩個臨時(shí)表的讀寫是一個關(guān)鍵原因,這種方式也適用于 Oracle 中的數(shù)據(jù)查找工作毒坛。
SQL 具有普適性望伦,很多 SQL 通用的優(yōu)化方案在 Hadoop 分布式計(jì)算方式中也可以達(dá)到效果。
5.2無效ID在關(guān)聯(lián)時(shí)的數(shù)據(jù)傾斜問題
  問題:日志中常會出現(xiàn)信息丟失煎殷,比如每日約為 20 億的全網(wǎng)日志屯伞,其中的 user_id 為主 鍵,在日志收集過程中會丟失豪直,出現(xiàn)主鍵為 null 的情況劣摇,如果取其中的 user_id 和 bmw_users 關(guān)聯(lián),就會碰到數(shù)據(jù)傾斜的問題顶伞。原因是 Hive 中饵撑,主鍵為 null 值的項(xiàng)會被當(dāng)做相同的 Key 而分配進(jìn)同一個計(jì)算 Map剑梳。
解決方法 1:user_id 為空的不參與關(guān)聯(lián),子查詢過濾 null
SELECT * FROM log a JOIN bmw_users b ON a.user_id IS NOT NULL AND a.user_id=b.user_id UNION All SELECT * FROM log a WHERE a.user_id IS NULL

解決方法 2 如下所示:函數(shù)過濾 null
SELECT * FROM log a LEFT OUTER JOIN bmw_users b ON CASE WHEN a.user_id IS NULL THEN CONCAT(‘dp_hive’,RAND()) ELSE a.user_id END =b.user_id;

調(diào)優(yōu)結(jié)果:原先由于數(shù)據(jù)傾斜導(dǎo)致運(yùn)行時(shí)長超過 1 小時(shí)滑潘,解決方法 1 運(yùn)行每日平均時(shí)長 25 分鐘垢乙,解決方法 2 運(yùn)行的每日平均時(shí)長在 20 分鐘左右。優(yōu)化效果很明顯语卤。
  我們在工作中總結(jié)出:解決方法2比解決方法1效果更好追逮,不但I(xiàn)O少了,而且作業(yè)數(shù)也少了粹舵。解決方法1中l(wèi)og讀取兩次钮孵,job 數(shù)為2。解決方法2中 job 數(shù)是1眼滤。這個優(yōu)化適合無效 id(比如-99巴席、 ‘’,null 等)產(chǎn)生的傾斜問題诅需。把空值的 key 變成一個字符串加上隨機(jī)數(shù)漾唉,就能把傾斜的 數(shù)據(jù)分到不同的Reduce上,從而解決數(shù)據(jù)傾斜問題堰塌。因?yàn)榭罩挡粎⑴c關(guān)聯(lián)赵刑,即使分到不同 的 Reduce 上,也不會影響最終的結(jié)果场刑。附上 Hadoop 通用關(guān)聯(lián)的實(shí)現(xiàn)方法是:關(guān)聯(lián)通過二次排序?qū)崿F(xiàn)的般此,關(guān)聯(lián)的列為 partion key,關(guān)聯(lián)的列和表的 tag 組成排序的 group key牵现,根據(jù) pariton key分配Reduce铐懊。同一Reduce內(nèi)根據(jù)group key排序。
5.3不同數(shù)據(jù)類型關(guān)聯(lián)產(chǎn)生的傾斜問題
  問題:不同數(shù)據(jù)類型 id 的關(guān)聯(lián)會產(chǎn)生數(shù)據(jù)傾斜問題瞎疼。
  一張表 s8 的日志居扒,每個商品一條記錄,要和商品表關(guān)聯(lián)丑慎。但關(guān)聯(lián)卻碰到傾斜的問題喜喂。 s8 的日志中有 32 為字符串商品 id,也有數(shù)值商品 id竿裂,日志中類型是 string 的玉吁,但商品中的 數(shù)值 id 是 bigint 的。猜想問題的原因是把 s8 的商品 id 轉(zhuǎn)成數(shù)值 id 做 hash 來分配 Reduce腻异, 所以字符串 id 的 s8 日志进副,都到一個 Reduce 上了,解決的方法驗(yàn)證了這個猜測。
  解決方法:把數(shù)據(jù)類型轉(zhuǎn)換成字符串類型
 
SELECT * FROM s8_log a LEFT OUTER JOIN r_auction_auctions b ON a.auction_id=CASE(b.auction_id AS STRING)

調(diào)優(yōu)結(jié)果顯示:數(shù)據(jù)表處理由 1 小時(shí) 30 分鐘經(jīng)代碼調(diào)整后可以在 20 分鐘內(nèi)完成影斑。
5.4利用Hive對UNION ALL優(yōu)化的特性
  多表 union all 會優(yōu)化成一個 job给赞。
  問題:比如推廣效果表要和商品表關(guān)聯(lián),效果表中的 auction_id 列既有 32 為字符串商 品 id矫户,也有數(shù)字 id片迅,和商品表關(guān)聯(lián)得到商品的信息。
  解決方法:Hive SQL 性能會比較好
SELECT * FROM effect a JOIN (SELECT auction_id AS auction_id FROM auctions UNION All SELECT auction_string_id AS auction_id FROM auctions) b ON a.auction_id=b.auction_id

比分別過濾數(shù)字 id皆辽,字符串 id 然后分別和商品表關(guān)聯(lián)性能要好柑蛇。
  這樣寫的好處:1 個 MapReduce 作業(yè),商品表只讀一次驱闷,推廣效果表只讀取一次耻台。把 這個 SQL 換成 Map/Reduce 代碼的話,Map 的時(shí)候空另,把 a 表的記錄打上標(biāo)簽 a盆耽,商品表記錄 每讀取一條,打上標(biāo)簽 b扼菠,變成兩個<key,value>對征字,<(b,數(shù)字 id),value>,<(b,字符串 id),value>娇豫。
  所以商品表的 HDFS 讀取只會是一次。
5.5解決Hive對UNION ALL優(yōu)化的短板
  Hive 對 union all 的優(yōu)化的特性:對 union all 優(yōu)化只局限于非嵌套查詢畅厢。
消滅子查詢內(nèi)的 group by

 示例 1:子查詢內(nèi)有 group by 

SELECT * FROM (SELECT * FROM t1 GROUP BY c1,c2,c3 UNION ALL SELECT * FROM t2 GROUP BY c1,c2,c3)t3 GROUP BY c1,c2,c3

從業(yè)務(wù)邏輯上說冯痢,子查詢內(nèi)的 GROUP BY 怎么都看顯得多余(功能上的多余,除非有 COUNT(DISTINCT))框杜,如果不是因?yàn)?Hive Bug 或者性能上的考量(曾經(jīng)出現(xiàn)如果不執(zhí)行子查詢 GROUP BY浦楣,數(shù)據(jù)得不到正確的結(jié)果的 Hive Bug)。所以這個 Hive 按經(jīng)驗(yàn)轉(zhuǎn)換成如下所示:
SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2)t3 GROUP BY c1,c2,c3

調(diào)優(yōu)結(jié)果:經(jīng)過測試咪辱,并未出現(xiàn) union all 的 Hive Bug振劳,數(shù)據(jù)是一致的。MapReduce 的 作業(yè)數(shù)由 3 減少到 1油狂。
t1 相當(dāng)于一個目錄历恐,t2 相當(dāng)于一個目錄,對 Map/Reduce 程序來說专筷,t1弱贼,t2 可以作為 Map/Reduce 作業(yè)的 mutli inputs。這可以通過一個 Map/Reduce 來解決這個問題磷蛹。Hadoop 的 計(jì)算框架吮旅,不怕數(shù)據(jù)多,就怕作業(yè)數(shù)多味咳。
  但如果換成是其他計(jì)算平臺如 Oracle庇勃,那就不一定了檬嘀,因?yàn)榘汛蟮妮斎氩鸪蓛蓚€輸入, 分別排序匯總后 merge(假如兩個子排序是并行的話)责嚷,是有可能性能更優(yōu)的(比如希爾排 序比冒泡排序的性能更優(yōu))鸳兽。
消滅子查詢內(nèi)的 COUNT(DISTINCT),MAX再层,MIN贸铜。

SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT c1,c2,c3 COUNT(DISTINCT c4) FROM t2 GROUP BY c1,c2,c3) t3 GROUP BY c1,c2,c3;

由于子查詢里頭有 COUNT(DISTINCT)操作,直接去 GROUP BY 將達(dá)不到業(yè)務(wù)目標(biāo)聂受。這時(shí)采用 臨時(shí)表消滅 COUNT(DISTINCT)作業(yè)不但能解決傾斜問題蒿秦,還能有效減少 jobs。
INSERT t4 SELECT c1,c2,c3,c4 FROM t2 GROUP BY c1,c2,c3; SELECT c1,c2,c3,SUM(income),SUM(uv) FROM (SELECT c1,c2,c3,income,0 AS uv FROM t1 UNION ALL SELECT c1,c2,c3,0 AS income,1 AS uv FROM t2) t3 GROUP BY c1,c2,c3;

job 數(shù)是 2蛋济,減少一半棍鳖,而且兩次 Map/Reduce 比 COUNT(DISTINCT)效率更高。
調(diào)優(yōu)結(jié)果:千萬級別的類目表碗旅,member 表渡处,與 10 億級得商品表關(guān)聯(lián)。原先 1963s 的任務(wù)經(jīng)過調(diào)整祟辟,1152s 即完成医瘫。
消滅子查詢內(nèi)的 JOIN

SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t4 UNION ALL SELECT * FROM t2 JOIN t3 ON t2.id=t3.id) x GROUP BY c1,c2;

上面代碼運(yùn)行會有 5 個 jobs。加入先 JOIN 生存臨時(shí)表的話 t5旧困,然后 UNION ALL醇份,會變成 2 個 jobs。
INSERT OVERWRITE TABLE t5 SELECT * FROM t2 JOIN t3 ON t2.id=t3.id; SELECT * FROM (t1 UNION ALL t4 UNION ALL t5);

調(diào)優(yōu)結(jié)果顯示:針對千萬級別的廣告位表吼具,由原先 5 個 Job 共 15 分鐘僚纷,分解為 2 個 job 一個 8-10 分鐘,一個3分鐘拗盒。
5.6GROUP BY替代COUNT(DISTINCT)達(dá)到優(yōu)化效果
  計(jì)算 uv 的時(shí)候怖竭,經(jīng)常會用到 COUNT(DISTINCT),但在數(shù)據(jù)比較傾斜的時(shí)候 COUNT(DISTINCT) 會比較慢陡蝇。這時(shí)可以嘗試用 GROUP BY 改寫代碼計(jì)算 uv痊臭。
原有代碼

INSERT OVERWRITE TABLE s_dw_tanx_adzone_uv PARTITION (ds=20120329) SELECT 20120329 AS thedate,adzoneid,COUNT(DISTINCT acookie) AS uv FROM s_ods_log_tanx_pv t WHERE t.ds=20120329 GROUP BY adzoneid

關(guān)于COUNT(DISTINCT)的數(shù)據(jù)傾斜問題不能一概而論,要依情況而定登夫,下面是我測試的一組數(shù)據(jù):
  測試數(shù)據(jù):169857條

統(tǒng)計(jì)每日IP CREATE TABLE ip_2014_12_29 AS SELECT COUNT(DISTINCT ip) AS IP FROM logdfs WHERE logdate='2014_12_29'; 耗時(shí):24.805 seconds #統(tǒng)計(jì)每日IP(改造) CREATE TABLE ip_2014_12_29 AS SELECT COUNT(1) AS IP FROM (SELECT DISTINCT ip from logdfs WHERE logdate='2014_12_29') tmp; 耗時(shí):46.833 seconds

測試結(jié)果表名:明顯改造后的語句比之前耗時(shí)趣兄,這是因?yàn)楦脑旌蟮恼Z句有2個SELECT,多了一個job悼嫉,這樣在數(shù)據(jù)量小的時(shí)候艇潭,數(shù)據(jù)不會存在傾斜問題。
6.優(yōu)化總結(jié)
  優(yōu)化時(shí),把hive sql當(dāng)做mapreduce程序來讀蹋凝,會有意想不到的驚喜鲁纠。理解hadoop的核心能力,是hive優(yōu)化的根本鳍寂。這是這一年來改含,項(xiàng)目組所有成員寶貴的經(jīng)驗(yàn)總結(jié)。
長期觀察hadoop處理數(shù)據(jù)的過程迄汛,有幾個顯著的特征:

不怕數(shù)據(jù)多捍壤,就怕數(shù)據(jù)傾斜。
對jobs數(shù)比較多的作業(yè)運(yùn)行效率相對比較低鞍爱,比如即使有幾百行的表鹃觉,如果多次關(guān)聯(lián)多次匯總,產(chǎn)生十幾個jobs睹逃,沒半小時(shí)是跑不完的盗扇。map reduce作業(yè)初始化的時(shí)間是比較長的。
對sum沉填,count來說疗隶,不存在數(shù)據(jù)傾斜問題。
對count(distinct ),效率較低翼闹,數(shù)據(jù)量一多斑鼻,準(zhǔn)出問題,如果是多count(distinct )效率更低猎荠。

優(yōu)化可以從幾個方面著手:

好的模型設(shè)計(jì)事半功倍坚弱。
解決數(shù)據(jù)傾斜問題。
減少job數(shù)法牲。
設(shè)置合理的map reduce的task數(shù),能有效提升性能琼掠。(比如拒垃,10w+級別的計(jì)算,用160個reduce瓷蛙,那是相當(dāng)?shù)睦速M(fèi)悼瓮,1個足夠)。
自己動手寫sql解決數(shù)據(jù)傾斜問題是個不錯的選擇艰猬。set hive.groupby.skewindata=true;這是通用的算法優(yōu)化横堡,但算法優(yōu)化總是漠視業(yè)務(wù),習(xí)慣性提供通用的解決方法冠桃。 Etl開發(fā)人員更了解業(yè)務(wù)命贴,更了解數(shù)據(jù),所以通過業(yè)務(wù)邏輯解決傾斜的方法往往更精確,更有效胸蛛。
對count(distinct)采取漠視的方法污茵,尤其數(shù)據(jù)大的時(shí)候很容易產(chǎn)生傾斜問題,不抱僥幸心理葬项。自己動手泞当,豐衣足食。
對小文件進(jìn)行合并民珍,是行至有效的提高調(diào)度效率的方法襟士,假如我們的作業(yè)設(shè)置合理的文件數(shù),對云梯的整體調(diào)度效率也會產(chǎn)生積極的影響嚷量。

優(yōu)化時(shí)把握整體陋桂,單個作業(yè)最優(yōu)不如整體最優(yōu)。
7.優(yōu)化的常用手段
  主要由三個屬性來決定:
hive.exec.reducers.bytes.per.reducer #這個參數(shù)控制一個job會有多少個reducer來處理津肛,依據(jù)的是輸入文件的總大小章喉。默認(rèn)1GB。
hive.exec.reducers.max #這個參數(shù)控制最大的reducer的數(shù)量身坐, 如果 input / bytes per reduce > max 則會啟動這個參數(shù)所指定的reduce個數(shù)秸脱。 這個并不會影響mapre.reduce.tasks參數(shù)的設(shè)置。默認(rèn)的max是999部蛇。
mapred.reduce.tasks #這個參數(shù)如果指定了摊唇,hive就不會用它的estimation函數(shù)來自動計(jì)算reduce的個數(shù),而是用這個參數(shù)來啟動reducer涯鲁。默認(rèn)是-1巷查。

7.1參數(shù)設(shè)置的影響
  如果reduce太少:如果數(shù)據(jù)量很大,會導(dǎo)致這個reduce異常的慢抹腿,從而導(dǎo)致這個任務(wù)不能結(jié)束岛请,也有可能會OOM 2、如果reduce太多: 產(chǎn)生的小文件太多警绩,合并起來代價(jià)太高崇败,namenode的內(nèi)存占用也會增大。如果我們不指定mapred.reduce.tasks肩祥, hive會自動計(jì)算需要多少個reducer后室。
8.結(jié)束語
  這篇博客就和大家分享到這里,后面再有好的優(yōu)化手段在和大家分享混狠,感謝大家在百忙之中花時(shí)間來閱讀我這篇博客岸霹,如果在優(yōu)化的過程中有什么問題可以加群進(jìn)行討論或發(fā)送郵件給我,我會盡我所能為您解答将饺,與君共勉贡避!

****************聯(lián)系方式: 郵箱:smartloli.org@gmail.com Twitter:https://twitter.com/smartloli QQ群(Hadoop - 交流社區(qū)1):424769183 溫馨提示:請大家加群的時(shí)候?qū)懮霞尤豪碛桑ㄐ彰?學(xué)校)痛黎,方便管理員審核,謝謝贸桶! 熱愛生活舅逸,享受編程,與君共勉皇筛!


****************作者:哥不是小蘿莉 [關(guān)于我][犒賞
出處:http://www.cnblogs.com/smartloli/
轉(zhuǎn)載請注明出處琉历,謝謝合作!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末水醋,一起剝皮案震驚了整個濱河市旗笔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拄踪,老刑警劉巖蝇恶,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惶桐,居然都是意外死亡撮弧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門姚糊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贿衍,“玉大人,你說我怎么就攤上這事救恨∶潮玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵肠槽,是天一觀的道長擎淤。 經(jīng)常有香客問我,道長秸仙,這世上最難降的妖魔是什么嘴拢? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮寂纪,結(jié)果婚禮上席吴,老公的妹妹穿的比我還像新娘。我一直安慰自己弊攘,他們只是感情好抢腐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布姑曙。 她就那樣靜靜地躺著襟交,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伤靠。 梳的紋絲不亂的頭發(fā)上捣域,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天啼染,我揣著相機(jī)與錄音,去河邊找鬼焕梅。 笑死迹鹅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贞言。 我是一名探鬼主播斜棚,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼该窗!你這毒婦竟也來了弟蚀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤酗失,失蹤者是張志新(化名)和其女友劉穎义钉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體规肴,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捶闸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拖刃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片删壮。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖序调,靈堂內(nèi)的尸體忽然破棺而出醉锅,到底是詐尸還是另有隱情,我是刑警寧澤发绢,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布硬耍,位于F島的核電站,受9級特大地震影響边酒,放射性物質(zhì)發(fā)生泄漏经柴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一墩朦、第九天 我趴在偏房一處隱蔽的房頂上張望坯认。 院中可真熱鬧,春花似錦氓涣、人聲如沸牛哺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽引润。三九已至,卻和暖如春痒玩,著一層夾襖步出監(jiān)牢的瞬間淳附,已是汗流浹背议慰。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奴曙,地道東北人别凹。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像洽糟,于是被迫代替她去往敵國和親炉菲。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

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