Greenplum 的分布式架構結構
1.基本架構
Greenplum(以下簡稱 GPDB)是一款典型的 Shared-Nothing 分散式資料庫系統。GPDB 擁有一個中控節點( Master )統籌整個系統,並在整個分布式架構下運行多個資料庫執行個體( Segment )。Master 是 GPDB 系統的訪問入口,其負責處理用戶端的串連及 SQL 命令、協調系統中的其他 Segment 工作,Segment 負責管理和處理使用者資料。而每個 Segment 實際上是由多個獨立的 PostgreSQL 執行個體組成,它們分布在不同的物理主機上,協同工作。
主節點與子節點
GPDB中,資料通過複雜的HASH 演算法或隨機拆分成無重疊的記錄集合,分布到所有 Segment 上。僅 Master 完成與使用者和用戶端程式的直接互動。因此但對於使用者來說,使用 GPDB 系統如同使用一個單機資料庫。
Master上儲存全域系統資料表(Global System Catalog ),但不儲存任何使用者資料,使用者資料只儲存在 Segment 上。Master 負責用戶端認證、處理 SQL 命令入口、在Segment 之間分配工作負、整合 Segment 處理結果、將最終結果呈現給用戶端程式。
使用者 Table 和相應的 Index 都分布在 GPDB 中各 Segment 上,每個 Segment 只儲存其中屬於本節點的那部分資料。使用者不能夠直接跳過 Master 訪問 Segment,而只能通過 Master 來訪問整個系統。在 GPDB 推薦的硬體設定環境下,每個有效 CPU 核對應一個 Segment ,比如一台物理主機配備了2個雙核的 CPU,那麼每個主機配置4個主執行個體( Segment Primary )。
網路連結
網路層組件( Interconnect )是 GPDB的重要組件。在使用者執行查詢時,每個 Segment 都需要執行相應的處理,因此物理主機間需要進行控制資訊和資料的高效傳遞。網路層的作用就是實現物理主機之間的通訊、資料傳遞,以及備份。在預設情況下,網路層使用 UDP 協議。GPDB 自己會為 UDP 協議做資料包校正,其可靠性與 TCP 協議一致,但其效能和擴充性遠好於TCP協議。
2.查詢執行機制
系統啟動後,使用者通過用戶端程式(例如 psql )串連到的 Master 主機並提交查詢語句。GP 會建立多個 DB 進程來處理查詢。在 Master 上的稱為執行分發器( Query Dispatcher/QD )。QD 負責建立、分發查詢計劃,匯總呈現最終結果。在 Segment 上,處理進程被稱為查詢執行器( Query executor/QE )。QE負責完成自身部分的處理工作以及與其他處理進程之間交換中間結果。
查詢計劃產生與派發
查詢被 Master 接收處理( QD身份)。QD 將查詢語句依據所定義的詞法和文法規則建立原始查詢文法樹。接著在查詢分析階段,QD 將原始文法樹轉換為查詢樹。然後進入查詢改寫階段,QD 將查詢樹依據系統中預先定義的規則對查詢樹進行轉換。QD 最終調用最佳化器接受改寫後的查詢樹,並依據該查詢樹完成查詢邏輯最佳化和物理最佳化。GPDB 是基於成本的最佳化策略:評估若干個執行計畫,找出最有效率的一個。但查詢最佳化工具必須全域的考慮整個叢集,在每個候選的執行計畫中考慮到節點間移動資料的開銷。至此 QD 建立一個並行的或者定向的查詢計劃(根據查詢語句決定)。之後Master將查詢計劃分發到相關的 Segment 去執行,每個 Segment 只負責處理自己本地的那部分資料操作。大部分的操作—比如掃表、關聯、彙總、排序都是同時在 Segment 上並行被執行。每個具體部分都獨立於其他 Segment 執行(一旦執行計畫確定,比如有 join,派發後 join 是在各個節點分別進行的,本機只和原生資料 join )。
查詢執行
由於 GPDB 採用 Shared-Nothing 架構,為了最大限度的實現並行化處理,當節點間需要移動資料時,查詢計劃將被分割,最終一個查詢會分為多個切片( slice ),每個切片都涉及不同處理工作。即:先執行一步分操作,然後執行資料移動,再執行下一步分操作。在查詢執行期間,每個 Segment 會根據查詢計劃上 slice 的劃分,建立多個 postgres 背景工作處理序,並行的執行查詢。每個 slice 對應的進程只處理屬於自己部分的工作,且這些處理工作僅在本 Segment 上執行。slice 之間為樹形結構,其整體構成整個查詢計劃。不同 Segment 之間對應的查詢計劃上的同一個 slice 處理工作稱為一個簇( gang )。在當前 gang 上的工作完成後,資料將向上傳遞,直到查詢計劃完成。Segment之間的通訊涉及到 GPDB 的網路層組件( Interconnect )。
QE 為每個 slice 開啟獨立進程,在該進程內執行多個操作。每一步代表著特定的 DB 操作,比如:掃表、關聯、彙總、排序等。Segment 上單個 slice 對應進程的執行運算元從上向下調用,資料從下向上傳遞。
與典型的 DB 操作不同的是,GPDB 有一個特有的運算元:移動( motion )。移動操作涉及到查詢處理期間在 Segment 之間移動資料。motion 分為廣播( broadcast )和重分布( redistribute motion )兩種。正是 motion 運算元將查詢計劃分割為一個個 slice ,上一層 slice 對應的進程會讀取下一層各個 slice 進程廣播或重分布的資料,然後進行計算。
Greenplum 同 PostgreSQL 一樣,採用元組流水方式擷取和處理資料。我們按需取出單條元組,在處理本條元組後,系統將會取出下一條滿足條件的元組,直到取出所有滿足條件的元組為止。slice 間的 motion 操作同樣以元組為單位收發資料,並通過下層 slice 緩衝構成生產消費模型,但不會阻斷整個查詢的流水。最終,各 Segment 的查詢結果同樣通過 motion 傳給 Master,Master 完成最終處理後返回查詢結果。
3.容錯機制節點鏡像與故障容錯
GPDB 支援為 Segment 配置鏡像節點,單個Primary Segment 與對應的 Mirror Segment 配置在不同的物理主機上。同一物理主機可同時混合裝載多個對應不同執行個體的 Primary Segment 和 Mirror Segment 。Primary Segment 與對應 Mirror Segment 之間的資料基於檔案層級同步備份。Mirror Segment 不直接參与資料庫事務和控制操作。
當 Primary Segment 不可訪問時,系統會自動切換到其對應的 Mirror Segment 上,此時,Mirror Segment 取代 Primary Segment 的作用。只要剩餘的可用 Segment 能夠保證資料完整性,在個別 Segment 或者物理主機宕機時,GPDB系統仍可能通過 Primary/Mirror 身份切換,來保持系統整體的可用狀態。
其具體切換過程是,每當 Master 發現無法串連到某 Primary Segment 時( FTS系統),會在 GPDB 的系統日誌表中標記失敗狀態,並啟用/喚醒對應的 Mirror Segment 取代原有的 Primary Segment 繼續完成後續工作。失敗的 Primary Segment 可以等恢複工作能力後,在系統處於運行狀態時切換回來。