Hive優(yōu)化

Hive優(yōu)化

今天的主要內(nèi)容——Hive優(yōu)化

  • Fetch抓取

    • Hive 中對某些情況的查詢可以不必使用 MapReduce 計(jì)算
  • 本地模式

    • 當(dāng)數(shù)據(jù)量非常小的時(shí)候竞阐,通過設(shè)置本地模式在單臺(tái)機(jī)器上處理所有任務(wù)喘沿,可提高效率
  • 表的優(yōu)化

    • 小表join大表

    • 大表join大表

      • 空KEY過濾

      • 空Key轉(zhuǎn)化

    • MapJoin

      • 注意:MapJoin的工作機(jī)制

      • mapjoin對分桶表join的優(yōu)化

    • Group By

      • Map端的聚合
    • Count(Distinct) 去重統(tǒng)計(jì)

      • 一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替換
    • 笛卡爾積

      • 避免使用笛卡爾積
    • 行列過濾

      • 避免使用select *

      • 通過子查詢后蓖救,再關(guān)聯(lián)表

    • 動(dòng)態(tài)分區(qū)的調(diào)整

      • 注意動(dòng)態(tài)分區(qū)的語法
    • 分桶

      • 分桶的理解以及插入數(shù)據(jù)時(shí)注意事項(xiàng)
    • 分區(qū)

      • 分區(qū)的理解
    • left semi join

      • 對 in/exists的子查詢提供了更高效的優(yōu)化方式
    • insert into 代替 union all

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

    • 合理設(shè)置Map數(shù)量

    • 小文件合并

    • 復(fù)雜文件增加Map數(shù)

    • 合理設(shè)置Reduce數(shù)量

  • 并行執(zhí)行

  • 嚴(yán)格模式

  • JVM重用(同一個(gè)job中的tasks)

  • 推測執(zhí)行

  • 壓縮

  • 執(zhí)行計(jì)劃

一、Fetch抓取

  • 概念:

    • Fetch 抓取是指旧困,Hive 中對某些情況的查詢可以不必使用 MapReduce 計(jì)算醇份。

    • 例如:

      • SELECT * FROM emp;

      • 在這種情況下,Hive 可以簡單地讀取 emp 對應(yīng)的存儲(chǔ)目錄下的文件吼具,然后輸出查詢結(jié)果到控制臺(tái)僚纷。

  • 操作

    • 在 hive-default.xml.template 文件中 hive.fetch.task.conversion屬性值設(shè)置

    • 修改屬性值:

      • hive.fetch.task.conversion

        • CDH5.3.6中對應(yīng)的hive 0.13.1中,該屬性值默認(rèn)為minimal

        • 之后新版中該屬性值默認(rèn)為more

             * none : disable hive.fetch.task.conversion
             
            * minimal : SELECT STAR, FILTER on partition columns, LIMIT only
                
                * minimal格式下:只有select * ; filter分區(qū)列過濾 下不走M(jìn)R
          
             * more : SELECT, FILTER, LIMIT only (support TABLESAMPLE and virtual columns)
          
                * more格式下:select拗盒;filter怖竭;limit不走M(jìn)R
          

二、本地模式(小任務(wù))

  • 概念

    • 當(dāng)數(shù)據(jù)量非常小時(shí)陡蝇,在這種情況下痊臭,為查詢觸發(fā)執(zhí)行任務(wù)時(shí)消耗可能會(huì)比實(shí)際 job 的執(zhí)行時(shí)間要多的多哮肚。

    • 可以聯(lián)系到hadoop運(yùn)行MapReduce job時(shí)候:

      • 當(dāng)job很小時(shí),application master會(huì)在自己的本地虛擬機(jī)中運(yùn)行tasks广匙,這時(shí)相比較于allocating and running in new containers的成本而言的绽左,也就是說相比較于開啟一個(gè)新的container并耗費(fèi)資源拉取數(shù)據(jù)的時(shí)間比job執(zhí)行時(shí)間都長。
    • 滿足以下條件時(shí)艇潭,可以使Hive 通過本地模式在單臺(tái)機(jī)器上處理所有的任務(wù)。

      • job的輸入數(shù)據(jù)大小必須小于參數(shù):hive.exec.mode.local.auto.inputbytes.max(默認(rèn)128MB)

      • 輸入文件的個(gè)數(shù)必須小于參數(shù)hive.exec.mode.local.auto.input.files.max戏蔑,默認(rèn)為4

      • job的reduce數(shù)必須為0或者1

  • 操作

    • set hive.exec.mode.local.auto=true; //開啟本地 mr

    • set hive.exec.mode.local.auto.inputbytes.max=50000000;

      • 設(shè)置 local mr 的最大輸入數(shù)據(jù)量蹋凝,當(dāng)輸入數(shù)據(jù)量小于這個(gè)值時(shí)采用 local mr 的方式,默認(rèn)為 134217728总棵,即 128M
    • set hive.exec.mode.local.auto.input.files.max=10;

      • 設(shè)置 local mr 的最大輸入文件個(gè)數(shù)鳍寂,當(dāng)輸入文件個(gè)數(shù)小于這個(gè)值時(shí)采用 local mr 的方式,默認(rèn)為 4

三情龄、表的優(yōu)化

1. 小表join大表

  • 概念

    • 大表放在后面

      • hive在處理每一個(gè)MR階段的join時(shí)迄汛,the last table in the sequence is streamed through the reducers whereas the others are buffered。即最后一張表是通過reducer拉取數(shù)據(jù)得到的骤视,而前面的表均是緩存到內(nèi)存中的鞍爱,因此,為了減少reducer內(nèi)存的使用专酗,選擇將數(shù)據(jù)量大的表放在最后邊睹逃,其他表緩存到reducer中)

      • 因此通常需要將小表放前面,或者標(biāo)記哪張表是大表:/*streamtable(table_name) */

      • 將 key 相對分散祷肯,并且數(shù)據(jù)量小的表放在 join 的左邊沉填,這樣可以有效減少內(nèi)存溢出錯(cuò)誤發(fā)生的幾率;再進(jìn)一步佑笋,可以使用 Group 讓小的維度表(1000 條以下的記錄條數(shù))先進(jìn)內(nèi)存翼闹。在 map 端完成 reduce。(也就是開啟map端的聚合)蒋纬、

    • 使用相同連接鍵

      • 首先要明白: hive是將joins轉(zhuǎn)化為MR任務(wù)去執(zhí)行的猎荠,當(dāng)多張表的連接條件為同一個(gè)join clause則開啟一個(gè)MR任務(wù),當(dāng)不同的join clauses時(shí)颠锉,則開啟多個(gè)MR任務(wù)法牲。

      • 因此,當(dāng)對3個(gè)或者更多個(gè)表進(jìn)行join連接時(shí)琼掠,如果每個(gè)on子句都使用相同的連接鍵的話拒垃,那么只會(huì)產(chǎn)生一個(gè)MapReduce job。

    • 實(shí)際測試發(fā)現(xiàn):新版的 hive 已經(jīng)對小表 JOIN 大表和大表 JOIN 小表進(jìn)行了優(yōu)化瓷蛙。小表放在左邊和右邊已經(jīng)沒有明顯區(qū)別悼瓮。

    • 其實(shí)開啟map端join后戈毒,還可以避免數(shù)據(jù)傾斜問題

  • 操作

    • 設(shè)置屬性值hive.auto.convert.join,默認(rèn)為true

2. 大表join大表

2.1 空KEY過濾

  • 概念

    • 有時(shí) join 超時(shí)是因?yàn)槟承?key 對應(yīng)的數(shù)據(jù)太多横堡,而相同 key 對應(yīng)的數(shù)據(jù)都會(huì)發(fā)送到相同的 reducer 上埋市,從而導(dǎo)致內(nèi)存不夠,

    • 此時(shí)我們應(yīng)該仔細(xì)分析這些異常的 key命贴,很多情況下道宅,這些 key 對應(yīng)的數(shù)據(jù)是異常數(shù)據(jù),我們需要在 SQL 語句中進(jìn)行過濾胸蛛。例如 key 對應(yīng)的字段為空

        insert overwrite table jointable 
        select
            n.*
        from (
            select 
                    *
            from
                nullidtable 
            where id is not null ) n 
        left join ori o on n.id = o.id;
      

2.2 空KEY轉(zhuǎn)化

  • 概念

    • 有時(shí)雖然某個(gè) key 為空對應(yīng)的數(shù)據(jù)很多污茵,但是相應(yīng)的數(shù)據(jù)不是異常數(shù)據(jù),必須要包含在join 的結(jié)果中葬项,此時(shí)我們可以表 a 中 key 為空的字段賦一個(gè)隨機(jī)的值泞当,使得數(shù)據(jù)隨機(jī)均勻地分不到不同的 reducer 上。

    • 此時(shí)注意:空key表full join表民珍,防止數(shù)據(jù)丟失

  • 操作

    • 設(shè)置reduce個(gè)數(shù)

      set mapreduce.job.reduces = 5;

    • join(空KEY轉(zhuǎn)化)

        insert overwrite table jointable
        select
            n.*
        from
            nullidtable n 
        full join ori o
        on case when n.id is null then concat('hive', rand()) else n.id end = o.id;
      

3. MapJoin

  • 概念

    • 如果不指定 MapJoin 或者不符合 MapJoin 的條件襟士,那么 Hive 解析器會(huì)將 Join 操作轉(zhuǎn)換,成 Common Join

    • 即:在 Reduce 階段完成 join嚷量。容易發(fā)生數(shù)據(jù)傾斜陋桂。可以用 MapJoin 把小表全部加載到內(nèi)存在 map 端進(jìn)行 join蝶溶,避免 reducer 處理章喉。

  • 參數(shù)設(shè)置

    • hive.auto.convert.join 設(shè)置mapjoin打開關(guān)閉;默認(rèn)為true
    • hive.mapjoin.smalltable.filesize 設(shè)置小表閾值身坐,默認(rèn)為25000000;25M
  • 深入理解

    • 當(dāng)滿足mapjoin條件時(shí)秸脱,會(huì)自動(dòng)更改為mapJoin

    • 也可以手動(dòng)指定為MapJoin

    • But the mapjoin hint should only be used for the following query

      • if all the inputs are bucketed or sorted,and the join should be converted to a bucketed map-side join or bucketized sort-merge join.

      • 當(dāng)兩張join的表根據(jù)同一列進(jìn)行分桶,且表的分桶數(shù)相同或者成倍數(shù)部蛇,則兩表連接時(shí)會(huì)對應(yīng)join

          select /* + MAPJOIN(b)*/ a.key,a.value from a join b on a.key = b.key
        
        • join can be done on the mapper only

        • Instead of fetching B completely for each mapper of A,only the required buckets are fetched.

        • the mapper processing bucket 1 for A will only fetch bucket 1 of B

        • 需要設(shè)置屬性:set hive.optimize.bucketmapjoin = true;

      • 當(dāng)兩張join的表根據(jù)同一列進(jìn)行分桶且桶內(nèi)根據(jù)此列有序摊唇,且表的分桶數(shù)相同,a sort-merge join can be performed. The corresponding buckets are joined with each other at the mapper.

4. Group By

  • 概念

    • 默認(rèn)情況下涯鲁,Map 階段同一 Key 數(shù)據(jù)分發(fā)給一個(gè) reduce巷查,當(dāng)一個(gè) key 數(shù)據(jù)過大時(shí)就傾斜了。

    • 并不是所有的聚合操作都需要在 Reduce 端完成抹腿,很多聚合操作都可以先在 Map 端進(jìn)行部分聚合岛请,最后在 Reduce 端得出最終結(jié)果。

    • 可對應(yīng)于hadoop的MapReduce中的combine操作警绩,與reduce實(shí)現(xiàn)相同業(yè)務(wù)邏輯崇败,運(yùn)行每一個(gè)map task中,減輕shuffle中從map到reduce的傳輸。

    • 不是所有的聚合都需要進(jìn)行此項(xiàng)優(yōu)化后室。當(dāng)group by 的字段沒有相同的時(shí)缩膝,則無效

      • select * from emp group by empno;

      • 因?yàn)閑mpno沒有重復(fù)的,因此map聚合沒有太大意義岸霹,并且浪費(fèi)資源疾层。

  • 參數(shù)設(shè)置

    • 是否在 Map 端進(jìn)行聚合,默認(rèn)為 True

        hive.map.aggr = true
      
    • 在 Map 端進(jìn)行聚合操作的條目數(shù)目

        hive.groupby.mapaggr.checkinterval = 100000
      
    • 有數(shù)據(jù)傾斜的時(shí)候進(jìn)行負(fù)載均衡(默認(rèn)是 false)

        hive.groupby.skewindata = true
      
        * 當(dāng)選項(xiàng)設(shè)定為 true贡避,生成的查詢計(jì)劃會(huì)有兩個(gè) MR Job痛黎。
        
        * 第一個(gè) MR Job 中,Map 的輸出結(jié)果會(huì)隨機(jī)分布到 Reduce 中刮吧,每個(gè) Reduce 做部分聚合操作舅逸,并輸出結(jié)果,這樣處理的結(jié)果是相同的 Group By Key 有可能被分發(fā)到不同的 Reduce 中皇筛,從而達(dá)到負(fù)載均衡的目的;坠七、
        
        * 第二個(gè) MR Job 再根據(jù)預(yù)處理的數(shù)據(jù)結(jié)果按照 Group By Key 分布到 Reduce 中(這個(gè)過程可以保證相同的 Group By Key 被分布到同一個(gè) Reduce 中)水醋,最后完成最終的聚合操作。
      

5. count(distinct) 去重統(tǒng)計(jì)

  • 概念

    • 數(shù)據(jù)量小的時(shí)候無所謂彪置,數(shù)據(jù)量大的情況下拄踪,由于 COUNT DISTINCT 操作需要用一個(gè)Reduce Task 來完成,這一個(gè) Reduce 需要處理的數(shù)據(jù)量太大拳魁,就會(huì)導(dǎo)致整個(gè) Job 很難完成惶桐,

    • 一般 COUNT DISTINCT 使用先 GROUP BY 再 COUNT 的方式替換:

  • 參數(shù)設(shè)置

    • set mapreduce.job.reduces = xxxx; 對reduce個(gè)數(shù)進(jìn)行設(shè)置

        select 
            count(id)
        from (
            select 
                id
            from
                bigtable
            group by
                id) a;
      
    • 先根據(jù)id進(jìn)行部分聚合,然后統(tǒng)計(jì)個(gè)數(shù)

6. 笛卡爾積

* 盡量避免笛卡爾積潘懊,join 的時(shí)候不加 on 條件姚糊,或者無效的 on 條件,Hive 只能使用 1個(gè) reducer 來完成笛卡爾積

7. 行列過濾

  • 列處理:

    • 在 SELECT 中授舟,只拿需要的列救恨,如果有,盡量使用分區(qū)過濾释树,少用 SELECT *肠槽。
  • 行處理:

    • 在分區(qū)剪裁中,當(dāng)使用外關(guān)聯(lián)時(shí)奢啥,如果將副表的過濾條件寫在 Where 后面那么就會(huì)先全表關(guān)聯(lián)秸仙,之后再過濾,應(yīng)該通過子查詢后桩盲,再關(guān)聯(lián)表

        select 
            b.id
        from
            bigtable b
        join (
            select
                id
            from
                ori 
            where id <= 10 ) o 
        on b.id = o.id;
      

8. 動(dòng)態(tài)分區(qū)調(diào)整

  • 概念

    • 關(guān)系型數(shù)據(jù)庫中寂纪,對分區(qū)表 Insert 數(shù)據(jù)時(shí)候,數(shù)據(jù)庫自動(dòng)會(huì)根據(jù)分區(qū)字段的值赌结,將數(shù)據(jù)插入到相應(yīng)的分區(qū)中

    • Hive 中也提供了類似的機(jī)制弊攘,即動(dòng)態(tài)分區(qū)(Dynamic Partition)抢腐,只不過,使用 Hive 的動(dòng)態(tài)分區(qū)襟交,需要進(jìn)行相應(yīng)的配置迈倍。

  • 參數(shù)設(shè)置

    • 開啟動(dòng)態(tài)分區(qū)功能(默認(rèn) true,開啟)

        hive.exec.dynamic.partition=true
      
    • 設(shè)置為非嚴(yán)格模式(動(dòng)態(tài)分區(qū)的模式捣域,默認(rèn) strict啼染,表示必須指定至少一個(gè)分區(qū)為靜態(tài)分區(qū),nonstrict 模式表示允許所有的分區(qū)字段都可以使用動(dòng)態(tài)分區(qū)焕梅。)

        hive.exec.dynamic.partition.mode=nonstrict
      
    • 在所有執(zhí)行 MR 的節(jié)點(diǎn)上迹鹅,最大一共可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)。

        hive.exec.max.dynamic.partitions=1000
      
    • 在每個(gè)執(zhí)行 MR 的節(jié)點(diǎn)上贞言,最大可以創(chuàng)建多少個(gè)動(dòng)態(tài)分區(qū)斜棚。該參數(shù)需要根據(jù)實(shí)際的數(shù)據(jù)來設(shè)定。比如:源數(shù)據(jù)中包含了一年的數(shù)據(jù)该窗,即 day 字段有 365 個(gè)值弟蚀,那么該參數(shù)就需要設(shè)置成大于 365,如果使用默認(rèn)值 100酗失,則會(huì)報(bào)錯(cuò)义钉。

        hive.exec.max.dynamic.partitions.pernode=100
      
    • 整個(gè) MR Job 中,最大可以創(chuàng)建多少個(gè) HDFS 文件规肴。

        hive.exec.max.created.files=100000
      
    • 當(dāng)有空分區(qū)生成時(shí)捶闸,是否拋出異常。一般不需要設(shè)置拖刃。

        hive.error.on.empty.partition=false
      
  • 操作

      insert overwrite table ori_partitioned_target
      partition (p_time)                              //指定分區(qū)列
      select
          id, time, uid, keyword, url_rank, click_num, click_url, p_time          //分區(qū)列也要作為一個(gè)字段查出
      from
          ori_partitioned;
    

9. 分區(qū)

  • 分區(qū)的理解:

    • 分區(qū)是一種根據(jù)“分區(qū)列”的值對表進(jìn)行粗略劃分的機(jī)制

    • Hive中的每個(gè)分區(qū)對應(yīng)著數(shù)據(jù)庫中相應(yīng)分區(qū)列的一個(gè)索引删壮;

      • 每個(gè)分區(qū)對應(yīng)著表下的一個(gè)目錄

      • 分區(qū)在HDFS上的表現(xiàn)形式與表在 HDFS上的表現(xiàn)形式相同,都是以子目錄的形式存在

    • 查詢時(shí)通過where選擇查詢的指定分區(qū)兑牡,可提高查詢效率醉锅。

      • 當(dāng)只需要遍歷小范圍內(nèi)的數(shù)據(jù)時(shí)或一定條件下的數(shù)據(jù),可有效減少掃描數(shù)據(jù)的數(shù)量
    • 一個(gè)表可在多個(gè)維度上進(jìn)行分區(qū)发绢,且分區(qū)可以嵌套使用硬耍,建表時(shí)通過partitioned by 來創(chuàng)建分區(qū)

      • partitioned by (year string)

      • partitioned by (year string,month string)

    • 將分區(qū)加載到表內(nèi)之前,需要指定添加分區(qū)列边酒,否則報(bào)錯(cuò)经柴。

      • 此時(shí)聯(lián)系到動(dòng)分區(qū)的調(diào)整

      • 動(dòng)態(tài)分區(qū)需要:

        ①開啟動(dòng)態(tài)分區(qū)

          hive.exec.dynamic.partition=true
        

        ②設(shè)置為非嚴(yán)格模式

          hive.exec.dynamic.partition.mode=nonstrict
        
    • partitioned by 子句中的列是表中正式的列(分區(qū)列,通過select * 可查到)墩朦,但是表數(shù)據(jù)中并不包含這些列

10. 分桶

  • 分桶的理解

    • 桶為表提供了額外的結(jié)構(gòu)坯认,hive在處理某些查詢時(shí)利用這個(gè)結(jié)構(gòu),能提高查詢效率

    • 桶通過對指定列進(jìn)行哈希計(jì)算來實(shí)現(xiàn)的,通過對哈希值將一個(gè)列名下的數(shù)據(jù)切分為一組桶牛哺,并使每個(gè)桶對應(yīng)于該列名下的存儲(chǔ)文件

    • 建立桶之前陋气,需要設(shè)置hive.enforce.bucketing = true;

    • 分區(qū)和分桶其中一個(gè)區(qū)別在于

      • 分區(qū)中的指定列在表數(shù)據(jù)中不存在,即數(shù)據(jù)文件中不存在

      • 分桶中的指定列在表數(shù)據(jù)中存在

    • 向桶中插入數(shù)據(jù)引润,若分為4個(gè)桶巩趁,則在插入數(shù)據(jù)時(shí),對應(yīng)于4個(gè)reduce操作淳附,輸出4個(gè)文件

  • 分區(qū)中的分桶

    • 注意分區(qū)中分桶的數(shù)據(jù)插入

    • clustered by (id) sorted by (age) into 4 buckets

      • clustered by 和 sorted by 不會(huì)影響數(shù)據(jù)的導(dǎo)入议慰,插入的數(shù)據(jù)若需要排序,則需要手動(dòng)定義

11. left semi join

  • 概念

    • left semi join是對in/exists子查詢提供了更高效的方式

    • 下面兩個(gè)語句等價(jià)

        select 
            a.key,a.value
        from
            a
        where
            a.key in(
            select b.key from B);
      
        等價(jià)于
      
        select
            a.key,a.value
        from
            a
        left semi join b
        on (a.key = b.key)
      
    • The restrictions of using left semi join are that the right-side join table should only be referened in the join condition, but not in where or select clause etc.(left semi join中右邊的表只能在on 中被引用奴曙,不可在where别凹,select中等使用)

12. insert into 代替 union all

  • 不同表的union all相當(dāng)于multiple inputs,同一個(gè)表的union all洽糟,相當(dāng)map一次輸出多條炉菲。

  • 如果union all的部分個(gè)數(shù)大于2,或者每個(gè)union部分?jǐn)?shù)據(jù)量大坤溃,應(yīng)該拆成多個(gè)insert into 語句拍霜,實(shí)際測試過程中,執(zhí)行時(shí)間能提升50%

      insert overwite table tablename partition (dt= ....)    
      select ..... from ( select ... from A       
      union all       
      select ... from B  union all select ... from C ) R      
      where ...;
      
      可以改寫為:
      
      insert into table tablename partition (dt= ....) select .... from A WHERE ...;
      
      insert into table tablename partition (dt= ....) select .... from B  WHERE ...;
      
      insert into table tablename partition (dt= ....) select .... from C WHERE ...;
    

四浇雹、數(shù)據(jù)傾斜

概述

  • 數(shù)據(jù)傾斜表現(xiàn):

    • 任務(wù)進(jìn)度長時(shí)間維持在99%(或100%),查看任務(wù)監(jiān)控頁面屿讽,發(fā)現(xiàn)只有少量(1個(gè)或幾個(gè))reduce子任務(wù)未完成昭灵。因?yàn)槠涮幚淼臄?shù)據(jù)量和其他reduce差異過大。
  • 數(shù)據(jù)傾斜原因:

    • key分布不均勻

    • 業(yè)務(wù)數(shù)據(jù)本身的特性

    • 建表時(shí)考慮不周

    • 某些SQL語句本身就有數(shù)據(jù)傾斜

           關(guān)鍵詞                  情形                                          后果
            -----------------|----------------------------------------------|--------------------------------------------------
            join                其中一個(gè)表較小伐谈,但是key集中                     分發(fā)到某一個(gè)或幾個(gè)Reduce上的數(shù)據(jù)遠(yuǎn)高于平均值
            -----------------|----------------------------------------------|-------------------------------------------------
            join                大表與大表烂完,但是分桶的判斷字段0值或空值過多          這些空值都由一個(gè)reduce處理,非常慢
            -----------------|----------------------------------------------|------------------------------------------------
            group by            group by 維度過小诵棵,某值的數(shù)量過多                   處理某值的reduce非常耗時(shí)
            -----------------|----------------------------------------------|-------------------------------------------------
            count distinct      某特殊值過多                                      處理此特殊值reduce耗時(shí)
            -----------------|----------------------------------------------|-------------------------------------------------
      

1. 合理設(shè)置map數(shù)量

  • 概念

    • 通常情況下抠蚣,作業(yè)會(huì)通過 input 的目錄產(chǎn)生一個(gè)或者多個(gè) map 任務(wù)

      • 主要的決定因素有:input 的文件總個(gè)數(shù),input 的文件大小履澳,集群設(shè)置的文件塊大小嘶窄。

      • 涉及到split切片機(jī)制

        • size = Math.max(minSize,Math.min(maxSize,blockSize));
      • 如果集群性能好的話,可設(shè)置blockSize

      • 開啟map端的聚合

    • 也可以適當(dāng)調(diào)整環(huán)形緩沖區(qū)的大小以提高效率

2. 小文件進(jìn)行合并

  • 在 map 執(zhí)行前合并小文件距贷,減少 map 數(shù):

    • CombineHiveInputFormat 具有對小文件進(jìn)行合并的功能(系統(tǒng)默認(rèn)的格式)柄冲。

    • HiveInputFormat 沒有對小文件合并功能。

        set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
      

3. 復(fù)雜文件增加 Map 數(shù)

  • 當(dāng) input 的文件都很大忠蝗,任務(wù)邏輯復(fù)雜现横,map 執(zhí)行非常慢的時(shí)候,可以考慮增加 Map數(shù),來使得每個(gè) map 處理的數(shù)據(jù)量減少戒祠,從而提高任務(wù)的執(zhí)行效率骇两。

  • 增加 map 的方法為:根據(jù)

      computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M 公式
    
  • 調(diào)整 maxSize 最大值。讓 maxSize 最大值低于 blocksize 就可以增加 map 的個(gè)數(shù)姜盈。

4. 合理設(shè)置 Reduce 數(shù)

4.1 調(diào)整 reduce 個(gè)數(shù)方法一

  • 每個(gè) Reduce 處理的數(shù)據(jù)量默認(rèn)是 256MB

      hive.exec.reducers.bytes.per.reducer=256000000
    
  • 每個(gè)任務(wù)最大的 reduce 數(shù)低千,默認(rèn)為 1009

      hive.exec.reducers.max=1009
    
  • 計(jì)算 reducer 數(shù)的公式

      N=min(參數(shù) 2,總輸入數(shù)據(jù)量/參數(shù) 1)
    

4.2 調(diào)整 reduce 個(gè)數(shù)方法二

  • 在 hadoop 的 mapred-default.xml 文件中修改

      設(shè)置每個(gè) job 的 Reduce 個(gè)數(shù)
      set mapreduce.job.reduces = 15;
    
  • 具體的個(gè)數(shù)需要經(jīng)過測試來得知

