都是HIVE資料傾斜惹的禍

2021-07-24 11:03:07 字數 1525 閱讀 7893

症狀和原因:

我遇到的問題:

select * from a join b;

1. a表1000多萬,b表不到2億,用mapjoin顯然不行;

2. 設定引數 set 

hive.groupby.skewindata=true,不起作用;

3. 由於關連鍵為手機號,自認為業務資料上不存在資料傾斜;

後來通過檢視每個表裡面關聯鍵的分布,才發現兩個表裡面都存在空串'',而且嚴重傾斜,大表裡面的空串數量有400多萬。

將兩個表的空串過濾後再進行關聯,job時間由原來的40多分鐘減少到2分鐘。

總結:

1. 資料傾斜的原因就那麼幾種,逐一排查;

2. 細心,動手,不能光憑感覺來判定;

3. 判定某乙個表的key是否存在資料傾斜,就是group by key,取top n來看;

附:資料傾斜常用解決方法:

1. 萬能膏藥:hive.groupby.skewindata=true

2. 大小表關聯:將key相對分散,並且資料量小的表放在join的左邊,這樣可以有效減少記憶體溢位錯誤發生的機率;再進一步,可以使用map join讓小的維度表(1000條以下的記錄條數)先迚記憶體。在map端完成reduce.

3. 大表和大表關聯:把空值的key變成乙個字串加上隨機數,把傾斜的資料分到不同的reduce上,由於null值關聯不上,處理後並不影響最終結果。

4. count distinct大量相同特殊值:count distinct時,將值為空的情況單獨處理,如果是計算count distinct,可以不用處理,直接過濾,在最後結果中加1。如果還有其他計算,需要進行group by,可以先將值為空的記錄單獨處理,再和其他計算結果進行union。

當該字段存在大量值為null或空的記錄,容易發生資料傾斜;

解決思路:

count distinct時,將值為空的情況單獨處理, 如果是計算 count distinct ,可以不用處理,直接過濾,在最後結果中加1 ;

如果還有其他計算,需要進行group by,可以先將值為空的記錄單獨處理,再和其他計算結果進行union。

案例:select count(distinct  end_user_id) as user_num  from trackinfo;

調整為:

select cast(count(distinct end_user_id)+1 as bigint) as user_num  from trackinfo where  end_user_id is not null and end_user_id <> '';

分析:把為空的過濾掉,在總的count上加1

multi-count distinct

select pid, count(distinct acookie),count(distinct ip),count(wangwangid ip) from ods_p4ppv_ad_d where dt=20140305 group by pid;

必須設定引數:set hive.groupby.skewindata=true

都是 IDENTITY惹的禍

前不久系統伺服器出現了一次不大不小事故,資料庫乙個表的資料不翼而飛,這個表雖然算不上頂級重要的表,但也算的上是個很重要的表,大家趕緊查是什麼把這個表的資料刪的只剩下180多條資料.為什麼還有180多條資料存在哪?真是挺讓人納悶的,但發現這180多條資料中有乙個共性,那就是那個不該為空的字段變成了空值...

都是埠惹的禍

這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...

都是埠惹的禍

這幾天公司搬家,所以忙的blog好久都沒有更新,關鍵是沒有什麼技術上的事情,都不知道寫點什麼,呵呵。周四到週日一直在乙個客戶那邊進行產品的實施,整個過程自然比較有趣,對於我來說最重要的就是認識到了靈活程式設計的重要。我們的程式需要幾個通訊埠,其中乙個是1433用來連線sqlserver資料庫,很多的...