環境:公司決定使用寬表,將10個相關的大表進行全量關聯 程序員
(1個上億級別的表,5個上千萬的表,剩下的表都不到百萬的表) sql
花了兩天的時間研究,測試 apache
例如: a~g這幾個表中,a表爲上億級別的表,5個上千萬的表,剩下爲表都百萬的表 函數
select a.uesrid,b.citycode,b.register_num, ... ,g.active_num from (select userid,citycode from a) left outer join (select userid,register_num from b) on (a.userid=b.userid) ... left outer join (select userid,active_num from g) on (a.userid=b.userid)
你會發現
最後一個job異常慢,而且reduce爲1。 oop
也多人會說,你傻逼呀,設置reduce數呀,對這是一個好辦法,可是結果如何呢? 性能
#設置傳輸格式 set mapred.output.compress=true; set hive.exec.compress.output=true; set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec; set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec; #設置200個reduces set mapred.reduce.tasks=200; #設置並行(甚至還。。。設置並行) set hive.exec.parallel=true; set hive.exec.parallel.thread.number=16; //同一個sql容許最大並行度,默認爲8
草,我就是按照網上各類教程,測試了一成天,仍是最後一個reduce爲1;(我但是上億級別噢!!!) 學習
hive自動分配reduce的計算方法 測試
1. hive.exec.reducers.bytes.per.reducer(默認爲1000^3) spa
2. hive.exec.reducers.max(默認爲999) code
計算reducer數的公式很簡單:
N=min(參數2,總輸入數據量/參數1)
而後查詢得知:
reduce爲1,是由於:
沒有使用group by
使用了order by
笛卡爾積
我TM都使了一遍,仍是reduce=1,我當時很無語,就尼瑪不能再作清楚一點嗎?(我但是小白呀!!!)
時間:3個小時都沒跑完,一直都是83%
因此hadoop,看到了這個語句,就會分配一個reduce
如何欺騙hive分配reduce呢?
而後修改腳本(固然上面的 設置reduce數 這個不能少噢)
# 如何欺騙hive多分配reduce select a.uesrid,b.citycode,sum(b.register_num), ... ,sum(g.active_num) # 求聚合函數 from (select userid,citycode from x) # x,y表示這幾個表中最小的一個表 full outer join (select userid,unregister from y) # x,y表示這幾個表中最小的一個表 on (x.userid=y.userid) # (可交替的設置 y.userid=b.userid) full outer join (select userid,register_num from b) on (x.userid=b.userid) # 關聯條件,都用小表進行關聯 ... right outer join (select userid,active_num from a) # 最大的表放在最後 on (y.userid=a.userid) # (可交替的設置 y.userid=b.userid) group by a.userid,b.citycode; # 最後進行group by
使用聚合函數,加 group by
而後小表放在前面(有人說:我TM要全部的信息,那你就用全鏈接唄)
而後大表通常就日後排,從小到大,一順排下來就行
這樣就能欺騙hive分配多個reduce,達到調優的效果
時間:15分鐘不到,興奮到高潮了嗎?哈哈
缺點:
生成200個文件,比較麻煩
設置並行,對性能要求有點高,因此適度設置並行數量就行
並行參數,僅作參考
當參數爲false的時候,三個job是順序的執行
set hive.exec.parallel=false;
可是能夠看出來其實兩個子查詢中的sql並沒有關係,能夠並行的跑
set hive.exec.parallel=true;
hive> set hive.exec.parallel.thread.number; (若是機器通常,能夠並行設置3,感受比較合理)
hive.exec.parallel.thread.number=8 默認並行數爲8
過高興了,做爲一個程序員,要求不高:電腦高配,作的事情有挑戰,而且花幾天時間能調通,就知足勒
樂於分享交流,但願能幫到像我同樣遇到此困難的人,呵呵
it技術的進步,不就是這樣相互交流共享學習嗎?
呵呵,那麼。。。你作到嗎?