天天看點

NewSQL的未來

<a></a>

NewSQL的未來

編者按:黃東旭,pingcap 聯合創始人、cto,是很多人仰望的國内分布式存儲領域(newsql) 技術大神級别的人物。我們請黃東旭來聊聊他眼中的newsql,有需要交流的内容,歡迎留言。

最近資料庫圈的一個比較大的事件是 nosql 先驅之一的 rethinkdb 的歇業大吉,rethinkdb這個事情本身我就不多做評論了,現在這個時機去分析不免有馬後炮的嫌疑,今天我想借着這個引子談談新型資料庫的未來。

縱觀過去十年資料庫的發展,其實是相當迅速,随着網際網路的發展以及業務資料量的不斷膨脹,大家漸漸發現傳統的單機 rdbms 開始出現一些瓶頸,很多業務的模型也和當初資料庫設計的場景不太一樣,一個最典型的思潮就是反範式設計,通過适當的資料備援來減小 join 帶來的開銷,當初 *-nf 的設計目的是盡可能的減小資料備援,但現在的硬體和存儲容量遠非當年可比,而且存儲媒體也在慢慢發生變化,從錄音帶到磁盤到閃存,甚至最近慢慢開始變成另一個異構的分布式存儲系統 (如 google f1, tidb),rdbms 本身也需要進化。在 nosql 蓬勃發展的這幾年也是 web 和移動端崛起的幾年,但是在 nosql 中反範式的設計是需要以付出一緻性為代價,不過這個世界的業務多種多樣,大家漸漸發現将一緻性交給業務去管理會極大的增加業務的複雜度,但是在資料庫層做又沒有太好的可以 scale 的方案,spof 問題和單機性能及帶寬瓶頸會成為懸在業務頭上的達摩克利斯之劍。

newsql 的出現就是為了解決擴充性和一緻性之間的沖突,我所了解的 newsql 主要還是面向 oltp 業務和輕量級的olap業務,大型複雜的olap 資料庫暫時不在本文讨論的範圍。對于 newsql 來說,我覺得應該需要明确一下必備的性質,什麼樣的資料庫才能稱之為newsql,在我看來,應該有以下幾點必備的特性:

1.sql

2.acid transaction, 支援跨行事務

3.auto-scale

4.auto-failover

sql

一切為了相容性!相容性!相容性! sql 的支援是和之前 nosql 從接口上最大的不同點,但是在一個分布式系統上支援 sql 和在單機 rdbms 上也是完全不一樣的,更關鍵的是如何更好的利用多個節點的計算能力,生成更好的執行計劃,将計算邏輯盡可能的均攤到多個存儲節點上,設計這樣一個 sql engine 的更像是在做一個分布式計算架構,考慮的側重點和單機上的查詢引擎是不一樣的,畢竟網絡的開銷和延遲是單機資料庫之前完全不需要考慮的。不過從最近幾年社群的實作來看,尤其是一些 olap 的系統,已經有不少優秀的分布式 sql 實作,比如: hive, impala,presto, sparksql 等優秀的開源項目。雖然 oltp 的 sql engine 和olap 的側重點有所不同,但是很多技術是相通的,但是一些單機 rdbms 的 sql 是很難直接應用在分布式環境下的,比如存儲過程和視圖等。正如剛才提到的,越來越多的業務開始接受反範式的設計,甚至很多新的業務都禁止使用存儲過程和外鍵等,這是一個好的現象。

acidtransaction

對于 oltp 類型的 newsql 來說,最重要的特點我認為是需要支援 acid 的跨行事務,其實隔離級别和跨行事務是個好東西,能用更少的代碼寫出正确的程式,這個交給業務程式員寫基本費時費力還很難寫對,但在分布式場景下支援分布式事務需要犧牲點什麼。本身分布式 mvcc 并不是太難做,在 google bigtable / spanner 這樣的系統中顯式的多版本已經是标配,那麼其實犧牲掉的是一定的延遲,因為在分布式場景中實作分布式事務在生産環境中基本就隻有兩階段送出的一種辦法,不過呢,考慮到 multi-paxos 或者 raft 這樣的複制協定總是要有延遲的,兩階段送出所帶來的 contention cost 相比複制其實也不算太多,對于一個分布式資料庫來說我們優化的目标永遠是吞吐。延遲問題也可以通過緩存和靈活降低隔離級别等方法搞定。

很多使用者在進行架構設計的時候,通常會避免分布式事務,但是這其實将很多複雜度轉移給了業務層,而且實作正确的事務語義是非常複雜的事情,對于開發者的要求還蠻高的,之前其實沒有太多的辦法,因為幾乎沒有一個方案能在資料庫層面上支援事務,但是有些對一緻性的要求很高的業務對此仍然是繞不開的。就如同 google 的 senior fellow engineer,jeff dean 在去年的一個會議上提到,作為工程師最後悔的事情就是沒有在bigtable 上支援跨行事務,以至于在随後的 10 多年,google内部的團隊前赴後繼的在 bigtable 上造了多套事務的輪子以支撐業務,不過這個遺憾在 spanner 中已經彌補了,也算是 happy ending。 其實 spanner 的例子是非常好的,而且我認為 google spanner 及 f1 是第一個線上上大規模使用的 newsql 系統,很多經驗和設計我們這些後來者是可以借鑒的。我認為,從使用者的角度來說,濫用事務帶來的性能問題不能作為在資料庫層面上不支援的理由,很多場景如果使用得當,能極大的降低業務開發的複雜度。

scale

