資料傾斜的產生和解決辦法?
產生資料傾斜的原因
唯一值非常少,極少數值有非常多的記錄值(唯一值少於幾千)
唯一值比較多,這個欄位的某些值有遠遠多於其他值的記錄數,但是它的佔比也小於百分之一或千分之一。
什麼是資料傾斜
資料傾斜無非就是大量的相同key被partition分配到一個分割槽裡,造成了’一個人累死,其他人閒死’的情況,這種情況是我們不能接受的,這也違背了平行計算的初衷,首先一個節點要承受著巨大的壓力,而其他節點計算完畢後要一直等待這個忙碌的節點,也拖累了整體的計算時間,可以說效率是十分低下的。
資料傾斜的解決辦法
增加jvm記憶體,這適用於第一種情況(唯一值非常少,極少數值有非常多的記錄值(唯一值少於幾千),這種情況下,往往只能通過硬體的手段來進行調優,增加jvm記憶體可以顯著的提高執行效率。
增加reduce的個數,這適用於第二種情況(唯一值比較多,這個欄位的某些值有遠遠多於其他值的記錄數,但是它的佔比也小於百分之一或千分之一),我們知道,這種情況下,最容易造成的結果就是大量相同key被partition到一個分割槽,從而一個reduce執行了大量的工作,而如果我們增加了reduce的個數,這種情況相對來說會減輕很多,畢竟計算的節點多了,就算工作量還是不均勻的,那也要小很多。
自定義分割槽,這需要使用者自己繼承partition類,指定分割槽策略,這種方式效果比較顯著。大資料培訓
重新設計key,有一種方案是在map階段時給key加上一個隨機數,有了隨機數的key就不會被大量的分配到同一節點(小几率),待到reduce後再把隨機數去掉即可。
使用combinner合併,combinner是在map階段,reduce之前的一箇中間階段,在這個階段可以選擇性的把大量的相同key資料先進行一個合併,可以看做是local reduce,然後再交給reduce來處理,這樣做的好處很多,即減輕了map端向reduce端傳送的資料量(減輕了網路頻寬),也減輕了map端和reduce端中間的shuffle階段的資料拉取數量(本地化磁碟IO速率),推薦使用這種方法。