細說分佈式數據庫的過去、如今與將來


隨着大數據這個概念的興起以及真實需求在各個行業的落地,不少人都熱衷於討論分佈式數據庫,今天就這個話題,主要分爲三部分:第一部分講一下分佈式數據庫的過去和現狀,但願你們能對這個領域有一個全面的瞭解;第二部分講一下TiDB的架構以及最近的一些進展;最後結合咱們開發TiDB過程當中的一些思考講一下分佈式數據庫將來可能的趨勢。


1、分佈式數據庫的歷史和現狀算法



一、從單機數據庫提及數據庫


關係型數據庫起源自1970年代,其最基本的功能有兩個:緩存


  1. 把數據存下來;  安全

  2. 知足用戶對數據的計算需求。服務器


第一點是最基本的要求,若是一個數據庫沒辦法把數據安全完整存下來,那麼後續的任何功能都沒有意義。當知足第一點後,用戶緊接着就會要求可以使用數據,多是簡單的查詢,好比按照某個Key來查找Value;也多是複雜的查詢,好比要對數據作複雜的聚合操做、連表操做、分組操做。每每第二點是一個比第一點更難知足的需求。架構


在數據庫發展早期階段,這兩個需求其實不難知足,好比有不少優秀的商業數據庫產品,如Oracle/DB2。在1990年以後,出現了開源數據庫MySQL和PostgreSQL。這些數據庫不斷地提高單機實例性能,再加上遵循摩爾定律的硬件提高速度,每每可以很好地支撐業務發展。負載均衡


接下來,隨着互聯網的不斷普及特別是移動互聯網的興起,數據規模爆炸式增加,而硬件這些年的進步速度卻在逐漸減慢,人們也在擔憂摩爾定律會失效。在此消彼長的狀況下,單機數據庫愈來愈難以知足用戶需求,即便是將數據保存下來這個最基本的需求。框架


二、分佈式數據庫運維


因此2005年左右,人們開始探索分佈式數據庫,帶起了NoSQL這波浪潮。這些數據庫解決的首要問題是單機上沒法保存所有數據,其中以HBase/Cassadra/MongoDB爲表明。爲了實現容量的水平擴展,這些數據庫每每要放棄事務,或者是隻提供簡單的KV接口。存儲模型的簡化爲存儲系統的開發帶來了便利,可是下降了對業務的支撐。分佈式


(1)NoSQL的進擊


HBase是其中的典型表明。HBase是Hadoop生態中的重要產品,Google BigTable的開源實現,因此這裏先說一下BigTable。 


BigTable是Google內部使用的分佈式數據庫,構建在GFS的基礎上,彌補了分佈式文件系統對於小對象的插入、更新、隨機讀請求的缺陷。HBase也按照這個架構實現,底層基於HDFS。HBase自己並不實際存儲數據,持久化的日誌和SST file存儲在HDFS上,Region Server經過 MemTable 提供快速的查詢,寫入都是先寫日誌,後臺進行Compact,將隨機寫轉換爲順序寫。數據經過 Region 在邏輯上進行分割,負載均衡經過調節各個Region Server負責的Region區間實現,Region在持續寫入後,會進行分裂,而後被負載均衡策略調度到多個Region Server上。


前面提到了,HBase自己並不存儲數據,這裏的Region僅是邏輯上的概念,數據仍是以文件的形式存儲在HDFS上,HBase並不關心副本個數、位置以及水平擴展問題,這些都依賴於HDFS實現。和BigTable同樣,HBase提供行級的一致性,從CAP理論的角度來看,它是一個CP的系統,而且沒有更進一步提供 ACID 的跨行事務,也是很遺憾。


HBase的優點在於經過擴展Region Server能夠幾乎線性提高系統的吞吐,及HDFS自己就具備的水平擴展能力,且整個系統成熟穩定。但HBase依然有一些不足。首先,Hadoop使用Java開發,GC延遲是一個沒法避免問題,這對系統的延遲形成一些影響。另外,因爲HBase自己並不存儲數據,和HDFS之間的交互會多一層性能損耗。第三,HBase和BigTable同樣,並不支持跨行事務,因此在Google內部有團隊開發了MegaStore、Percolator這些基於BigTable的事務層。Jeff Dean認可很後悔沒有在BigTable中加入跨行事務,這也是Spanner出現的一個緣由。


(2)RDMS的救贖


