分布式數據庫是不同的
今天的話題有兩層含義,第一層是說相對于我們所熟知的集中式數據庫來說,分布式數據庫是與之不同的。在做數據庫選型的時候,我們要充分的了解其間的不同,才能做出較為科學的決策。我想很多數據庫從業人員都了解其中的不同,不幸的是,他們不是數據庫選型的決策者,大多數決策者并不了解這一點。
關于分布式數據庫與集中式數據庫的不同,我上周已經發文討論過了,今天我要講的是另外一個問題,那就是不同的分布式數據庫產品也是不同的。
2013年,我和一些準備開發一款分布式數據庫的朋友在討論這個產品的時候,實際上大家對數據庫,特別是分布式數據庫都不太了解。我們給這款數據庫提出的目標是:
圖片
首先是超大規模,都分布式數據庫了,肯定是要能解決集中式數據庫的容量不足的問題的,因此超大是必須的,超大規模的數據庫可以解決存儲容量、計算容量與超大規模計算的速度等一系列問題;可動態擴展,不夠用了就擴節點;無需備份,自動容災,自動故障切換;有了上面這一條,那么保證永遠在線,永不出錯也就不是難事了。不過實際上今天看來,當時對數據庫的了解太粗淺了,十年過去了,我還沒看到這個數據庫產品出現。
目前的分布式數據庫產品種類繁多,技術路線也各有不同,我今天不準備對其做準確的分類,而是從幾個小角度來看看這些數據庫產品之間的不同。首先是從存算分離和對等分布式這兩種最為典型流派說起。分布式數據庫要么采用存算分離架構,要么采用對等分布式架構。其典型產品就是TiDB和OceanBase。
存算分離,顧名思義,其計算引擎和存儲引擎是完全分離的,計算引擎負責SQL的執行,存儲引擎負責管理被存儲的數據。徹底的存算分離的數據庫,其最典型的特點是創建數據表的時候不需要SHARDING KEY,數據存儲的分片是數據庫內部自動管理的。當SQL引擎需要訪問某個數據的時候,會根據元數據信息以及分片邏輯,自動找到所需要訪問的數據。存算分離的數據庫,計算節點可能只有一個,也可以是一個讀寫節點,多個只讀節點,甚至也可以是多個全功能對等的讀寫節點。比如TiDB,其TiDB節點是計算節點,多個計算節點是對等模式的,全功能讀寫的。其TiKV是存儲節點,負責存儲所有的數據。
對于存算分離的分布式數據庫,計算節點生成SQL的執行樹后,會把算子下推到多個存儲節點進行并行的數據掃描或者訪問。算子的并行化程度以及能夠下推的粒度決定了執行的效率。因此此類數據庫的性能取決于SQL執行計劃的水平與可下推的算子的粒度。
有些存算分離的數據庫,其存儲節點是一個獨立的數據庫實例,這種情況下,大部分算子是以子SQL的形式下推到存儲節點的,其效率相對是較低的。當然,數據庫廠商也可以就其數據庫引擎的核心進行改造,使之能夠接受更細小的算子的下推,從而提高執行性能。有些基于Postgresql等開源代碼的分布式數據庫,比如Gaussdb就是這么做的。
談到Gaussdb,這里就多說幾句,實際上Gaussdb是一種存算分離的分布式數據庫,其CN是計算節點,DN是存儲節點。不過Gaussdb與TiDB雖然說都是采用存算分離,但是其實現方式差異很大。Gaussdb的CN/DN實際上都包含了一個全功能的RDBMS實例,甚至客戶端可以直接連接到DN上去做SQL的執行。而TiDB的計算與存儲引擎的功能是完全分離的,必須二者合體才能完成SQL執行的任務。對于Gaussdb來說,一個SQL可以將其子查詢全面下發到DN上,CN只做簡單的匯聚,CN也可以下推更細粒度的算子到DN上,由CN完成更多的計算。基于Gaussdb的架構,如果我們要將一張表分布到多個DN上,那么我們就必須指定Sharding Key。
那么這兩種存算分離架構哪個更優呢?還真的不太好說,TiDB可以像我們使用普通的集中式數據庫一樣來使用分布式數據庫,這方面TiDB似乎更勝一籌,不過實際上并非如此。因為TiDB的完全存算分離,導致了計算節點的本地數據緩沖無法實現了,所有的數據訪問都不能直接從本地緩沖里獲取,而都必須通過存儲節點獲取。這導致了一些對延時要求較高的OLTP系統的性能無法滿足,這就是所謂的“穩定的慢”。
對于一些復雜的表關聯,大查詢,其性能雖然說與架構相關,但是最終決定性能的還是CBO優化器的執行計劃的效率,以及算子分解與并行下推的能力。因此存算分離的分布式數據庫,能夠以何種粒度下推算子與優化器的功力決定了最終的性能。對于存儲節點是一個獨立的數據庫實例的分布式數據庫而言,在最初的技術實現上,肯定下推的只是子SQL。下推比SQL粒度更小的算子必須在SQL引擎的核心上做工作,因此對技術要求更高。當然隨著產品的發展,這種工作是必須要做的。不過目前很多采用此類架構的分布式數據庫的存儲引擎采用了MySQL,對于此類數據庫的核心代碼的修改,如果不開源,是否違反了GPL協議,我一直百思不得其解。
分布式數據庫的另外一個主要流派就是對等分布式,其代表是OceanBase。此類數據庫是采用分片技術的,每個分片是一個完整的rdbms實例,具有計算引擎,并帶有存儲引擎,用于管理本地的數據。客戶端連接到任何一個分片,都可以執行SQL,不需要通過一個計算節點。這種架構的缺點是如果要把一張表打散到分布式集群中,這張表必須指定Sharding Key。不過優點是每個節點都可以通過本地緩存來提高本地數據的訪問性能。
今天的討論我主要想讓讀者了解,沒有完美的分布式數據庫架構,如果我們要來看一個分布式數據庫的水平,不僅僅要看起實現架構,更重要的是要看其SQL引擎、CBO優化器和分布式執行器的能力。誰家的產品把這些做好了,就能脫穎而出。