第一節:簡介
一、數據傾斜
數據傾斜:由於數據分布不均勻,造成數據大量的集中到一點,造成數據熱點。
大數據中不怕數據量大,怕數據傾斜。
hive的數據傾斜 --- mapreduce的數據傾斜。
二、主要表現形式
hive運行日志中
map 100% reduce 97%
map 100% reduce 97%
map 100% reduce 97%
map 100% reduce 97%
。。。。。。。
第二節:hive中不易數據傾斜場景
一、 不執行mapreduce
1、簡介
hql語句---不執行mapreduce的
hive.fetch.task.conversion 決定的哪些語句不用執行mapreduce任務而是執行fetch的任務即數據抓取。
2、none
此屬性禁用,所有的hql語句都要執行mr任務
3、minimal
在版本0.10.0 through 0.13.1時默認使用
select*, filter on partition columns (where and having clauses),limit only
select *,where過濾分區字段的時候,limit 直接執行fetch的,不執行mr任務的。
以上三種情況不用執行mapreduce
4、more
Select,filter, limit only (including tablesample, virtual columns)
select 表中的任意沒有加工的原始字段
where 過濾
limit
以上三種情況不用執行mapreduce。
group by、join、order by、distinct等肯定走mapreduce的。
二、group by和聚合函數
max|min|sum + group by
默認在map端執行combiner在map端先執行一次聚合(combiner),reduce端接受的數據量少,不容易產生數據傾斜的。
三、mapjoin
在mapjoin的時候,有多個的maptask,不走reducetask,所以不會造成數據傾斜。
第三節:hive中容易數據傾斜場景
一、join
reducejoin的時候,如果里面的字段有一個是特別的多的話,會產生數據傾斜的問題。
二、group by
group by不和聚合函數一起使用的時候
三、count(distinct)
慎重使用,極易產生數據傾斜。
最終只會啟動一個reducetask,無論手動設置幾個reducetask任務,最終只運行一個。
優化:
把 count和distinct的需求分開
先求distinct
select distinct userId from weibo;
再求count
select count(*) from (select distinct userId from weibo)a;
最終轉換為2個mapreduce任務。
四、注意
在hive中如果一個hql語句需要轉換為多個job,下一個job需要依賴上一個job的,上一個job的結果不落磁盤,直接發送給下一個job,下一個job的maptask的個數由上一個job的輸出的reducetask的個數決定的。
第四節:經典場景
一、關聯鍵存在大量null值
1、簡介
在join(大*大)的情況下

2、解決方案
(1)將null值刪除

(2)需要null值


二、關聯建類型不統一
1、簡介
在join(大*大)情況下
用戶表中 user_id 字段為 int,log 表中 user_id 為 string類型,當按照兩個表的 user_id 進行 join 操作的時候,默認的 hash 操作會按照 int 類型的 id 進行分配,這樣就會導致所有的 string 類型的 id 就被分到同一個 reducer 當中。
因為此時的分區算法是:分區字段.hash%分區個數,所以不能識別string類型的,因此他們會被分配到同一個的reducetask。
2、解決方案
cast(原始數據 as 需要轉換的類型)
cast(age as bigint)
利用類型轉換函數。
三、reducejoin可能產生數據傾斜
1、小*小、大*小
不會產生數據傾斜的。
默認執行的mapjoin
小表限制:
set hive.auto.convert.join=true;
//設置 MapJoin 優化自動開啟
set hive.mapjoin.smalltable.filesize=25000000 25M
//設置小表的大小
關聯的時候,較小表小於等於25000000byte的時候,默認執行mapjoin。
2、大*中

3、大*大

