分佈式系統 in 2010s :存儲之數據庫篇

做者:黃東旭前端

常常思考一個問題,爲何咱們須要分佈式?很大程度或許是不得已而爲之。若是摩爾定律不會失效,若是經過低成本的硬件就能解決互聯網日益增加的計算存儲需求,是否是咱們也就不須要分佈式了。

過去的二三十年,是一場軟件工程師們自我拯救的,浩浩蕩蕩的革命。分佈式技術的發展,深入地改變了咱們編程的模式,改變了咱們思考軟件的模式。經過隨處可見的 X86 或者 Arm 機器,構建出一個無限擴展的計算以及存儲能力,這是軟件工程師最浪漫的自我救贖。數據庫

值 2019 年底,PingCAP 聯合 InfoQ 共同策劃出品「分佈式系統前沿技術」專題, 邀請轉轉、Pulsar、微衆銀行、UCloud、知乎、貝殼金服等技術團隊共同參與,從數據庫、硬件、測試、運維等角度,共同探索這個古老領域的新生機。編程

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

存儲和計算進一步分離

我印象中最先的存儲-計算分離的嘗試是 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 的開山鼻祖,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 巴不得爲了每一個細分的場景設計一個數據庫)。過分地細分會加大數據在不一樣系統中流動的成本。解決這個問題有兩個關鍵:

  1. 數據產品應該切分到什麼粒度?
  2. 用戶可不能夠不用知道背後發生了什麼?

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

SQL 是一個很是棒的語言,它只描述了用戶的意圖,並且徹底與實現無關,對於數據庫來講,其實能夠在 SQL 層的後面來進行切分,在 TiDB 中,咱們引入 TiFlash 就是一個很好的例子。動機很簡單:

  1. 用戶其實並非數據庫專家,你不能期望用戶能 100% 在恰當的時間使用恰當的數據庫,而且用對。
  2. 數據之間的同步在一個系統之下才能儘可能保持更多的信息,例如,TiFlash 能保持 TiDB 中事務的 MVCC 版本,TiFlash 的數據同步粒度能夠小到 Raft Log 的級別。

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

我其實堅信系統必定是朝着更智能、更易用的方向發展的,如今都 21 世紀了,你是但願天天拿着一個 Nokia 再揹着一個相機,仍是直接一部手機搞定?

本文是「分佈式系統前沿技術」專題文章,目前該專題在持續更新中,歡迎你們保持關注👇

相關文章
相關標籤/搜索