分布式DB(Greenplum)中數據傾斜的原因和解法


背景

    對於分布式數據庫來說,QUERY的運行效率取決於最慢的那個節點。


    當數據出現傾斜時,某些節點的運算量可能比其他節點大。除了帶來運行慢的問題,還有其他的問題,例如導致OOM,或者DISK FULL等問題。

如何監控傾斜

1、 監控數據庫級別傾斜

640.webp

2、 監控表級傾斜


出現數據傾斜的原因和解決辦法

1、分布鍵選擇不正確,導致數據存儲分布不均。 

例如選擇的字段某些值特別多,由於數據是按分布鍵VALUE的HASH進行分布的,導致這些值所在的SEGMENT的數據可能比而其他SEGMENT多很多。 

分布鍵的選擇詳見:

《Greenplum 最佳實踐 - 數據分布黃金法則 - 分布列與分區的選擇》

2、查詢導致的數據重分布,數據重分布后,數據不均。

例如group by的字段不是分布鍵,那么運算時就需要重分布數據。

解決辦法1:

由於查詢帶來的數據傾斜的可能性非常大,所以Greenplum在內核層面做了優化,做法是:

先在segment本地聚合產生少量記錄,將聚合結果再次重分布,重分布后再次在segment聚合,最后將結果發到master節點,有必要的話在master節點調用聚合函數的final func(已經是很少的記錄數和運算量)。

例子:

tbl_ao_col表是c1的分布鍵,但是我們group by使用了c398字段,因此看看它是怎么做的呢?請看執行計划的解釋。


對於非分布鍵的分組聚合請求,Greenplum采用了多階段聚合如下:

第一階段,在SEGMENT本地聚合。(需要掃描所有數據,這里不同存儲,前面的列和后面的列的差別就體現出來了,行存儲的deform開銷,在對后面的列進行統計時性能影響很明顯。)

第二階段,根據分組字段,將結果數據重分布。(重分布需要用到的字段,此時結果很小。)

第三階段,再次在SEGMENT本地聚合。(需要對重分布后的數據進行聚合。)

第四階段,返回結果給master,有必要的話master節點調用聚合函數的final func(已經是很少的記錄數和運算量)。

3、內核只能解決一部分查詢引入的數據重分布傾斜問題,還有一部分問題內核沒法解決。例如窗口查詢。


使用窗口函數時,Greenplum需要先按窗口中的分組對數據進行重分布,這一次重分布就可能導致嚴重的傾斜。

實際上內核層優化才是最好的解決辦法,例如以上窗口函數,由於我們只需要取c2分組中c3最小的一條記錄。因此也可以在每個節點先取得一條,再重分布,再算。

不通過修改內核,還有什么方法呢?

3.1 Mapreduce任務就很好解決,Greenplum的mapreduce接口調用方法如下:

http://greenplum.org/docs/ref_guide/yaml_spec.html

3.2 通過寫PL函數也能解決。例如


小結

數據傾斜的原因可能是數據存儲的傾斜,QUERY執行過程中數據重分布的傾斜。

數據傾斜可能引入以下后果:

1、計算短板

2、oom

3、disk full

數據傾斜的解決辦法:

1、如果是存儲的傾斜,通過調整更加均勻的分布鍵來解決。(也可以選擇使用隨機分布,或者使用多列作為分布鍵)。

2、如果是QUERY造成的傾斜,Greenplum內核對group by已經做了優化,即使分組字段不是分布鍵,通過多階段聚合,可以消除影響。

3、如果是窗口函數QUERY造成的傾斜,目前內核沒有對這部分優化,首先會對窗口函數的分組字段所有數據進行重分布,如果這個分組字段數據有嚴重傾斜,那么會造成重分布后的某些節點數據量過大。解決辦法有mapreduce或pl函數。

參考

《Greenplum 內存與負載管理最佳實踐》

《Greenplum 最佳實踐 - 數據分布黃金法則 - 分布列與分區的選擇》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM