Hive優(yōu)化總結(jié)

一.常用參數(shù)

開啟中間結(jié)果壓縮? 對于輸入數(shù)據(jù)量有少許減少,但是cpu開銷增大珠洗,對于單stage任務總體不理想

set hive.exec.compress.intermediate=true;

set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec

開啟最終輸出壓縮

set hive.exec.compress.output=true;

mapred.compress.map.output? ?map的輸出是否壓縮

mapred.map.output.compression.codec??map的輸出壓縮方式

mapred.output.compress?reduce的輸出是否壓縮

mapred.output.compression.codecreduce的輸出壓縮方式

set mapred.output.compression.codec=org.apache.hadoop.io.compress.GZipCodec

減少MAP數(shù)量

設置MAP的分割文件大小 set mapred.max.split.size=512000000

增加MR中MARTASK的可使用內(nèi)存內(nèi)存? set mapreduce.map.memory.mb; 以解決MAP時的OOM

map執(zhí)行時間:map任務啟動和初始化的時間+邏輯處理的時間忱屑。

所以 如果小文件過多茵典,可以執(zhí)行set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;在MAP開始前進行小文件合并

調(diào)整reduce參數(shù)的值

set mapred.reduce.tasks = 15;

set hive.exec.reducers.bytes.per.reducer =

一般根據(jù)輸入文件的總大小,用它的estimation函數(shù)來自動計算reduce的個數(shù):reduce個數(shù) = InputFileSize / bytes per reducer

設置并行度

set hive.exec.paralle=true?

set hive.exec.parallel.thread.number=16;

設置mapjoin

set hive.auto.convert.join = true;

set hive.mapjoin.smalltable.filesize = 2500000 ;//刷入內(nèi)存表的大小(字節(jié))?

設置嚴格模式(一般設置成全局級,而非會話級)

set hive.marped.mode=strict

防止用戶執(zhí)行那些可能意想不到的不好的影響的查詢? 分區(qū)表必須指定分區(qū)

開啟動態(tài)分區(qū)排序優(yōu)化 set hive.optimize.sort.dynamic.partition

? 開啟map任務的mapreduce會引入reduce過程狂秘,這樣動態(tài)分區(qū)的那個字段比如日期在傳到reducer時會被排序硕噩。由于分區(qū)字段是排序的假残,因此每個reducer只需要保持一個文件寫入器(file writer)隨時處于打開狀態(tài)(不然每個動態(tài)分區(qū)都需要打開一個寫入器),在收到來自特定分區(qū)的所有行后榴徐,關(guān)閉記錄寫入器(record writer)守问,從而減小內(nèi)存壓力

二、日常sql編寫技巧

1.將大表放后頭

? ? Hive假定查詢中最后的一個表是大表坑资。它會將其它表緩存起來耗帕,然后掃描最后那個表。 因此通常需要將小表放前面袱贮,或者標記哪張表是大表:/*streamtable(table_name) */

2.使用相同的連接鍵

? ? 當對3個或者更多個表進行join連接時仿便,如果每個on子句都使用相同的連接鍵的話,那么只會產(chǎn)生一個MapReduce job。

3.盡量盡早地過濾數(shù)據(jù)

? ? 減少每個階段的數(shù)據(jù)量,對于分區(qū)表要加分區(qū)嗽仪,同時只選擇需要使用到的字段荒勇。

4.盡量原子化操作

? ? 盡量避免一個SQL包含復雜邏輯,可以使用中間表來完成復雜的邏輯

5.limit 語句快速出結(jié)果

? ? 尤其是spark sql

數(shù)據(jù)傾斜

原因

1)闻坚、key分布不均勻

2)沽翔、業(yè)務數(shù)據(jù)本身的特性

3)、建表時考慮不周

4)窿凤、某些SQL語句本身就有數(shù)據(jù)傾斜

解決方案:

場景1:join時小表放在前面仅偎,并開啟mapjoin??? set hive.auto.convert.join = true;

