Categories
程式開發

2010 年代的分佈式系統:存儲之數據庫篇


回看這幾年,分佈式系統領域出現了很多新東西,特別是雲和AI 的崛起,讓這個過去其實不太sexy 的領域一下到了風口浪尖,在這期間誕生了很多新技術、新思想,讓這個古老的領域重新煥發生機。站在 2010s 的尾巴上,我想跟大家一起聊聊分佈式系統令人振奮的進化路程,以及談一些對 2020s 的大膽猜想。

無論哪個時代,存儲都是一個重要的話題,今天先聊聊數據庫。在過去的幾年,數據庫技術上出現了幾個很明顯的趨勢。

存儲和計算進一步分離

我印像中最早的存儲-計算分離的嘗試是 Snowflake,Snowflake 團隊在 2016 年發表的論文《The Snowflake Elastic Data Warehouse》是近幾年我讀過的最好的大數據相關論文之一,尤其推薦閱讀。 Snowflake 的架構關鍵點是在無狀態的計算節點 + 中間的緩存層 + S3 上存儲數據,計算並不強耦合緩存層,非常符合雲的思想。從最近 AWS 推出的 RedShift 冷熱分離架構來看,AWS 也承認 Snowflake 這個搞法是先進生產力的發展方向。另外這幾年關注數據庫的朋友不可能不注意到 Aurora。不同於 Snowflake,Aurora 應該是第一個將存儲-計算分離的思想用在 OLTP 數據庫中的產品,並大放異彩。 Aurora 的成功在於將數據複製的粒度從 Binlog降低到 Redo Log ,極大地減少複製鏈路上的 IO 放大。而且前端復用了MySQL,基本做到了100% 的應用層MySQL 語法兼容,並且託管了運維,同時讓傳統的MySQL 適用範圍進一步拓展,這在中小型數據量的場景下是一個很省心的方案。

雖然 Aurora 獲得了商業上的成功,但是從技術上,我並不覺得有很大的創新。熟悉 Oracle 的朋友第一次見 Aurora 的架構可能會覺得和 RAC 似曾相識。 Oracle 大概在十幾年前就用了類似的方案,甚至很完美的解決了 Cache Coherence 的問題。另外,Aurora 的Multi-Master 還有很長的路要走,從最近在ReInvent 上的說法來看,目前Aurora 的Multi-Master 的主要場景還是作為Single Writer 的高可用方案,本質的原因應該是目前Multi-Writer 採用樂觀衝突檢測,衝突檢測的粒度是Page,在衝突率高的場合會帶來很大的性能下降。

我認為 Aurora 是一個很好的迎合 90% 的公有云互聯網用戶的方案:100% MySQL 兼容,對一致性不太關心,讀遠大於寫,全託管。但同時,Aurora 的架構決定了它放棄了 10% 有極端需求的用戶,如全局的 ACID 事務+ 強一致,Hyper Scale(百 T 以上,並且業務不方便拆庫),需要實時的複雜 OLAP。這類方案我覺得類似 TiDB 的以 Shared-nothing 為主的設計才是唯一的出路。作為一個分佈式系統工程師,我對任何不能水平擴展的架構都會覺得不太優雅。

分佈式 SQL 數據庫登上舞台,ACID 全面回歸

回想幾年前NoSQL 最風光的時候,大家恨不得將一切系統都使用NoSQL 改造,雖然易用性、擴展性和性能都不錯,但是多數NoSQL 系統都拋棄掉了數據庫最重要的一些東西,例如ACID 約束,SQL 等等。 NoSQL 的主要推手是互聯網公司,互聯網公司的簡單業務加上超強的工程師團隊,NoSQL丟掉的東西當然能用某些工具簡單搞定。

但最近幾年大家漸漸發現低垂的果實基本上沒有了,剩下的都是硬骨頭。

最好的例子就是作為 NoSQL 的開山鼻祖,Google 第一個搞了 NewSQL (Spanner 和 F1)。在後移動時代,業務變得越來越複雜,要求越來越實時,同時​​對於數據的需求也越來越強。尤其對於一些金融機構來說,一方面產品面臨著互聯網化,一方面不管是出於監管的要求還是業務本身的需求,ACID 是很難繞開的。更現實的是,大多數傳統公司並沒有像頂級互聯網公司的人才供給,大量歷史系統基於 SQL 開發,完全遷移到 NoSQL 上肯定不現實。

在這個背景下,分佈式關係型數據庫,我認為這是我們這一代人,在開源數據庫這個市場上最後一個 missing part,終於慢慢流行起來。這背後的很多細節由於篇幅的原因我就不介紹,推薦閱讀 PingCAP TiFlash技術負責人 maxiaoyu 的一篇文章《從大數據到數據庫》,對這個話題有很精彩的闡述。

