随着大資料這個概念的興起以及真實需求在各個行業的落地,很多人都熱衷于讨論分布式資料庫,今天就這個話題,主要分為三部分:第一部分講一下分布式資料庫的過去和現狀,希望大家能對這個領域有一個全面的了解;第二部分講一下tidb的架構以及最近的一些進展;最後結合我們開發tidb過程中的一些思考講一下分布式資料庫未來可能的趨勢。
一、分布式資料庫的曆史和現狀
1、從單機資料庫說起
關系型資料庫起源自1970年代,其最基本的功能有兩個:
把資料存下來;
滿足使用者對資料的計算需求。
第一點是最基本的要求,如果一個資料庫沒辦法把資料安全完整存下來,那麼後續的任何功能都沒有意義。當滿足第一點後,使用者緊接着就會要求能夠使用資料,可能是簡單的查詢,比如按照某個key來查找value;也可能是複雜的查詢,比如要對資料做複雜的聚合操作、連表操作、分組操作。往往第二點是一個比第一點更難滿足的需求。
在資料庫發展早期階段,這兩個需求其實不難滿足,比如有很多優秀的商業資料庫産品,如oracle/db2。在1990年之後,出現了開源資料庫mysql和postgresql。這些資料庫不斷地提升單機執行個體性能,再加上遵循摩爾定律的硬體提升速度,往往能夠很好地支撐業務發展。
接下來,随着網際網路的不斷普及特别是移動網際網路的興起,資料規模爆炸式增長,而硬體這些年的進步速度卻在逐漸減慢,人們也在擔心摩爾定律會失效。在此消彼長的情況下,單機資料庫越來越難以滿足使用者需求,即使是将資料儲存下來這個最基本的需求。
2、分布式資料庫
是以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 社群最好的分布式擴充方案,不少人在基于這個項目做自己的系統。
3、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在生産環境中提供服務,将下面幾個功能在一套系統中提供:
sql支援
acid事務
水準擴充
auto failover
多機房異地容災
正因為具備如此多的誘人特性,在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。這個項目已經開發了兩年時間,當然在開始動手前我們也準備了很長時間。接下來我會介紹一下這個項目。
二、tidb的架構和最近進展
tidb本質上是一個更加正統的spanner和f1實作,并不cockroachdb那樣選擇将sql和kv融合,而是像spanner和f1一樣選擇分離。
這樣分層的思想也是貫穿整個tidb項目始終的,對于測試,滾動更新以及各層的複雜度控制會比較有優勢,另外tidb選擇了mysql協定和文法的相容,mysql社群的orm架構、運維工具,直接可以應用在tidb上,另外和 spanner一樣,tidb是一個無狀态的mpp sql layer,整個系統的底層是依賴 tikv 來提供分布式存儲和分布式事務的支援,tikv的分布式事務模型采用的是google percolator的模型,但是在此之上做了很多優化,percolator的優點是去中心化程度非常高,整個繼續不需要一個獨立的事務管理子產品,事務送出狀态這些資訊其實是均勻分散在系統的各個key的meta中,整個模型唯一依賴的是一個授時伺服器,在我們的系統上,極限情況這個授時伺服器每秒能配置設定 400w以上個單調遞增的時間戳,大多數情況基本夠用了(畢竟有google量級的場景并不多見),同時在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的分布式計算能力提速。這個項目已經開始開發,預計近期開源,五月份就能有第一個版本。
三、分布式資料庫的未來趨勢
關于未來,我覺得未來的資料庫會有幾個趨勢,也是tidb項目追求的目标: