Greenplum 調優--數據分布法則 - 分布列與分區的選擇


分布列選擇黃金法則

由於Greenplum是一個分布式的數據庫,數據是分散存儲在各個數據節點的,所以需要告訴Greenplum數據應該如何分布。

短板效應

當用戶請求QUERY時,Greenplum會在所有的節點並行執行,所以最慢的節點會成為整個系統的瓶頸。

Greenplum 支持的分布算法 :

用戶可以指定 分布列(允許指定多個列) ,或者使用 隨機分布 算法。

那么用戶應該如何選擇分布列,或者是否要使用隨機分布算法呢?

總結起來,需要考慮以下幾點

  • JOIN

    當JOIN的列都是分布列時,不需要重分布或廣播小表,可以在segment內完成JOIN。

 

兩個表在JOIN時,如果JOIN列不是表的分布列,那么其中一個更小的表會發生數據重分布,或者broadcast,以繼續完成JOIN的動作。

例如a和b都是隨機分布的,在JOIN時,要么廣播小表,要么兩個表都根據JOIN 列重分布。

 

例如a和b,其中a是JOIN列分布,b不是,那么b可以選擇廣播,或者重分布。

 

重分布或廣播的動作都是自動完成的,但是這樣一定會帶來額外的網絡開銷。

想象一下,如果你的QUERY並發很高,而且大量的QUERY中涉及到JOIN的數據重分布或broadcast的話,網絡很快就會成為瓶頸。

法則1,分布列盡量選擇需要經常JOIN的列,這類查詢的並發越高,越應該考慮。

  • 防止數據傾斜

    Greenplum依據指定的分布列,hash取模存放到對應的segment中。

    如果選擇的分布列值分布不均勻,就可能導致數據傾斜,某些segment可能非常大,而某些segment非常小。

    數據傾斜的顯著危害,1. 空間不均勻,不好規划存儲。2. 數據分布過多的節點,容易成為整個系統的短板。

    法則2,盡量選擇分布均勻的列,或者多列

  • 高並發查詢,選擇性好

    如果數據經常被高並發的鍵值或離散查詢,建議將查詢條件的列作為分布列,這樣不需要連接到所有的segment去查,可以大大提高並發能力。

    例子

    aa01 的分布列是aaz499

    查詢分布列時,定位到一個segment查詢

postgres=# explain analyze select * from aa01 where aaz499=1;  
                                    QUERY PLAN                                      
----------------------------------------------------------------------------------  
 Gather Motion 1:1  (slice1; segments: 1)  (cost=0.00..120.00 rows=1 width=1973)  
   Rows out:  0 rows at destination with 1.352 ms to end, start offset by 144 ms.  
   ->  Seq Scan on aa01  (cost=0.00..120.00 rows=1 width=1973)  
         Filter: aaz499 = 1  
         Rows out:  0 rows with 0.031 ms to end, start offset by 145 ms.  
 Slice statistics:  
   (slice0)    Executor memory: 330K bytes.  
   (slice1)    Executor memory: 176K bytes (seg10).  
 Statement statistics:  
   Memory used: 128000K bytes  
 Optimizer status: legacy query optimizer  
 Total runtime: 145.822 ms  
(12 rows)  

查詢非分布列,需要所有的segment參與查詢

postgres=# explain analyze select * from aa01 where cae007='t';  
                                     QUERY PLAN                                       
------------------------------------------------------------------------------------  
 Gather Motion 16:1  (slice1; segments: 16)  (cost=0.00..120.00 rows=2 width=1973)  
   Rows out:  0 rows at destination with 2.001 ms to end, start offset by 146 ms.  
   ->  Seq Scan on aa01  (cost=0.00..120.00 rows=1 width=1973)  
         Filter: cae007::text = 't'::text  
         Rows out:  0 rows (seg0) with 0.047 ms to end, start offset by 147 ms.  
 Slice statistics:  
   (slice0)    Executor memory: 330K bytes.  
   (slice1)    Executor memory: 176K bytes avg x 16 workers, 176K bytes max (seg0).  
 Statement statistics:  
   Memory used: 128000K bytes  
 Optimizer status: legacy query optimizer  
 Total runtime: 147.813 ms  
(12 rows)  

法則3,盡量選擇高並發查詢的條件列(指該查詢條件產生的中間結果集小的,如果中間結果集很大,那就讓所有節點都來參與運算更好,因此不選),如果有多個條件,請先權衡前面的法則

法則4,不要輕易使用隨機分布

分區黃金法則

目前Greenplum支持LIST和RANGE兩種分區類型。

分區的目的是盡可能的縮小QUERY需要掃描的數據量,因此必須和查詢條件相關聯。

法則1,盡量選擇和查詢條件相關的字段,縮小QUERY需要掃描的數據

法則2,當有多個查詢條件時,可以使用子分區,進一步縮小需要掃描的數據

例子,一個用戶發起了帶兩個查詢條件col1=xx and col2 between ?1 and ?2 的請求,通過分區,如果表已經根據col1進行了LIST分區,同時根據col2進行了range的分區,那么查詢范圍可以大大的縮小。

screenshot

小結

  • 分布列選擇法則

    原則,避免短板效應。

    法則1,分布列盡量選擇需要經常JOIN的列,這類查詢的並發越高,越應該考慮。

    法則2,盡量選擇分布均勻的列,或者多列

    法則3,盡量選擇高並發查詢的條件列(指該查詢條件產生的中間結果集小的,如果中間結果集很大,那就讓所有節點都來參與運算更好,因此不選),如果有多個條件,請先權衡前面的法則

    法則4,不要輕易使用隨機分布

  • 分區法則

    原則,縮小查詢范圍。

    法則1,盡量選擇和查詢條件相關的字段,縮小QUERY需要掃描的數據

    法則2,當有多個查詢條件時,可以使用子分區,進一步縮小需要掃描的數據

轉載自:

https://github.com/zuozi2810/blog/blob/master/201607/20160719_02.md


免責聲明!

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



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