Spark Skew Join Optimization

數據傾斜在分佈式計算中是一個很常見的問題,Spark提供了一種比較便捷的方法來處理一些簡單的數據傾斜場景。

Spark中定位數據傾斜

1、找到耗時長的stage並確定爲shuffle stage。
2、給所有的task按照shuffle records排序,找到最多數據的task。
3、比較其他的task確定是否發生了傾斜。
4、根據業務邏輯,Spark執行計劃,找到傾斜的key。

單表

skew hint必須至少包含一個表,所有和這個表有關的join都會自動使用傾斜join的優化策略。

-- orders表傾斜
SELECT /*+ SKEW('orders') */ * FROM orders, customers WHERE c_custId = o_custId

-- 臨時表傾斜
SELECT /*+ SKEW('C1') */ *
  FROM (SELECT * FROM customers WHERE c_custId < 100) C1, orders
  WHERE C1.c_custId = o_custId

表和字段

一個表可能會有多join,當其中的一個字段發生了傾斜時,由於自動傾斜優化策略有一定的額外開銷,所以最好是在需要的時候加上註解,而不處理所有的字段。爲此,該註解支持指定某張表的某個字段,這樣只有那個字段會被優化。

-- 單字段 orders的o_custId字段
SELECT /*+ SKEW('orders', 'o_custId') */ *
  FROM orders, customers
  WHERE o_custId = c_custId

-- 多字段 orders的o_custId和o_storeRegionId字段
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId')) */ *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId

表、字段以及傾斜值

有些場景,處理單個字段都會是非常耗時的,如果我們明確了join 的key在哪個值上傾斜了,我們也可以進一步的細化註解。這樣就能進一步的減少傾斜處理的額外開銷了。

-- 單個表的單個字段的單個傾斜值 orders的o_custId字段的0發生了傾斜
SELECT /*+ SKEW('orders', 'o_custId', 0) */ *
  FROM orders, customers
  WHERE o_custId = c_custId

-- 單個表的單個字段的多個傾斜值 orders的o_custId字段的(0, 1, 2)發生了傾斜
SELECT /*+ SKEW('orders', 'o_custId', (0, 1, 2)) */ *
  FROM orders, customers
  WHERE o_custId = c_custId

-- 單個表的多個字段的多個傾斜值 orders的o_custId字段的(0, 1001)以及o_storeRegionId字段的(1, 1002)發生了傾斜
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId'), ((0, 1001), (1, 1002))) */ *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId

據說,Delta Lake會自動得出傾斜的值,也不妨試試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章