雲基礎設施和數據庫的進一步整合

在過去的幾十年,數據庫開發者都像是在單打獨鬥,就好像操作系統以下的就完全是黑盒了,這個假設也沒錯,畢竟軟件開發者大多也沒有硬件背景。另外如果一個方案過於綁定硬件和底層基礎設施,必然很難成為事實標準,而且硬件非常不利於調試和更新,成本過高,這也是我一直對定制一體機不是太感興趣的原因。但是雲的出現,將IaaS 的基礎能力變成了軟件可複用的單元,我可以在雲上按需租用算力和服務,這會給數據庫開發者在設計系統的時候帶來更多的可能性,舉幾個例子:

1、 Spanner 原生的 TrueTime API 依賴原子鐘和 GPS 時鐘,如果純軟件實現的話,需要犧牲的東西很多(例如 CockroachDB 的 HLC 和 TiDB 的改進版 Percolator 模型,都是基於軟件時鐘的事務模型)。但是長期來看,不管是 AWS 還是 GCP 都會提供類似 TrueTime 的高精度時鐘服務,這樣一來我們就能更好的實現低延遲長距離分佈式事務。

2、 可以藉助Fargate + EKS 輕量級容器+ Managed K8s 的服務,讓數據庫應對突發熱點小表讀的場景(這個場景幾乎是Shared-Nothing 架構的老大難問題),比如在TiDB 中通過Raft Learner的方式,配合雲的Auto Scaler 快速在新的容器中創建只讀副本,而不是僅僅通過3 副本提供服務;比如動態起10 個pod,給熱點數據創建Raft 副本(這是我們將TiKV 的數據分片設計得那麼小的一個重要原因),處理完突發的讀流量後再銷毀這些容器,變成3 副本。

3、冷熱數據分離,這個很好理解,將不常用的數據分片,分析型的副本,數據備份放到 S3 上,極大地降低成本。

4、 RDMA/CPU/超算 as a Service,任何云上的硬件層面的改進,只要暴露 API,都是可以給軟件開發者帶來新的好處。

例子還有很多,我就不一一列舉了。總之我的觀點是雲服務 API 的能力會像過去的代碼標準庫一樣,是大家可以依賴的東西,雖然現在公有云的 SLA 仍然不夠理想,但是長遠上看,一定是會越來越完善的。

所以,數據庫的未來在哪裡?是更加的垂直化還是走向統一?對於這個問題,我同意這個世界不存在銀彈,但是我也並不像我的偶像,AWS CTO Vogels 博士那麼悲觀,相信未來是一個割裂的世界(AWS 恨不得為了每個細分的場景設計一個數據庫)。過度地細分會加大數據在不同系統中流動的成本。解決這個問題有兩個關鍵:

  • 數據產品應該切分到什麼粒度?

  • 用戶可不可以不用知道背後發生了什麼?

第一個問題並沒有一個明確的答案,但是我覺得肯定不是越細越好的,而且這個和Workload 有關,比如如果沒有那麼大量的數據,直接在MySQL 或者PostgreSQL 上跑分析查詢其實一點問題也沒有,沒有必要非去用Redshift。雖然沒有直接的答案,但是我隱約覺得第一個問題和第二個問題是息息相關的,畢竟沒有銀彈,就像OLAP 跑在列存儲引擎上一定比行存引擎快,但是對用戶來說其實可以都是SQL 的接口。

SQL 是一個非常棒的語言,它只描述了用戶的意圖,而且完全與實現無關,對於數據庫來說,其實可以在SQL 層的後面來進行切分,在TiDB 中,我們引入TiFlash 就是一個很好的例子。動機很簡單:

1、用戶其實並不是數據庫專家,你不能指望用戶能 100% 在恰當的時間使用恰當的數據庫,並且用對。

2、數據之間的同步在一個系統之下才能盡量保持更多的信息,例如,TiFlash 能保持 TiDB 中事務的 MVCC 版本,TiFlash 的數據同步粒度可以小到 Raft Log 的級別。

另外一些新的功能仍然可以以 SQL 的接口對外提供,例如全文檢索,用 SQL 其實也可以簡潔的表達。這裡我就不一一展開了。

我其實堅信系統一定是朝著更智能、更易用的方向發展的,現在都 21 世紀了,你是希望每天拿著一個 Nokia 再背著一個相機,還是直接一部手機搞定?

作者介紹:

黃東旭,分佈式系統專家,架構師,開源軟件作者。 PingCAP 聯合創始人兼 CTO,知名開源項目 Codis / TiDB / TiKV 主要作者,曾就職於微軟亞洲研究院,網易有道及豌豆莢。 2015 年創業,成立 PingCAP,致力於下一代開源分佈式數據庫的研發工作,擅長分佈式存儲系統設計與實現,高並發後端架構設計。