背景
數據處理平台從oracle遷移到hadoop平台后,原有的數據處理過程需要改寫為sparkSql。由於sparkSql執行環境和數據的不確定,經常有資源競爭導致處理過程意外停止,數據傾斜導致任務執行失敗。 為減少出錯概率,需要對sparkSql進行規范與優化。
轉換
- exist 轉換 為 left sime join,left sime join不會因為右表有重復而數據增加。
- from table1, table2,table3 轉為 inner join ,使用join 會更清晰的分辨表連接是否充分,以免笛卡爾積引起集群資源浪費。
- decode()轉為 case when
- 在使用union all 時 ,sql編譯出錯, 需要指定數據類型如: cast(abe001 as double)
- 分清count(columnName)count(*)count(1)意義 ,count(columnName)不包含空,可以使用sum(case when columnName is null else 0 else 1 end )替換count
- oracle form前的子查詢必須放在join 之后
- 時間格式請使用"yyyy-MM-dd HH:mm:ss",YYYY表示當天所在的周的年份可能結果不是想要的,hh是12小時制,在對時間做計算是會出錯。
- 在對字符串的數字做比較是請轉為 int或 double型,如果數據中與非數字字符或導致按字符串的方式比較大小。
- sql對 大的整數 進行字符處理時,注意可以會被轉成科學計數法。
- 在對字符或時間做處理時,請先使用select 查看處理結果,以免出現不想要的結果。
數據傾斜
數據傾斜報錯
通常數據傾斜有以下幾種現象:
- java.util.concurrent.TimeoutException: Futures timed out after [300 seconds]
- spark監控有一個或幾個task始終執行不完
- 有execute 報 內存溢出
- 表連接不足,產生笛卡爾積
優化SQl點
1.檢查group by 字段是否全為一個值或空, 從group中移除只用一個值得字段
2. sql使用大表反復關聯小表如:
) a
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'AAC004') c
on a.AAC004 = c.aaa102
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'AAC011') d
on a.aac011 = d.aaa102
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'YAB019') e
on a.yab019 = e.aaa102
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'AAB019') f
on a.aab019 = f.aaa102
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'YAB003') g
on a.aab301 = g.aaa102
left join (select m.aaa102,m.aaa103 from database.aa11 m where m.aaa100 = 'AAB301') h
on a.yac145 = h.aaa102
默認小於150M的表會廣播(broacast),如上處理后將不能被廣播, 修改為:
) a
left join database.aa11 c
on a.AAC004 = c.aaa102 and c.aaa100 = 'AAC004'
left join database.aa11 d
on a.aac011 = d.aaa102 and d.aaa100 = 'AAC011'
left join database.aa11 e
on a.yab019 = e.aaa102 and e.aaa100 = 'YAB019'
left join database.aa11 f
on a.aab019 = f.aaa102 and f.aaa100 = 'AAB019'
left join database.aa11 g
on a.aab301 = g.aaa102 and g.aaa100 = 'YAB003'
left join database.aa11 h
on a.yac145 = h.aaa102 and h.aaa100 = 'AAB301'
- 復雜的Or條件語句 最好拆分成 union
- 使用 join 單表連接 排查連接條件