hiveSQL執行,轉化為MR過程


-- hive的庫、表等數據操作實際是hdfs系統中的目錄和文件,讓開發者可以通過sql語句, 像操作關系數據庫一樣操作文件內容。

一、hiveSQL轉化為MR過程
        一直好奇hiveSQL轉化為MR過程,好奇hive是如何做到這些的,所以在網上找了幾篇相關博客,根據自己理解重新畫了一份執行過程圖,做筆記。

 

 

 

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


2.原因:
    2.1、key分布不均勻。
    2.2、業務數據本身的原因。
    2.3、建表考慮不周。
    2.4、某些SQL本身就有數據傾斜。


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

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

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

    3.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.4、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.1、配置fetch抓取:修改配置文件hive.fetch.task.conversion為more,修改之后全局查找和字段查找以及limit都不會觸發MR任務。
    4.2、善用本地模式:大多數的Hadoop Job要求Hadoop提供完整的可擴展性來觸發大數據集,不過有時候hive的輸入數據量非常的小,這樣的情況下可能觸發任務的事件比執行的事件還長,我們就可以通過本地模式把小量的數據放到本地上面計算。
    4.3、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、動態分區調整:(慎用)
        4.5.1    開啟動態分區:hive.exec.dynamic.partition=true。
        4.5.2    設置為非嚴格模式:hive.exec.dynamic.partiton.mode = nostrict。
        4.5.3    實操:創建分區表、加載數據到分區表中、創建目標分區、設置動態分區、查看目標分區表的分區情況。
    4.6、小文件進行合並:在map執行之前合並小文件,減少map的數量,設置 set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat。
    4.7、調整map的數量和reduce的數量。
    4.8、並行執行:在Hive中可能有很多個階段,不一定是一個階段,這些階段並非相互依賴的。然后這些階段可以並行完成,設置並行:set hive.exec.parallel = true。
    4.9、JVM的重用,缺點是task槽會被占用,一直要等到任務完成才會釋放。

 

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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM