解決:MapReduce資料傾斜問題
問題背景
技術最近在做資料溯源重構優化,計劃使用業務方的資料跑資料任務,以解決資料質量問題。
過程中,碰到這樣一個case:某資料需要join n張Hive表提資料,其中有這樣一個業務邏輯要關聯出mmm文章的mmm賬號資訊,文章表記錄數xxx億+,賬號表yyy萬+,這種資料關係導致在跑MR任務時資料傾斜,某個reduce要處理大部分資料,任務跑了20多個小時沒有完成
問題原因
-
Hive多表join時,每個join會生成一個MR任務,並以join on條件作為reduce的hash_key
-
由於業務上不是所有的文章都是pgc發文,文章表裡就會有大量mmm賬號外來鍵值為空的資料,約zz億+
-
就是說zz億+的資料只能被一個reduce處理,進而導致任務不能按預期完成
解決方案
引入隨機ID解決資料傾斜:文章表在join賬號表時做判斷,如果賬號外來鍵為空,生成隨機ID保證hash_key均勻分佈
最佳實踐
在問題排查過程中除了通過隨機數解決hash_key分佈不均的問題,還有幾個優化點:
1. 只查任務相關的資料
a.只查詢用到的欄位
b.過濾掉任務無關的資料
2. 按資料儲存從小到大的順序關聯從表
a.內容詳情表xxxT
b.最原始一版HQL是先join了內容詳情表,任務執行時間也特別長(並且任務執行過程中從一開始就佔用較大的儲存資源)
c.調整表關聯順序,最後join內容詳情表,任務執行符合預期
3. 關於語句巢狀,很早之前寫HQL當時有一個規範,關聯多個從表時一定要通過巢狀子查詢的方式,在同一層級只join一張表(具體原因暫不詳!!!)
上面提到的2個優化點的本質跟MR實現機制相關:MR過程中M的結果只有落盤後,才能被後續環節獲取到。這就很好解釋了:寬表由n張表的資料join出來,從MR的過程看會生成4個job,如果第一個job就關聯使用了xxxT的資料,那麼後面3個job也要處理xxxT+的資料(網路、磁碟IO、shuffle都很耗時)