除了NoSQL以外,RDMS系統也作了很多努力來適應業務的變化,也就是關係型數據庫的中間件和分庫分表方案。作一款中間件須要考慮不少,好比解析 SQL,解析出ShardKey,而後根據ShardKey分發請求,再合併結果。另外在中間件這層還須要維護Session及事務狀態,並且大多數方案並不支持跨shard的事務,這就不可避免地致使了業務使用起來會比較麻煩,須要本身維護事務狀態。此外,還有動態的擴容縮容和自動的故障恢復,在集羣規模愈來愈大的狀況下,運維和DDL的複雜度是指數級上升。


國內開發者在這個領域有過不少的著名的項目,好比阿里的Cobar、TDDL,後來社區基於Cobar改進的MyCAT,360開源的Atlas等,都屬於這一類中間件產品。在中間件這個方案上有一個知名的開源項目是Youtube的Vitess,這是一個集大成的中間件產品,內置了熱數據緩存、水平動態分片、讀寫分離等,但這也形成了整個項目很是複雜。


另一個值得一提的是PostgreSQL XC這個項目,其總體的架構有點像早期版本的OceanBase,由一箇中央節點來處理協調分佈式事務,數據分散在各個存儲節點上,應該是目前PG 社區最好的分佈式擴展方案,很多人在基於這個項目作本身的系統。


三、NewSQL的發展


2012~2013年Google 相繼發表了Spanner和F1兩套系統的論文,讓業界第一次看到了關係模型和NoSQL的擴展性在一個大規模生產系統上融合的可能性。 Spanner 經過使用硬件設備(GPS時鐘+原子鐘)巧妙地解決時鐘同步的問題,而在分佈式系統裏,時鐘正是最讓人頭痛的問題。Spanner的強大之處在於即便兩個數據中心隔得很是遠,也能保證經過TrueTime API獲取的時間偏差在一個很小的範圍內(10ms),而且不須要通信。Spanner的底層仍然基於分佈式文件系統,不過論文裏也說是能夠將來優化的點。


Google的內部的數據庫存儲業務,大可能是3~5副本,重要的數據須要7副本,且這些副本遍及全球各大洲的數據中心,因爲廣泛使用了Paxos,延遲是能夠縮短到一個能夠接受的範圍(寫入延遲100ms以上),另外由Paxos帶來的Auto-Failover能力,更是讓整個集羣即便數據中心癱瘓,業務層都是透明無感知的。F1是構建在Spanner之上,對外提供了SQL接口,F1是一個分佈式MPP SQL層,其自己並不存儲數據,而是將客戶端的SQL翻譯成對KV的操做,調用Spanner來完成請求。


Spanner和F1的出現標誌着第一個NewSQL在生產環境中提供服務,將下面幾個功能在一套系統中提供:


  1. SQL支持 

  2. ACID事務 

  3. 水平擴展 

  4. Auto Failover

  5. 多機房異地容災


正由於具有如此多的誘人特性,在Google內部,大量的業務已經從原來的 BigTable切換到Spanner之上。相信這對業界的思路會有巨大的影響,就像當年的Hadoop同樣,Google的基礎軟件的技術趨勢是走在社區前面的。


Spanner/F1論文引發了社區的普遍的關注,很快開始出現了追隨者。第一個團隊是CockroachLabs作的CockroachDB。CockroachDB的設計和Spanner很像,可是沒有選擇TrueTime API ,而是使用HLC(Hybrid logical clock),也就是NTP +邏輯時鐘來代替TrueTime時間戳,另外CockroachDB選用Raft作數據複製協議,底層存儲落地在RocksDB中,對外的接口選擇了PG協議。


CockroachDB的技術選型比較激進,好比依賴了HLC來作事務,時間戳的精確度並無辦法作到10ms內的延遲,因此Commit Wait須要用戶本身指定,其選擇取決於用戶的NTP服務時鐘偏差,這點對於用戶來講很是不友好。固然 CockroachDB的這些技術選擇也帶來了很好的易用性,全部邏輯都在一個組件中,部署很是簡單,這個是很是大的優勢。


另外一個追隨者就是咱們作的TiDB。這個項目已經開發了兩年時間,固然在開始動手前咱們也準備了很長時間。接下來我會介紹一下這個項目。


2、TiDB的架構和最近進展


TiDB本質上是一個更加正統的Spanner和F1實現,並不CockroachDB那樣選擇將SQL和KV融合,而是像Spanner和F1同樣選擇分離。下面是TiDB的架構圖:



