hive中數據傾斜

數據傾斜通常指hive根據key值hash分發到各個節點,相同的key值會分發到一個執行節點中,由於某些key值對應的數據量比其它key值的數據量大很多,導致某些執行節點的運行時間遠大於其它節點,從而導致整個job執行時間較長。
在hive中執行的sql會有map和reduce兩個階段,map階段的數據傾斜主要爲數據從磁盤讀入內存時、join,reduce階段數據傾斜主要有join、group by、count distinct,針對於這些操作有不同的處理方式來避免數據傾斜。
一、map階段
1.由於map讀入數據的文件大小分佈不均勻,並且小文件特別多,導致某些map讀取並處理的數據特別多
這種情況可通過參數調整防止由於小文件過多導致每個map讀取的數據量不均勻,mapred.max.split.size=256000000(每個map可以處理的最大文件大小,可調大該值來減少map數)
二、reduce階段
1.join
數據表在進行join時有兩種情況會出現傾斜:
(1)小表和大表join的傾斜
這種情況,可以直接使用hint(如/ + mapjoin(a) /)將小表全部加載到內存中後順序掃描大表完成join(mapjoin有使用限制,必須是join中的從表較小時纔可用,從表主要指left join中的右表,right join中的左表,小表最大爲2GB)
(2)大表和大表join的傾斜
這種情況,需要具體原因具體分析:

  • 由某些特殊值引起的數據傾斜
    參數設置方式:hive.optimize.skewjoin=true; 將造成傾斜的特殊值先不處理直接寫入hdfs,然後新啓一個mapjoin專門處理特殊值;可以通過參數設置數據量超過多少默認爲特殊值,如hive.skewjoin.key=10000,表名超過10000條的key會被認定爲特殊值;
    特殊值的處理也可以在sql中進行優化,在sql中將特殊值與非特殊值分別處理,然後再通過union all拼接,但這樣會增加IO;
  • 由空值引起的數據傾斜
    將空值的key變爲一個字符串加上隨機數,也可以借鑑特殊值的sql優化方式;
  • 不同數據類型關聯產生的數據傾斜
    如int型的用戶id與string類型的用戶id進行關聯,hive默認會將hash按int類型分配,string類型的數據會全部分配到一個reduce中,此時應將int型轉化爲string再做關聯
    2.group by + count distinct
    當sql中出現這種情況時,需預先對group by的字段進行去重處理,然後再進行count
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章