三、Hive-sql優化,數據傾斜處理

1、Hive-sql優化

#增長reducer任務數量(拉取數量分流)
set mapred.reduce.tasks=20;

#在同一個sql中的不一樣的job是否能夠同時運行,默認爲false
set hive.exec.parallel=true;

#增長同一個sql容許並行任務的最大線程數
set hive.exec.parallel.thread.number=8;

#設置reducer內存大小
set mapreduce.reduce.memory.mb=4096;
set mapreduce.reduce.java.opts=-Xmx3584m; -- -Xmx 設置堆的最大空間大小。

#mapjoin相關設置,小表加載到內存,無reduce
set hive.mapjoin.smalltable.filesize=25000000; -- 刷入內存表的大小(字節)。注意:設置太大也不會校驗,因此要根據本身的數據集調整
set hive.auto.convert.join = true; -- 開啓mapjoin,默認false
set hive.mapjoin.followby.gby.localtask.max.memory.usage=0.6 ;--map join作group by操做時,可以使用多大的內存來存儲數據。若數據太大則不會保存在內存裏,默認0.55
set hive.mapjoin.localtask.max.memory.usage=0.90; -- 本地任務能夠使用內存的百分比,默認值:0.90
-- 在設置成false時,能夠手動的指定mapjoin /*+ MAPJOIN(c) */  。-->c:放到內存中的表
select /*+ MAPJOIN(c) */ * from user_install_status u
inner join country_dict c
on u.country=c.code
-- 若是不是作innerjoin, 作left join 、right join
-- A left join B, 把B放到內存
-- A right join B, 把A放到內存

#設置執行引擎
set hive.execution.engine=mr; -- 執行MapReduce任務,也能夠設置爲spark
-- 設置內存大小
set mapreduce.reduce.memory.mb=8192; -- reduce 設置的是 Container 的內存上限,這個參數由 NodeManager 讀取並進行控制,當 Container 的內存大小超過了這個參數值,NodeManager 會負責 kill 掉 Container
set mapreduce.reduce.java.opts=-Xmx6144m; -- reduce Java 程序能夠使用的最大堆內存數,要小於 mapreduce.reduce.memory.mb
set mapreduce.map.memory.mb=8192; -- map申請內存大小
set mapreduce.map.java.opts=-Xmx6144m;

#動態分區設置,參考:https://www.cnblogs.com/cssdongl/p/6831884.html
set hive.exec.dynamic.partition=true; 是開啓動態分區
set hive.exec.dynamic.partition.mode=nonstrict; 這個屬性默認值是strict,就是要求分區字段必須有一個是靜態的分區值,當前設置爲nonstrict,那麼能夠所有動態分區

#其餘
-- 開始負載均衡
set hive.groupby.skewindata=true
-- 開啓map端combiner
set hive.map.aggr=true

2、數據傾斜

2.一、數據傾斜的表現

  • 任務進度長時間維持在99%(或100%),查看任務監控頁面,發現只有少許(1個或幾個)reduce子任務未完成。由於其處理的數據量和其餘reduce差別過大。
  • 單一reduce的記錄數與平均記錄數差別過大,一般可能達到3倍甚至更多。 最長時長遠大於平均時長。

2.二、數據傾斜的解決方案

參數調節:css

  • 對於group by 產生傾斜的問題
    • 開啓map端combiner:【set hive.map.aggr=true;】
    • 開啓負載均衡:【set 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 中),最後完成最終的聚合操做。

SQL 語句調節:html

  • 大小表Join:
    • 使用map join讓小的維度表先進內存。在map端完成join,不通過reduce。
  • 大表Join大表:
    • 非法數據太多,好比null,能夠把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不一樣的reduce上,因爲null值關聯不上,處理後並不影響最終結果。
    • 若是null值不要,能夠經過where條件篩選掉;
    • 將大量的非法數據轉化成隨機數+字符串,這樣兩個表的數據不會join在一塊兒。
  • count distinct大量相同特殊值:
    • count distinct時,將值爲空的狀況單獨處理
    • 若是是計算count distinct,能夠不用處理,直接過濾,在最後結果中加1。
    • 若是還有其餘計算,須要進行group by,能夠先將值爲空的記錄單獨處理,再和其餘計算結果進行union。
    • 採用sum group by的方式來替換 count(distinct) 完成計算。
  • 特殊狀況特殊處理:
    • 在業務邏輯優化效果的不大狀況下,有些時候是能夠將傾斜的數據單獨拿出來處理。最後union回去
    • 好比:group by時維度太小,數據過於集中,數據自身傾斜,好比 北京的用戶比其它地方的用戶多不少
    • 此時能夠把北京的數據單獨處理:先把北京的數據分紅N塊,每塊的數據進行局部統計,再將每塊的局部統計結果進行彙總,最終統計出結果
相關文章
相關標籤/搜索