hive性能优化指南
1.概述
繼續(xù)《hive性能優(yōu)化指南--初級篇》一文中的剩余部分,本篇博客贅述了在工作中總結(jié)Hive的常用優(yōu)化手段和在工作中使用Hive出現(xiàn)的問題。下面開始本篇文章的優(yōu)化介紹。
2.介紹
首先,我們來看看Hadoop的計算框架特性,在此特性下會衍生哪些問題?
- 數(shù)據(jù)量大不是問題,數(shù)據(jù)傾斜是個問題。
- jobs數(shù)比較多的作業(yè)運行效率相對比較低,比如即使有幾百行的表,如果多次關(guān)聯(lián)多次匯總,產(chǎn)生十幾個jobs,耗時很長。原因是map reduce作業(yè)初始化的時間是比較長的。
- sum,count,max,min等UDAF,不怕數(shù)據(jù)傾斜問題,hadoop在map端的匯總合并優(yōu)化,使數(shù)據(jù)傾斜不成問題。
- count(distinct ),在數(shù)據(jù)量大的情況下,效率較低,如果是多count(distinct )效率更低,因為count(distinct)是按group by 字段分組,按distinct字段排序,一般這種分布方式是很傾斜的。舉個例子:比如男uv,女uv,像淘寶一天30億的pv,如果按性別分組,分配2個 reduce,每個reduce處理15億數(shù)據(jù)。
面對這些問題,我們能有哪些有效的優(yōu)化手段呢?下面列出一些在工作有效可行的優(yōu)化手段:
- 好的模型設(shè)計事半功倍。
- 解決數(shù)據(jù)傾斜問題。
- 減少job數(shù)。
- 設(shè)置合理的map reduce的task數(shù),能有效提升性能。(比如,10w+級別的計算,用160個reduce,那是相當(dāng)?shù)睦速M,1個足夠)。
- 了解數(shù)據(jù)分布,自己動手解決數(shù)據(jù)傾斜問題是個不錯的選擇。set hive.groupby.skewindata=true;這是通用的算法優(yōu)化,但算法優(yōu)化有時不能適應(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)化時把握整體,單個作業(yè)最優(yōu)不如整體最優(yōu)。
而接下來,我們心中應(yīng)該會有一些疑問,影響性能的根源是什么?
3.性能低下的根源
hive性能優(yōu)化時,把HiveQL當(dāng)做M/R程序來讀,即從M/R的運行角度來考慮優(yōu)化性能,從更底層思考如何優(yōu)化運算性能,而不僅僅局限于邏輯代碼的替換層面。
RAC(Real Application Cluster)真正應(yīng)用集群就像一輛機動靈活的小貨車,響應(yīng)快;Hadoop就像吞吐量巨大的輪船,啟動開銷大,如果每次只做小數(shù)量的輸入輸出,利用率 將會很低。所以用好Hadoop的首要任務(wù)是增大每次任務(wù)所搭載的數(shù)據(jù)量。
Hadoop的核心能力是parition和sort,因而這也是優(yōu)化的根本。
觀察Hadoop處理數(shù)據(jù)的過程,有幾個顯著的特征:
- 數(shù)據(jù)的大規(guī)模并不是負(fù)載重點,造成運行壓力過大是因為運行數(shù)據(jù)的傾斜。
- jobs數(shù)比較多的作業(yè)運行效率相對比較低,比如即使有幾百行的表,如果多次關(guān)聯(lián)對此匯總,產(chǎn)生幾十個jobs,將會需要30分鐘以上的時間且大部分時間被用于作業(yè)分配,初始化和數(shù)據(jù)輸出。M/R作業(yè)初始化的時間是比較耗時間資源的一個部分。
- 在使用SUM,COUNT,MAX,MIN等UDAF函數(shù)時,不怕數(shù)據(jù)傾斜問題,Hadoop在Map端的匯總合并優(yōu)化過,使數(shù)據(jù)傾斜不成問題。
- COUNT(DISTINCT)在數(shù)據(jù)量大的情況下,效率較低,如果多COUNT(DISTINCT)效率更低,因為 COUNT(DISTINCT)是按GROUP BY字段分組,按DISTINCT字段排序,一般這種分布式方式是很傾斜的;比如:男UV,女UV,淘寶一天30億的PV,如果按性別分組,分配2個 reduce,每個reduce處理15億數(shù)據(jù)。
- 數(shù)據(jù)傾斜是導(dǎo)致效率大幅降低的主要原因,可以采用多一次 Map/Reduce 的方法, 避免傾斜。
最后得出的結(jié)論是:避實就虛,用 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)化控制選項。
4.1 列裁剪
Hive 在讀數(shù)據(jù)的時候,可以只讀取查詢中所需要用到的列,而忽略其它列。 例如,若有以下查詢:
?
SELECT a,b FROM q WHERE e<10;?
在實施此項查詢中,Q 表有 5 列(a,b,c,d,e),Hive 只讀取查詢邏輯中真實需要 的 3 列 a、b、e,而忽略列 c,d;這樣做節(jié)省了讀取開銷,中間表存儲開銷和數(shù)據(jù)整合開銷。
裁剪所對應(yīng)的參數(shù)項為:hive.optimize.cp=true(默認(rèn)值為true)
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)值為true)
4.3 JOIN操作
在使用寫有 Join 操作的查詢語句時有一條原則:應(yīng)該將條目少的表/子查詢放在 Join 操作符的左邊。原因是在 Join 操作的 Reduce 階段,位于 Join 操作符左邊的表的內(nèi)容會被加載進(jìn)內(nèi)存,載入條目較少的表可以有效減少 OOM(out of memory)即內(nèi)存溢出。所以對于同一個 key 來說,對應(yīng)的 value 值小的放前,大的放后,這便是“小表放前”原則。對于一條語句中有多個 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 的時候也是一樣
如果 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)的,上述查詢和以下查詢是等價的:??
?
?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.4 MAP 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.5 GROUP BY操作
進(jìn)行GROUP BY操作時需要注意一下幾點:
- Map端部分聚合
事實上并不是所有的聚合操作都需要在reduce部分進(jìn)行,很多聚合操作都可以先在Map端進(jìn)行部分聚合,然后reduce端得出最終結(jié)果。
這里需要修改的參數(shù)為:
hive.map.aggr=true(用于設(shè)定是否在 map 端進(jìn)行聚合,默認(rèn)值為true) hive.groupby.mapaggr.checkinterval=100000(用于設(shè)定 map 端進(jìn)行聚合操作的條目數(shù))
- 有數(shù)據(jù)傾斜時進(jìn)行負(fù)載均衡
此處需要設(shè)定 hive.groupby.skewindata,當(dāng)選項設(shè)定為 true 是,生成的查詢計劃有兩 個 MapReduce 任務(wù)。在第一個 MapReduce 中,map 的輸出結(jié)果集合會隨機分布到 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)值為true)
- 是否合并Reduce 端輸出文件:hive.merge.mapredfiles=false(默認(rèn)值為false)
- 合并文件的大小:hive.merge.size.per.task=256*1000*1000(默認(rèn)值為 256000000)
5.程序角度優(yōu)化
5.1 熟練使用SQL提高查詢
熟練地使用 SQL,能寫出高效率的查詢語句。
場景:有一張 user 表,為賣家每天收到表,user_id,ds(日期)為 key,屬性有主營類目,指標(biāo)有交易金額,交易筆數(shù)。每天要取前10天的總收入,總筆數(shù),和最近一天的主營類目。
解決方法 1:常用方法
?
?INSERT OVERWRITE TABLE t1
SELECT user_id,substr(MAX(CONCAT(ds,cat),9) AS main_cat) FROM users
WHERE ds=20120329 // 20120329 為日期列的值,實際代碼中可以用函數(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;
?
下面給出方法1的思路,實現(xiàn)步驟如下:
第一步:利用分析函數(shù),取每個 user_id 最近一天的主營類目,存入臨時表 t1。
第二步:匯總 10 天的總交易金額,交易筆數(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é)省了兩個臨時表的讀寫是一個關(guān)鍵原因,這種方式也適用于 Oracle 中的數(shù)據(jù)查找工作。?
? ? ? SQL 具有普適性,很多 SQL 通用的優(yōu)化方案在 Hadoop 分布式計算方式中也可以達(dá)到效果。
5.2 無效ID在關(guān)聯(lián)時的數(shù)據(jù)傾斜問題
問題:日志中常會出現(xiàn)信息丟失,比如每日約為 20 億的全網(wǎng)日志,其中的 user_id 為主 鍵,在日志收集過程中會丟失,出現(xiàn)主鍵為 null 的情況,如果取其中的 user_id 和 bmw_users 關(guān)聯(lián),就會碰到數(shù)據(jù)傾斜的問題。原因是 Hive 中,主鍵為 null 值的項會被當(dāng)做相同的 Key 而分配進(jìn)同一個計算 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:user_id 為空的不參與關(guān)聯(lián),函數(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)致運行時長超過 1 小時,解決方法 1 運行每日平均時長 25 分鐘,解決方法 2 運行的每日平均時長在 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 變成一個字符串加上隨機數(shù),就能把傾斜的 數(shù)據(jù)分到不同的Reduce上,從而解決數(shù)據(jù)傾斜問題。因為空值不參與關(guān)聯(lián),即使分到不同 的 Reduce 上,也不會影響最終的結(jié)果。附上 Hadoop 通用關(guān)聯(lián)的實現(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 上了,解決的方法驗證了這個猜測。
解決方法:把數(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 小時 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 的時候,把 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)),如果不是因為 Hive Bug 或者性能上的考量(曾經(jīng)出現(xiàn)如果不執(zhí)行子查詢 GROUP BY,數(shù)據(jù)得不到正確的結(jié)果的 Hive Bug)。所以這個 Hive 按經(jīng)驗轉(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 的 計算框架,不怕數(shù)據(jù)多,就怕作業(yè)數(shù)多。
但如果換成是其他計算平臺如 Oracle,那就不一定了,因為把大的輸入拆成兩個輸入, 分別排序匯總后 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)。這時采用 臨時表消滅 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;
?
上面代碼運行會有 5 個 jobs。加入先 JOIN 生存臨時表的話 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.6 GROUP BY替代COUNT(DISTINCT)達(dá)到優(yōu)化效果
? ? ? ? 計算 uv 的時候,經(jīng)常會用到 COUNT(DISTINCT),但在數(shù)據(jù)比較傾斜的時候 COUNT(DISTINCT)?會比較慢。這時可以嘗試用 GROUP BY 改寫代碼計算 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)計每日IP
CREATE TABLE ip_2014_12_29 AS SELECT COUNT(DISTINCT ip) AS IP FROM logdfs WHERE logdate='2014_12_29';
耗時:24.805 seconds
#統(tǒng)計每日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;
耗時:46.833 seconds
?
測試結(jié)果表名:明顯改造后的語句比之前耗時,這是因為改造后的語句有2個SELECT,多了一個job,這樣在數(shù)據(jù)量小的時候,數(shù)據(jù)不會存在傾斜問題。
?
6.優(yōu)化總結(jié)
優(yōu)化時,把hive sql當(dāng)做mapreduce程序來讀,會有意想不到的驚喜。理解hadoop的核心能力,是hive優(yōu)化的根本。這是這一年來,項目組所有成員寶貴的經(jīng)驗總結(jié)。
- 長期觀察hadoop處理數(shù)據(jù)的過程,有幾個顯著的特征:
- 優(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ù)來自動計算reduce的個數(shù),而是用這個參數(shù)來啟動reducer。默認(rèn)是-1。
? ? ? ?參數(shù)設(shè)置的影響
如果reduce太少:如果數(shù)據(jù)量很大,會導(dǎo)致這個reduce異常的慢,從而導(dǎo)致這個任務(wù)不能結(jié)束,也有可能會OOM 2、如果reduce太多:? 產(chǎn)生的小文件太多,合并起來代價太高,namenode的內(nèi)存占用也會增大。如果我們不指定mapred.reduce.tasks, hive會自動計算需要多少個reducer。
8.結(jié)束語
這篇博客就和大家分享到這里,后面再有好的優(yōu)化手段在和大家分享,感謝大家在百忙之中花時間來閱讀我這篇博客,如果在優(yōu)化的過程中有什么問題可以加群進(jìn)行討論或發(fā)送郵件給我,我會盡我所能為您解答,與君共勉!
原文鏈接:http://www.thebigdata.cn/QiTa/13858.html
總結(jié)
以上是生活随笔為你收集整理的hive性能优化指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark性能相关参数配置详解
- 下一篇: 深入浅出学Hive:Hive QL