? ? ? ? 或使用?set hive.optimize.skewinfo=table_B:(selleer_id) [ ( "0") ("1") ) ]? ?說明B表的值集中在0和1上

      set hive.optimize.skewjoin = true;

場景2:借助隨機函數(shù) 對關(guān)聯(lián)不到的 如0值或空值進行過濾或隨機函數(shù)替換處理,避免傾斜

場景3:方案1:通過 union all將數(shù)據(jù)進行分離雳殊,聚集值單獨處理

? ? ? ? ? ? ?方案2:在MAP端 預聚合 set hive.map.aggr=true

這個設置可以將頂層的聚合操作放在Map階段執(zhí)行橘沥,從而減輕清洗階段數(shù)據(jù)傳輸和Reduce階段的執(zhí)行時間,提升總體性能夯秃。確點是更廢內(nèi)存

? ? ? ? ? ? ?方案3:? ? 1.hive.groupby.skewindata=true? (set hive.groupby.mapaggr.checkinterval=100000;這個是group的鍵對應的記錄條數(shù)超過這個值則會進行優(yōu)化? 注意:該參數(shù)僅支持單列

hive.groupby.skewindata=true 控制生成兩個MR Job座咆。

第一個MRJob 中,Map的輸出結(jié)果集合會隨機分布到Reduce中仓洼,每個Reduce做部分聚合操作介陶,并輸出結(jié)果,這樣處理的結(jié)果是相同的GroupBy Key有可能被分發(fā)到不同的Reduce中衬潦,從而達到負載均衡的目的斤蔓;第二個MRJob再根據(jù)預處理的數(shù)據(jù)結(jié)果按照GroupBy Key分布到Reduce中(這個過程可以保證相同的GroupBy Key被分布到同一個Reduce中

場景4:?select count(distinct udid) from T 改寫成? select count(1) from( select distinct udid from T) t;

區(qū)別:增加一個JOB植酥,同時后者在執(zhí)行子查詢的時候镀岛,可以有多個reduce參與計算,而前者只有一個reduce


大表JOIN大表時性能問題

1.分桶

建表時采用表分桶的設計友驮,同時join時可以嘗試使用bucket map join漂羊;基本處理方法是將兩個表在join key上做hash bucket,將較小表(sale_history)的bucket設置為較大表(call_result)的數(shù)倍卸留。這樣數(shù)據(jù)就會按照join key做hash bucket走越。這樣做的話,小表依然會復制到各個節(jié)點上耻瑟,map join的時候旨指,小表的每一組bucket加載成hashtable,與對應的大表bucket做局部join喳整。

如果兩表的join key 都具有唯一性(是主鍵關(guān)聯(lián))谆构,還可以進一步做sort merge bucket map join ;做法是兩表都做bucket的基礎(chǔ)上框都,每個bucket內(nèi)部還要進行排序搬素,這樣做得好處就是在兩邊的bucket要做局部join的時候,用類似merge sort算法中的merge操作一樣把兩個bucket順序遍歷一下即可。

1.1 條件

1) set hive.optimize.bucketmapjoin = true;

2) 一個表的bucket數(shù)是另一個表bucket數(shù)的整數(shù)倍

3) bucket列 == join列

4) 必須是應用在map join的場景中

1.2 注意

1)如果表不是bucket的熬尺,只是做普通join


2.業(yè)務場景處理:

? ? ? ?看懂實現(xiàn)邏輯即可摸屠,核心邏輯,無外乎是維護一個大客戶表粱哼,對數(shù)據(jù)進行放大季二,結(jié)合隨機函數(shù),生成新的關(guān)聯(lián)鍵揭措,確保只關(guān)聯(lián)到其中的一條即可戒傻,將數(shù)據(jù)的集中度進行打散

  1).通用方案

      此方案的思路是建立一個numbers表,其值只有一列int 行蜂筹,比如從1到10(具體值可根據(jù)傾斜程度確定)需纳,然后放大B表10倍,再取模join艺挪。代碼如下:

      select

         m.buyer_id,

        sum(pay_cnt_90day)? as pay_cnt_90day,

        sum(case when m.sale_level = 0? then pay_cnt_90day? end)? as pay_cnt_90day_s0,

        sum(case when m.sale_level = 1? then pay_cnt_90day? end)? as pay_cnt_90day_s1,

        sum(case when m.sale_level = 2? then pay_cnt_90day? end)? as pay_cnt_90day_s2,

        sum(case when m.sale_level = 3? then pay_cnt_90day? end)? as pay_cnt_90day_s3,

        sum(case when m.sale_level = 4? then pay_cnt_90day? end)? as pay_cnt_90day_s4,

        sum(case when m.sale_level = 5? then pay_cnt_90day? end)? as pay_cnt_90day_s5

      from?(

        select??a.buer_id,? a.seller_id,? b.sale_level, a.pay_cnt_90day

        from?(??select buyer_id,? seller_id,? pay_cnt_90day? ?from table_A)? a

        join

        ? ? ? ?(

          select? /*+mapjoin(members)*/

            seller_id,? sale_level ,member

          from table_B

? ?         join members

          )? b

        on? a.seller_id? = b.seller_id

          and mod(a.pay_cnt_90day,10)+1 = b.number?

        )? m

      group by?m.buyer_id

?        此思路的核心在于不翩,既然按照seller_id分發(fā)會傾斜,那么再人工增加一列進行分發(fā)麻裳,這樣之前傾斜的值的傾斜程度會減少到原來的1/10口蝠,可以通過配置numbers表改放大倍數(shù)來降低傾斜程度,

      但這樣做的一個弊端是B表也會膨脹N倍津坑。

  2).專用方案

        通用方案的思路把B表的每條數(shù)據(jù)都放大了相同的倍數(shù)妙蔗,實際上這是不需要的,只需要把大賣家放大倍數(shù)即可:需要首先知道大賣家的名單疆瑰,即先建立一個臨時表動態(tài)存放每天最新的大賣家(

      比如dim_big_seller),同時此表的大賣家要膨脹預先設定的倍數(shù)(1000倍)眉反。

        在A表和B表分別新建一個join列,其邏輯為:如果是大賣家穆役,那么concat一個隨機分配正整數(shù)(0到預定義的倍數(shù)之間寸五,本例為0~1000);如果不是耿币,保持不變梳杏。具體代碼如下:

      select

         m.buyer_id,

        sum(pay_cnt_90day)? as pay_cnt_90day,

        sum(case when m.sale_level = 0? then pay_cnt_90day? end)? as pay_cnt_90day_s0,

        sum(case when m.sale_level = 1? then pay_cnt_90day? end)? as pay_cnt_90day_s1,

        sum(case when m.sale_level = 2? then pay_cnt_90day? end)? as pay_cnt_90day_s2,

        sum(case when m.sale_level = 3? then pay_cnt_90day? end)? as pay_cnt_90day_s3,

        sum(case when m.sale_level = 4? then pay_cnt_90day? end)? as pay_cnt_90day_s4,

        sum(case when m.sale_level = 5? then pay_cnt_90day? end)? as pay_cnt_90day_s5

      from?(

        select??a.buer_id,? a.seller_id,? b.sale_level, a.pay_cnt_90day

        from?(??

          select??/*+mapjoin(big)*/

             buyer_id,? seller_id,? pay_cnt_90day,

             if(big.seller_id is not null, concat(? table_A.seller_id,? 'rnd',? cast(? rand() * 1000 as bigint ), table_A.seller_id)? as seller_id_joinkey

            ??from table_A

            ? ?left outer join

             --big表seller_id有重復,請注意一定要group by 后再join,保證table_A的行數(shù)保持不變

            ⊙徒印(select seller_id? from dim_big_seller? group by seller_id)big

             on table_A.seller_id = big.seller_id

        )? a

        join

        ? ? ? ?(

          select? /*+mapjoin(big)*/

            seller_id,? sale_level ,

            --big表的seller_id_joinkey生成邏輯和上面的生成邏輯一樣

            coalesce(seller_id_joinkey,table_B.seller_id) as seller_id_joinkey

          from table_B

? ?         left out join

          --table_B表join大賣家表后大賣家行數(shù)擴大1000倍十性,其它賣家行數(shù)保持不變

          (select seller_id, seller_id_joinkey from dim_big_seller) big

          on table_B.seller_id= big.seller_id

          )? b

        on? a.seller_id_joinkey= b.seller_id_joinkey

        )? m

      group by?m.buyer_id

      相比通用方案,專用方案的運行效率明細好了許多塑悼,因為只是將B表中大賣家的行數(shù)放大了1000倍劲适,其它賣家的行數(shù)保持不變,但同時代碼復雜了很多拢肆,而且必須首先建立大數(shù)據(jù)表减响。

   3).動態(tài)一分為二

      實際上方案2和3都用了一分為二的思想靖诗,但是都不徹底,對于mapjoin不能解決的問題支示,終極解決方案是動態(tài)一分為二刊橘,即對傾斜的鍵值和不傾斜的鍵值分開處理,不傾斜的正常join即可颂鸿,

    傾斜的把他們找出來做mapjoin,最后union all其結(jié)果即可促绵。

      但是此種解決方案比較麻煩,代碼復雜而且需要一個臨時表存放傾斜的鍵值嘴纺。代碼如下:

      --由于數(shù)據(jù)傾斜败晴,先找出90天買家超過10000的賣家

      insert overwrite table? temp_table_B

      select?

        m.seller_id,? n.sale_level

      from (

        select? ?seller_id

        from (

          select seller_id,count(buyer_id) as byr_cnt

          from table_A

          group by seller_id

          ) a

        where a.byr_cnt >10000

        ) m

      left join?

      (

       select seller_id, sale_level? from table_B

      ) n

     ? ?on m.seller_id = n.seller_id;

      --對于90天買家超過10000的賣家直接mapjoin,對其它賣家直接正常join即可。

大表關(guān)聯(lián)案例? 引用自? https://www.cnblogs.com/shaosks/p/9491905.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栽渴,一起剝皮案震驚了整個濱河市尖坤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闲擦,老刑警劉巖慢味,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墅冷,居然都是意外死亡纯路,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門寞忿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來驰唬,“玉大人,你說我怎么就攤上這事腔彰〗斜啵” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵萍桌,是天一觀的道長宵溅。 經(jīng)常有香客問我,道長上炎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任雏搂,我火速辦了婚禮藕施,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凸郑。我一直安慰自己裳食,他們只是感情好,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布芙沥。 她就那樣靜靜地躺著诲祸,像睡著了一般浊吏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上救氯,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天找田,我揣著相機與錄音,去河邊找鬼着憨。 笑死墩衙,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的甲抖。 我是一名探鬼主播漆改,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼准谚!你這毒婦竟也來了挫剑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤柱衔,失蹤者是張志新(化名)和其女友劉穎暮顺,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秀存,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡捶码,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了或链。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惫恼。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖澳盐,靈堂內(nèi)的尸體忽然破棺而出祈纯,到底是詐尸還是另有隱情,我是刑警寧澤叼耙,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布腕窥,位于F島的核電站,受9級特大地震影響筛婉,放射性物質(zhì)發(fā)生泄漏簇爆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一爽撒、第九天 我趴在偏房一處隱蔽的房頂上張望入蛆。 院中可真熱鬧,春花似錦硕勿、人聲如沸哨毁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扼褪。三九已至想幻,卻和暖如春具壮,著一層夾襖步出監(jiān)牢的瞬間拾并,已是汗流浹背均芽。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工匿沛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梆砸,地道東北人沪铭。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓串稀,卻偏偏與公主長得像粥庄,于是被迫代替她去往敵國和親岖瑰。 傳聞我的和親對象是個殘疾皇子叛买,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

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