五贩据、并行執(zhí)行

  • 概念

    • Hive 會(huì)將一個(gè)查詢轉(zhuǎn)化成一個(gè)或者多個(gè)階段栋操。這樣的階段可以是 MapReduce 階段、抽樣階段饱亮、合并階段矾芙、limit 階段〗希或者 Hive 執(zhí)行過程中可能需要的其他階段剔宪。

    • 默認(rèn)情況下,Hive 一次只會(huì)執(zhí)行一個(gè)階段壹无。

    • 不過葱绒,如果某些階段不是互相依賴,是可以并行執(zhí)行的斗锭。

  • 參數(shù)設(shè)置

      set hive.exec.parallel=true; //打開任務(wù)并行執(zhí)行
      set hive.exec.parallel.thread.number=16; //同一個(gè) sql 允許最大并行度地淀,默認(rèn)為 8。
    
  • 不過岖是,在共享集群中帮毁,需要注意下,如果 job 中并行階段增多豺撑,那么集群利用率就會(huì)增加烈疚。當(dāng)然,得是在系統(tǒng)資源比較空閑的時(shí)候才有優(yōu)勢聪轿,否則爷肝,沒資源,并行也起不來

六陆错、嚴(yán)格模式

開啟嚴(yán)格模式可以禁止 3 種類型的查詢灯抛。

1. 分區(qū)表——where過濾

  • 對于分區(qū)表,除非 where 語句中含有分區(qū)字段過濾條件來限制范圍音瓷,否則不允許執(zhí)行牧愁。

  • 就是用戶不允許掃描所有分區(qū)。進(jìn)行這個(gè)限制的原因是外莲,通常分區(qū)表都擁有非常大的數(shù)據(jù)集猪半,而且數(shù)據(jù)增加迅速兔朦。沒有進(jìn)行分區(qū)限制的查詢可能會(huì)消耗令人不可接受的巨大資源來處理這個(gè)表。

2. order by 搭配limit使用

  • 對于使用了 order by 語句的查詢磨确,要求必須使用 limit 語句沽甥。

  • 因?yàn)?order by 為了執(zhí)行排序過程會(huì)將所有的結(jié)果數(shù)據(jù)分發(fā)到同一個(gè) Reducer 中進(jìn)行處理,強(qiáng)制要求用戶增加這個(gè) LIMIT語句可以防止 Reducer 額外執(zhí)行很長一段時(shí)間乏奥。

3. 限制笛卡爾積的查詢摆舟。

  • 多表join時(shí),指定join條件

七邓了、JVM重用(針對同一個(gè)job的tasks而言的)

  • 概念

    • JVM 重用是 Hadoop 調(diào)優(yōu)參數(shù)的內(nèi)容恨诱,其對 Hive 的性能具有非常大的影響,特別是對于很難避免小文件的場景或 task 特別多的場景骗炉,這類場景大多數(shù)執(zhí)行時(shí)間都很短照宝。

    • Hadoop中有個(gè)參數(shù)是mapred.job.reuse.jvm.num.tasks,默認(rèn)是1句葵,表示一個(gè)JVM上最多可以順序執(zhí)行的task數(shù)目(屬于同一個(gè)Job)是1厕鹃。也就是說一個(gè)task啟一個(gè)JVM。

    • 為每個(gè)task啟動(dòng)一個(gè)新的JVM將耗時(shí)1秒左右乍丈,對于運(yùn)行時(shí)間較長(比如1分鐘以上)的job影響不大剂碴,但如果都是時(shí)間很短的task,那么頻繁啟停JVM會(huì)有開銷轻专。

  • 參數(shù)設(shè)置

    • 如果我們想使用JVM重用技術(shù)來提高性能忆矛,那么可以將mapred.job.reuse.jvm.num.tasks設(shè)置成大于1的數(shù)。這表示屬于同一job的順序執(zhí)行的task可以共享一個(gè)JVM请垛,也就是說第二輪的map可以重用前一輪的JVM催训,而不是第一輪結(jié)束后關(guān)閉JVM,第二輪再啟動(dòng)新的JVM叼屠。

    • 那么最多一個(gè)JVM能順序執(zhí)行多少個(gè)task才關(guān)閉呢瞳腌?

      • 這個(gè)值就是mapred.job.reuse.jvm.num.tasks绞铃。如果設(shè)置成-1镜雨,那么只要是同一個(gè)job的task(無所謂多少個(gè)),都可以按順序在一個(gè)JVM上連續(xù)執(zhí)行
    • 如果task屬于不同的job儿捧,那么JVM重用機(jī)制無效荚坞,不同job的task需要不同的JVM來運(yùn)行

  • 注意事項(xiàng)

    • JVM重用技術(shù)不是指同一Job的兩個(gè)或兩個(gè)以上的task可以同時(shí)運(yùn)行于同一JVM上,而是排隊(duì)按順序執(zhí)行菲盾。

    • 一個(gè)tasktracker最多可以同時(shí)運(yùn)行的task數(shù)目由mapred.tasktracker.map.tasks.maximum和mapred.tasktracker.reduce.tasks.maximum決定颓影,并且這兩個(gè)參數(shù)在mapred-site.xml中設(shè)置。

    • 其他方法懒鉴,如在JobClient端通過命令行-Dmapred.tasktracker.map.tasks.maximum=number或者conf.set("mapred.tasktracker.map.tasks.maximum","number")設(shè)置都是無效的诡挂。

    • 這個(gè)功能的缺點(diǎn)是碎浇,開啟 JVM 重用將一直占用使用到的 task 插槽,以便進(jìn)行重用璃俗,直到任務(wù)完成后才能釋放奴璃。如果某個(gè)“不平衡的”job 中有某幾個(gè) reduce task 執(zhí)行的時(shí)間要比其他 Reduce task 消耗的時(shí)間多的多的話,那么保留的插槽就會(huì)一直空閑著卻無法被其他的 job使用城豁,直到所有的 task 都結(jié)束了才會(huì)釋放苟穆。

