hiveSQL執行,轉化爲MR過程

-- hive的庫、表等數據操做實際是hdfs系統中的目錄和文件,讓開發者能夠經過sql語句, 像操做關係數據庫同樣操做文件內容。sql

1、hiveSQL轉化爲MR過程
        一直好奇hiveSQL轉化爲MR過程,好奇hive是如何作到這些的,因此在網上找了幾篇相關博客,根據本身理解從新畫了一份執行過程圖,作筆記。數據庫

 

 

 

2、hive 執行過程當中數據傾斜問題
1.描述:
        數據傾斜主要表如今,MR程序執行過程當中,reduce節點大部分執行完畢,可是有一個或者少數幾個節點運行很慢,致使整個程序的處理時間很長。這是由於該reduce處理節點對應的key對應數據條數遠超於其餘key致使該節點處理數據量太大而不能和其餘節點同步完成執行。簡而言之,解釋同一key對應數據條數太多致使。常見有空值key。apache


2.緣由:
    2.一、key分佈不均勻。
    2.二、業務數據自己的緣由。
    2.三、建表考慮不周。
    2.四、某些SQL自己就有數據傾斜。負載均衡


3.解決方式:
    3.一、給key一個隨機值,打亂key,進行第一步操做,而後第二步去掉隨機值再處理。
    3.二、參數調節:
             hive.map.aggr = true Map 端部分聚合,至關於Combiner。
             hive.groupby.skewindata=true(萬能) 。有數據傾斜的時候進行負載均衡,當選項設定爲 true,生成的查詢計劃會有兩 個 MR Job。oop

   第一個 MR Job 中,Map 的輸出結果集合會隨機分佈到 Reduce 中,每一個 Reduce 作部分聚合操做,並輸出結果,這樣處理的結果是相同的 Group By Key 有可能被分發到不一樣的 Reduce 中,從而達到負載均衡的目的;fetch

   第二個MR Job 再根據預處理的數據結果按照 Group By Key 分佈到 Reduce 中(這個過程能夠保證相同的 Group By Key 被分 布到同一個 Reduce 中),最後完成最終的聚合操做。        大數據

    3.三、SQL語句調節:  
        3.3.1    大小表Join:使用map join讓小的維度表(1000條如下的記錄條數) 先進內存。在map端完成reduce.
        3.3.2    大表Join大表:把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不一樣的reduce上,因爲null值關聯不上,處理後並不影響最終結果。
        3.3.3    count distinct大量相同特殊值:count distinct時,將值爲空的狀況單獨處理,若是是計算count distinct,能夠不用處理,直接過濾,在最後結果中加1。若是還有其餘計算,須要進行group by,能夠先將值爲空的記錄單獨處理,再和其餘計算結果進行union。
        3.3.4    group by維度太小:採用sum() group by的方式來替換count(distinct)完成計算。
        3.3.5    特殊狀況特殊處理:在業務邏輯優化效果的不大狀況下,有些時候是能夠將傾斜的數據單獨拿出來處理。最後union回去。
    3.四、map和reduce優化。
      3.4.1    當出現小文件過多,須要合併小文件。能夠經過set hive.merge.mapfiles=true來解決。
           3.4.2    單個文件大小稍稍大於配置的block塊的大寫,此時須要適當增長map的個數。解決方法:set mapred.map.tasks個數
           3.4.3    文件大小適中,但map端計算量很是大,如select id,count(*),sum(case when...),sum(case when...)...須要增長map個數。解決方法:set mapred.map.tasks個數,set mapred.reduce.tasks個數優化

4.Hive的優化:
    4.一、配置fetch抓取:修改配置文件hive.fetch.task.conversion爲more,修改以後全局查找和字段查找以及limit都不會觸發MR任務。
    4.二、善用本地模式:大多數的Hadoop Job要求Hadoop提供完整的可擴展性來觸發大數據集,不過有時候hive的輸入數據量很是的小,這樣的狀況下可能觸發任務的事件比執行的事件還長,咱們就能夠經過本地模式把小量的數據放到本地上面計算。
    4.三、Group by:默認狀況下,map階段同一key的數據會發給一個reduce,當一個key數據過大就會傾斜,並非全部的聚合操做都須要reduce端完成,不少聚合操做均可以如今map端進行部分聚合,最後在reduce端得出最終結果。
        4.3.1    開啓在map端聚合:hive.map.aggr = true。
        4.3.2    在map端進行聚合操做的條目數:hive.groupby.mapaggr.checkinterval = 100000。
        4.3.3    有數據傾斜的時候進行負載均衡:hive.groupby.skewindata = true。
    4.四、行列過濾:列處理:只拿本身須要的列,若是有,儘可能使用分區過濾。行處理:在分區裁剪的時候,當使用外關聯的時候,先徹底關聯再過濾。
    4.五、動態分區調整:(慎用)
        4.5.1    開啓動態分區:hive.exec.dynamic.partition=true。
        4.5.2    設置爲非嚴格模式:hive.exec.dynamic.partiton.mode = nostrict。
        4.5.3    實操:建立分區表、加載數據到分區表中、建立目標分區、設置動態分區、查看目標分區表的分區狀況。
    4.六、小文件進行合併:在map執行以前合併小文件,減小map的數量,設置 set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。
    4.七、調整map的數量和reduce的數量。
    4.八、並行執行:在Hive中可能有不少個階段,不必定是一個階段,這些階段並不是相互依賴的。而後這些階段能夠並行完成,設置並行:set hive.exec.parallel = true。
    4.九、JVM的重用,缺點是task槽會被佔用,一直要等到任務完成纔會釋放。.net

 

轉載:https://blog.csdn.net/weixin_41408329/article/details/1061165433d

 

 

相關文章
相關標籤/搜索