資料傾斜問題産生
在hive中, 執行一條SQL語句, 最終會翻譯為MR, MR中mapTask和reduceTask都可能存在多個, 資料傾斜主要指的是整個MR中reduce階段有多個reduce , 每個reduce拿到的資料的條數并不均衡, 導緻某一個或者某幾個拿到了比其他的reduce更多的資料, 到底處理資料壓力集中在某幾個reduce上, 形成資料傾斜問題。
join資料傾斜的處理
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLiJmMzkjY2ImYidzNwITM4IDNmRzY0cTYhBTYyMjN0kzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
出現傾斜的根本原因:
在reduce中,某一個, 或者某幾個的分組k2對應value的資料比較多, 進而引起資料傾斜問題
-
解決方案一:
可以通過 map join, bucket map join 以及 SMB Map join 解決
注意:
通過map join來解決資料傾斜, 但是map join使用是存在條件的, 如果無法滿足這些條件, 無法使用map join
-
解決方案二:
思路: 将那些産生傾斜的k2和對應value資料, 從目前這個MR移植出去, 單獨找一個MR來處理即可, 處理後, 和之前MR的彙總結果即可
關鍵問題: 如何找出那些存在傾斜的k2資料
---------運作期處理方案--------------
思路: 在執行MR的時候, 會動态統計每一個k2的值出現的重複的數量, 當這個重複的數量達到一定門檻值後, 認為目前這個k2的資料存在資料傾斜, 自動将其剔除, 交由給一個單獨的MR來處理即可, 兩個MR處理完成後, 将結果, 基于union all 合并在一起即可
實操 :
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=100000; – 此參考在實際生産環境中, 需要進行調整在合理的值
适用于: 并不清楚那個key容易産生傾斜, 此時可以交由系統來動态檢測
---------編譯期處理方案--------------
思路: 在建立這個表的時候,我們就可以預知到後續插入到這個表中, 那些key的值會産生傾斜, 在建表的時候, 将其提前配置設定好即可, 在後續運作的時候, 程式會自動将設定的k2的值資料單獨找一個MR來進行單獨的處理操作, 處理後, 再和原有MR進行union all的合并操作
實操: set hive.optimize.skewjoin.compiletime=true; 建表 CREATE TABLE list_bucket_single (key STRING, value STRING) -- 傾斜的字段和需要拆分的key值 SKEWED BY (key) ON (1,5,6) -- 為傾斜值建立子目錄單獨存放 [STORED AS DIRECTORIES];
在實際生産環境中, 應該使用那種方式呢? 兩種方式都會使用的
一般來說, 會将兩個都開啟, 編譯期的明确在編譯期将其設定好, 編譯期不清楚, 通過 運作期動态捕獲即可
-
union all優化方案
說明: 不管是運作期, 還是編譯期的join傾斜解決, 最終都會運作多個MR , 最終将多個MR的結果, 通過union all進行彙總, union all也是單獨需要一個MR來運作的
解決方案:
讓每一個MR在運作完成後, 直接将結果輸出到目的地即可, 預設是輸出到臨時檔案目錄下, 通過union all合并到最終目的地
set hive.optimize.union.remove=true;