八、推測執(zhí)行

  • 概念

    • 在分布式集群環(huán)境下唱星,因?yàn)槌绦?Bug(包括 Hadoop 本身的 bug)雳旅,負(fù)載不均衡或者資源分布不均等原因,會(huì)造成同一個(gè)作業(yè)的多個(gè)任務(wù)之間運(yùn)行速度不一致间聊,有些任務(wù)的運(yùn)行速度可能明顯慢于其他任務(wù)(比如一個(gè)作業(yè)的某個(gè)任務(wù)進(jìn)度只有 50%攒盈,而其他所有任務(wù)已經(jīng)運(yùn)行完畢),則這些任務(wù)會(huì)拖慢作業(yè)的整體執(zhí)行進(jìn)度甸饱。

    • 為了避免這種情況發(fā)生沦童,Hadoop 采用了推測執(zhí)行(Speculative Execution)機(jī)制,它根據(jù)一定的法則推測出“拖后腿”的任務(wù)叹话,并為這樣的任務(wù)啟動(dòng)一個(gè)備份任務(wù)偷遗,讓該任務(wù)與原始任務(wù)同時(shí)處理同一份數(shù)據(jù),并最終選用最先成功運(yùn)行完成任務(wù)的計(jì)算結(jié)果作為最終結(jié)果驼壶。

  • 參數(shù)設(shè)置

      <property>
           <name>mapreduce.map.speculative</name>
           <value>true</value>
           <description>If true, then multiple instances of some map tasks may be executed in parallel.</description>
      </property>
      
      <property>
           <name>mapreduce.reduce.speculative</name>
           <value>true</value>
           <description>If true, then multiple instances of some reduce tasks  may be executed in parallel.</description>
      </property>
    
      <property>
           <name>hive.mapred.reduce.tasks.speculative.execution</name>
           <value>true</value>
           <description>Whether speculative execution for reducers should be turned on.</description>
       </property>
    
  • 注意事項(xiàng)

    • 如果用戶因?yàn)檩斎霐?shù)據(jù)量很大而需要執(zhí)行長時(shí)間的 map 或者 Reduce task 的話氏豌,那么啟動(dòng)推測執(zhí)行造成的浪費(fèi)是非常巨大大。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末热凹,一起剝皮案震驚了整個(gè)濱河市泵喘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌般妙,老刑警劉巖纪铺,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碟渺,居然都是意外死亡鲜锚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門苫拍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芜繁,“玉大人,你說我怎么就攤上這事绒极】チ睿” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵垄提,是天一觀的道長榔袋。 經(jīng)常有香客問我周拐,道長,這世上最難降的妖魔是什么凰兑? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任速妖,我火速辦了婚禮,結(jié)果婚禮上聪黎,老公的妹妹穿的比我還像新娘罕容。我一直安慰自己,他們只是感情好稿饰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布锦秒。 她就那樣靜靜地躺著,像睡著了一般喉镰。 火紅的嫁衣襯著肌膚如雪旅择。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天侣姆,我揣著相機(jī)與錄音生真,去河邊找鬼。 笑死捺宗,一個(gè)胖子當(dāng)著我的面吹牛柱蟀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚜厉,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼长已,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了昼牛?” 一聲冷哼從身側(cè)響起术瓮,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贰健,沒想到半個(gè)月后胞四,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伶椿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年辜伟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悬垃。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡游昼,死狀恐怖甘苍,靈堂內(nèi)的尸體忽然破棺而出尝蠕,到底是詐尸還是另有隱情,我是刑警寧澤载庭,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布看彼,位于F島的核電站廊佩,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏靖榕。R本人自食惡果不足惜标锄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茁计。 院中可真熱鬧料皇,春花似錦、人聲如沸星压。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娜膘。三九已至逊脯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竣贪,已是汗流浹背军洼。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留演怎,地道東北人匕争。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像爷耀,于是被迫代替她去往敵國和親汗捡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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