作為一個現代的資料庫,可擴充性我覺得是排在第一位的,而且這裡的可擴充性值得好好說一下,目前關系型資料庫的擴充方案上,基本隻有分庫分表和 proxy 中間件兩種方案,但是這兩種方案并沒有辦法做到透明的彈性擴充,而且到達一定規模後的運維成本幾乎是指數級别上升,這也是大多數公司在微服務實踐的過程中遇到的最大障礙,服務可以很好的做到無狀态和解耦合,但是資料天然是有狀态的,比較理想的情況是有一個統一的,通用的存儲層,讓服務層能夠放開手腳。彈性擴充的技術在很多 nosql 裡已經有過很好的實踐,目前比較成熟的方案還是類 bigtable 式的 region based 的方案,在 key-value 層面上實作水準擴充。另外值得一提的是,對于 newsql 這類需要支援 sql 的資料庫而言,region based 的資料切分是目前唯一的方案, 因為 sql 的查詢需要支援順序 scan 的資料通路方式,基于一緻性哈希的方案很難支援高效的順序通路。這裡隐含了一個假設就是真正能夠支援 scale 的 newsql 架構很難是基于中間件的方案,sql above nosql 是目前來說唯一的可行方案,從 google 的選型也能看出來。基于中間件的方案的問題是中間件很難生成足夠高效的執行計劃,而且底層的多個資料庫執行個體之間并沒有辦法提供一個統一的事務語義,在執行跨節點的 join 或者事務的時候沒有辦法保證一緻性,另外底層的資料庫執行個體(一般來說是 postgresql 或者 mysql) 本身并沒有原生的擴充方案,需要中間件層面上額外做大量的工作,這也是為什麼中間件的方案很多,但是做完美非常困難。

failover

目前大多數的資料庫的複制模型還是基于主從的方案,但是主從的方案本質上來說是沒有辦法脫離人工運維的,是以這個模型是很難 scale 的 。如果需要做 auto failover,從庫何時提升成主庫,主庫是否完全下線,提升起來的從庫是否擁有最新的資料?尤其如果出現叢集腦裂的狀況,一旦 auto failover 設計得不周全,甚至可能出現雙主的嚴重故障。是以資料的一緻性是需要 dba 的人工介入保證,但是在資料量比較龐大的情況下,人工可運維的規模是有上限的,比如 google 在 f1 之前,維護了一個 100 節點左右的 mysql 中間件叢集支援同樣的業務,在這個規模之下維護的成本就已經非常高了,使得 google 不惜以從零開始重新開發一個資料庫為代價。從 google 在 spanner 和 f1 以及現在流行的開源 newsql 方案,比如 tidb 和cockroachdb 等可以看到,在複制模型上都沒有選擇主從的模型,而是選用了 multi-paxos 或者 raft 這樣基于分布式選舉的複制協定。 

multi-paxos(以下出于省略暫用 paxos 來指代,但是實際上兩者有些不一樣,在本文特指multi-paxos)  和raft 的原理由于篇幅原因就不贅述了,簡單來說,它們是高度自動化,強一緻的複制算法,在某節點故障的時候,支援完全自動和強一緻的故障轉移和自我恢複,這樣才能做到使用者層的透明,但是這裡有一個技術的難點,即scale 政策與這樣的複制協定的融合,多個 paxos / raft group 的分裂、合并以及排程,以及相關的測試。這個技術的門檻比較高,實作起來的複雜度也比較高,但是作為一個 scale 的資料庫來說,是一定要實作的,在目前的開源實作中,隻有 pingcap 的tidb 的成熟度和穩定度是比較高的,有興趣的朋友可以參考 tidb(github.com/pingcap/tidb) 的實作。

failover相關的另外一個話題是跨資料中心多活,這個基本上是所有分布式系統開發者心中的聖杯。目前也是基本沒有方案,大多數的多活的方案還是同步熱備,而且很難在保證延遲的情況下同時保持一緻性,但是 paxos 和 raft based 的方案給多活提供了一種新的可能性,這類選舉算法,隻要一個 paxos / raft group 内的大多數節點複制成功,即可給用戶端傳回成功,舉一個簡單的例子,如果這個 group 内有三個節點,分别在北京,廊坊,廣州的三個資料中心,對于傳統的強一緻方案,一個在北京發起的寫入需要等待廣州的資料中心複制完畢,才能給用戶端傳回成功,但是對于 paxos 或者 raft 這樣的算法,其實延遲僅僅是北京和廊坊之間資料中心的延遲,比傳統方案大大的降低了延遲,雖然對于帶寬的要求仍然很高,但是我覺得這是在資料庫層面上未來實作跨資料中心多活的一個趨勢和可行的方向。按照 google 在 spanner 論文中的描述,google 的資料中心分别位于美國西海岸,東海岸,以及中部,是以總體的寫入延遲控制在半個美國的範圍内,還是可以接受的。

未來在哪裡

不妨把眼光稍微放遠一些,其實仔細想想 newsql 一直在嘗試解決問題是:擺脫人工運維束縛,存儲層實作真正的自生長,自維護,同時使用者可以以最自然的程式設計接口通路和存儲資料。當實作這點以後,業務才可以擺脫存儲的媒體,容量的限制,而專注于邏輯實作。大規模的分布式和多租戶是必然的選擇,其實這個目标和雲的目标是很接近的,實際上資料庫是雲不可或缺的一部分,不過現在的資料庫都太不 cloud-native 了,是以如何和雲更緊密結合,更好的利用雲的資源排程,如何對業務透明的同時無縫的在雲上自我進化是我最近思考得比較多的問題。在這個領域 google 是走在時代前沿的,從幾個 newsql 的開源實作者都不約而同的選擇了 spanner 和 f1 的模型上可以看得出來。

本文轉載自微信公衆号 中生代技術 freshmantechnology