這樣分層的思想也是貫穿整個TiDB項目始終的,對於測試,滾動升級以及各層的複雜度控制會比較有優點,另外TiDB選擇了MySQL協議和語法的兼容,MySQL社區的ORM框架、運維工具,直接能夠應用在TiDB上,另外和 Spanner同樣,TiDB是一個無狀態的MPP SQL Layer,整個系統的底層是依賴 TiKV 來提供分佈式存儲和分佈式事務的支持,TiKV的分佈式事務模型採用的是Google Percolator的模型,可是在此之上作了不少優化,Percolator的優勢是去中心化程度很是高,整個繼續不須要一個獨立的事務管理模塊,事務提交狀態這些信息實際上是均勻分散在系統的各個key的meta中,整個模型惟一依賴的是一個授時服務器,在咱們的系統上,極限狀況這個授時服務器每秒能分配 400w以上個單調遞增的時間戳,大多數狀況基本夠用了(畢竟有Google量級的場景並很少見),同時在TiKV中,這個授時服務自己是高可用的,也不存在單點故障的問題。



上面是TiKV的架構圖。TiKV和CockroachDB同樣也是選擇了Raft做爲整個數據庫的基礎,不同的是,TiKV總體採用Rust語言開發,做爲一個沒有GC和 Runtime的語言,在性能上能夠挖掘的潛力會更大。不一樣TiKV實例上的多個副本一塊兒構成了一個Raft Group,PD負責對副本的位置進行調度,經過配置調度策略,能夠保證一個Raft Group的多個副本不會保存在同一臺機器/機架/機房中。


除了核心的TiDB、TiKV以外,咱們還提供了很多易用的工具,便於用戶作數據遷移和備份。好比咱們提供的Syncer,不但能將單個MySQL實例中的數據同步到TiDB,還能將多個MySQL實例中的數據彙總到一個TiDB集羣中,甚至是將已經分庫分表的數據再合庫合表。這樣數據的同步方式更加靈活好用。


TiDB目前即將發佈RC3版本,預計六月份可以發佈GA版本。在即將到來的 RC3版本中,對MySQL兼容性、SQL優化器、系統穩定性、性能作了大量的工做。對於OLTP場景,重點優化寫入性能。另外提供了權限管理功能,用戶能夠按照MySQL的權限管理方式控制數據訪問權限。對於OLAP場景,也對優化器作了大量的工做,包括更多語句的優化、支持SortMergeJoin算子、IndexLookupJoin算子。另外對內存使用也作了大量的優化,一些場景下,內存使用降低75%。


除了TiDB自己的優化以外,咱們還在作一個新的工程,名字叫TiSpark。簡單來說,就是讓Spark更好地接入TiDB。如今其實Spark已經能夠經過JDBC接口讀取TiDB中的數據,可是這裏有兩個問題:1. 只能經過單個TiDB節點讀取數據且數據須要從TiKV中通過 TiDB 中轉。2. 不能和Spark的優化器相結合,咱們指望能和Spark的優化器整合,將Filter、聚合能經過TiKV的分佈式計算能力提速。這個項目已經開始開發,預計近期開源,五月份就能有第一個版本。


3、分佈式數據庫的將來趨勢


關於將來,我以爲將來的數據庫會有幾個趨勢,也是TiDB項目追求的目標:


一、數據庫會隨着業務雲化,將來一切的業務都會跑在雲端,無論是私有云或者公有云,運維團隊接觸的可能不再是真實的物理機,而是一個個隔離的容器或者「計算資源」,這對數據庫也是一個挑戰,由於數據庫天生就是有狀態的,數據老是要存儲在物理的磁盤上,而數據移動的代價比移動容器的代價可能大不少。


二、多租戶技術會成爲標配,一個大數據庫承載一切的業務,數據在底層打通,上層經過權限,容器等技術進行隔離,可是數據的打通和擴展會變得異常簡單,結合第一點提到的雲化,業務層能夠不再用關心物理機的容量和拓撲,只須要認爲底層是一個無窮大的數據庫平臺便可,不用再擔憂單機容量和負載均衡等問題。


三、OLAP和OLTP業務會融合,用戶將數據存儲進去後,須要比較方便高效的方式訪問這塊數據,可是OLTP和OLAP在SQL優化器/執行器這層的實現必定是千差萬別的。以往的實現中,用戶每每是經過ETL工具將數據從OLTP數據庫同步到OLAP數據庫,這一方面形成了資源的浪費,另外一方面也下降了OLAP的實時性。對於用戶而言,若是能使用同一套標準的語法和規則來進行數據的讀寫和分析,會有更好的體驗。


四、在將來分佈式數據庫系統上,主從日誌同步這樣落後的備份方式會被Multi-Paxos / Raft這樣更強的分佈式一致性算法替代,人工的數據庫運維在管理大規模數據庫集羣時是不可能的,全部的故障恢復和高可用都將是高度自動化的。