「一切都會(huì)運(yùn)行在云端」。現(xiàn)在越來(lái)越多的業(yè)務(wù)從自己維護(hù)基礎(chǔ)設(shè)施轉(zhuǎn)移到公有(或者私有)云上, 帶來(lái)的好處也是無(wú)需贅述的,極大降低了 IaaS 層的運(yùn)維成本,對(duì)于數(shù)據(jù)庫(kù)層面來(lái)說(shuō)的,以往需要很強(qiáng)的 DBA 背景才能搞定彈性擴(kuò)容高可用什么的高級(jí)動(dòng)作,現(xiàn)在大多數(shù)云服務(wù)基本都或多或少提供了類似的服務(wù)。
今天的分享主要集中在比較頂尖的云服務(wù)商的云數(shù)據(jù)庫(kù)方案背后的架構(gòu),以及我最近觀察到的一些對(duì)于云數(shù)據(jù)庫(kù)有意義的工業(yè)界的相關(guān)技術(shù)的進(jìn)展。
Amazon RDS
其實(shí)說(shuō)到公有云上的云數(shù)據(jù)庫(kù),應(yīng)該最早 Amazon 的 RDS,最早應(yīng)該是在 2009 年發(fā)布的,Amazon RDS 的架構(gòu)類似在底層的數(shù)據(jù)庫(kù)上構(gòu)建了一個(gè)中間層(從架構(gòu)上來(lái)看,阿里云 RDS,UCloud RDS 等其他云的 RDS 服務(wù)基本是大同小異,比拼的是功能多樣性和實(shí)現(xiàn)的細(xì)節(jié)),這個(gè)中間層負(fù)責(zé)路由客戶端的 SQL 請(qǐng)求發(fā)往實(shí)際的數(shù)據(jù)庫(kù)存儲(chǔ)節(jié)點(diǎn),因?yàn)閷I(yè)務(wù)端的請(qǐng)求通過(guò)中間層代理,所以可以對(duì)底層的數(shù)據(jù)庫(kù)實(shí)例進(jìn)行很多運(yùn)維工作,比如備份,遷移到磁盤更大或者 IO 更空閑的物理機(jī)等,這些工作因?yàn)殡[藏在中間層后邊,業(yè)務(wù)層可以做到基本沒(méi)有感知,另外這個(gè)中間路由層基本只是簡(jiǎn)單的轉(zhuǎn)發(fā)請(qǐng)求,所以底層可以連接各種類型的數(shù)據(jù)庫(kù)。
所以一般來(lái)說(shuō),RDS 基本都會(huì)支持 MySQL / SQLServer / MariaDB / PostgreSQL 等流行的數(shù)據(jù)庫(kù),對(duì)兼容性基本沒(méi)有損失,而且在這個(gè) Proxy 層設(shè)計(jì)良好的情況下,對(duì)性能的損失是比較小的,另外有一層中間層隔離底層的資源池,對(duì)于資源的利用和調(diào)度上可以做不少事情,比如簡(jiǎn)單舉個(gè)例子,比如有一些不那么活躍的 RDS 實(shí)例可以調(diào)度在一起共用物理機(jī),比如需要在線擴(kuò)容只需要將副本建立在更大磁盤的機(jī)器上,在 Proxy 層將請(qǐng)求重新定向即可,比如定期的數(shù)據(jù)備份可以放到 S3 上,這些一切都對(duì)用戶可以做到透明。
但是這樣的架構(gòu)缺點(diǎn)也同樣明顯:本質(zhì)上還是一個(gè)單機(jī)主從的架構(gòu),對(duì)于超過(guò)最大配置物理機(jī)的容量,CPU 負(fù)載,IO 的場(chǎng)景就束手無(wú)策了,隨著很多業(yè)務(wù)的數(shù)據(jù)量并發(fā)量的增長(zhǎng),尤其是移動(dòng)互聯(lián)網(wǎng)的發(fā)展,無(wú)限的可擴(kuò)展性成為了一個(gè)很重要需求。當(dāng)然對(duì)于絕大多數(shù)數(shù)據(jù)量要求沒(méi)那么大,單實(shí)例沒(méi)有高并發(fā)訪問(wèn)的庫(kù)來(lái)說(shuō),RDS 仍然是很適合的。
Amazon DynamoDB
對(duì)于剛才提到的水平擴(kuò)展問(wèn)題,一些用戶實(shí)在痛的不行,甚至能接受放棄掉關(guān)系模型和 SQL,比如一些互聯(lián)網(wǎng)應(yīng)用業(yè)務(wù)模型比較簡(jiǎn)單,但是并發(fā)量和數(shù)據(jù)量巨大,應(yīng)對(duì)這種情況,Amazon 開(kāi)發(fā)了 DynamoDB,并于 2012 年初發(fā)布 DynamoDB 的云服務(wù),其實(shí) Dynamo 的論文早在 2007 年就在 SOSP 發(fā)表,這篇有歷史意義的論文直接引爆了 NoSQL 運(yùn)動(dòng),讓大家覺(jué)得原來(lái)數(shù)據(jù)庫(kù)還能這么搞,關(guān)于 DynamoDB 的模型和一些技術(shù)細(xì)節(jié),我在我另一篇文章《開(kāi)源數(shù)據(jù)庫(kù)現(xiàn)狀》提過(guò),這里就不贅述了。
Dynamo 對(duì)外主打的特點(diǎn)是水平擴(kuò)展能力和通過(guò)多副本實(shí)現(xiàn)(3副本)的高可用,另外在 API 的設(shè)計(jì)上可以支持最終一致性讀取和強(qiáng)一致性讀取,最終一致性讀取能提升讀的吞吐量。但是請(qǐng)注意,DynamoDB 雖然有強(qiáng)一致讀,但是這里的強(qiáng)一致性并不是傳統(tǒng)我們?cè)跀?shù)據(jù)庫(kù)里說(shuō)的 ACID 的 C,而且由于沒(méi)有時(shí)序的概念(只有 vector clock),對(duì)于沖突的處理只能交給客戶端,Dynamo 并不支持事務(wù)。不過(guò)對(duì)于一些特定的業(yè)務(wù)場(chǎng)景來(lái)說(shuō),擴(kuò)展能力和可用性是最重要的,不僅僅是容量,還有集群的吞吐。
阿里云 DRDS
但是那些 RDS 的用戶的數(shù)據(jù)量也是在持續(xù)增長(zhǎng)的,對(duì)于云服務(wù)提供商來(lái)說(shuō)不能眼睜睜的看著這些 RDS 用戶數(shù)據(jù)量一大就走掉或者自己維護(hù)數(shù)據(jù)庫(kù)集群,因?yàn)橐膊皇钦l(shuí)都能徹底重構(gòu)代碼到 NoSQL 之上,并且分庫(kù)分表其實(shí)對(duì)于業(yè)務(wù)開(kāi)發(fā)者來(lái)說(shuō)是一個(gè)很痛苦的事情,在痛苦中往往是蘊(yùn)含著商業(yè)機(jī)會(huì)的。
比如對(duì)于 RDS 的擴(kuò)展方案,我介紹兩個(gè)比較典型的,第一個(gè)是阿里云的 DRDS (不過(guò)現(xiàn)在好像從阿里云的產(chǎn)品列表里拿掉了?),DRDS 其實(shí)思路很簡(jiǎn)單,就是比 RDS 多一小步,在剛才提到的 RDS 的中間層中加入用戶配置的路由策略,比如用戶可以指定某個(gè)表的某些列作為 sharding key 根據(jù)一定規(guī)則路由到特定的實(shí)例,也可以垂直的配置分庫(kù)的策略。
其實(shí) DRDS 的前身就是淘寶的 TDDL,只不過(guò)原來(lái) TDDL 是做在 JDBC 層,現(xiàn)在將 TDDL 做進(jìn)了 Proxy 層(有點(diǎn)像把 TDDL 塞到 Cobar 的感覺(jué)),這樣的好處是,將應(yīng)用層分庫(kù)分表的工作封裝起來(lái)了,但是本質(zhì)上仍然是一個(gè)中間件的方案,盡管能對(duì)簡(jiǎn)單的業(yè)務(wù)做到一定程度的 SQL 兼容。
對(duì)于一些復(fù)雜查詢,多維度查詢,跨 Shard 事務(wù)支持都是有限了,畢竟中間路由層對(duì) SQL 的理解有限,至于更換 Sharding key 、DDL、備份也是很麻煩的事情,從 Youtube 開(kāi)源的中間件 Vitess 的實(shí)現(xiàn)和復(fù)雜程度來(lái)看甚至并不比實(shí)現(xiàn)一個(gè)數(shù)據(jù)庫(kù)簡(jiǎn)單,但是兼容性卻并沒(méi)有重新寫一個(gè)數(shù)據(jù)庫(kù)來(lái)得好。
Amazon Aurora
后來(lái)時(shí)間來(lái)到了 2015 年,Amazon 走了另外一條路,在 2015 年,Amazon Aurora 發(fā)布,Aurora 的資料在公網(wǎng)上并不多,Aurora 提供了 5x 于單機(jī) MySQL 5.6 的讀吞吐能力,不過(guò)最大也就擴(kuò)展到 15 個(gè)副本,副本越多對(duì)寫吞吐影響越大,因?yàn)橹挥幸粋€(gè) Primary Instance 能提供寫入服務(wù),單個(gè)副本最大支持容量 64T,而且支持高可用以及彈性的擴(kuò)展。
值得一提的是 Aurora 的兼容性,其實(shí)做數(shù)據(jù)庫(kù)的都知道,兼容性是一個(gè)很難解決的問(wèn)題,可能實(shí)現(xiàn)上很小的差異就會(huì)讓用戶的遷移成本變得很大,這也是為什么中間件和分庫(kù)分表的方案如此反人類的原因,我們大多都在追求用戶平滑的遷移體驗(yàn)。
Aurora 另辟蹊徑,由于公開(kāi)的資料不多,我猜想 Aurora 在 MySQL 前端之下實(shí)現(xiàn)了一個(gè)基于 InnoDB 的分布式共享存儲(chǔ)層(https://www.percona.com/blog/2015/11/16/amazon-aurora-looking-deeper/),對(duì)于讀實(shí)例來(lái)說(shuō)是很好水平擴(kuò)展的,這樣就將 workload 均攤在前端的各個(gè) MySQL 實(shí)例上,有點(diǎn)類似 Oracle RAC 那樣的 Share everything 的架構(gòu)。
這個(gè)架構(gòu)的好處相對(duì)中間件的方案很明顯,兼容性更強(qiáng),因?yàn)檫€是復(fù)用了 MySQL 的 SQL 解析器,優(yōu)化器,業(yè)務(wù)層即使有復(fù)雜查詢也沒(méi)關(guān)系,因?yàn)檫B接的就是 MySQL。但是也正是由于這個(gè)原因,在節(jié)點(diǎn)更多,數(shù)據(jù)量更大的情況下,查詢并不能利用集群的計(jì)算能力(對(duì)于很多復(fù)雜查詢來(lái)說(shuō),瓶頸出現(xiàn)在 CPU 上),而且 MySQL 的 SQL 優(yōu)化器能力一直是 MySQL 的弱項(xiàng),而且對(duì)于大數(shù)據(jù)量的查詢的 SQL 引擎的設(shè)計(jì)是和單機(jī)有天壤之別的,一個(gè)簡(jiǎn)單的例子,分布式 Query Engine 比如 SparkSQL / Presto / Impala 的設(shè)計(jì)肯定和單機(jī)的 SQL 優(yōu)化器完全不同,更像是一個(gè)分布式計(jì)算框架。
所以我認(rèn)為 Aurora 是一個(gè)在數(shù)據(jù)量不太大的情況下(有容量上限),對(duì)簡(jiǎn)單查詢的讀性能優(yōu)化的方案,另外兼容性比中間件的方案好得多。但是缺點(diǎn)是對(duì)于大數(shù)據(jù)量,復(fù)雜查詢的支持還是比較弱,另外對(duì)于寫入性能 Aurora 其實(shí)沒(méi)有做太多優(yōu)化(單點(diǎn)寫入),如果寫入上出現(xiàn)瓶頸,仍然需要在業(yè)務(wù)層做水平或者豎直拆分。
Google Cloud BigTableGoogle
作為大數(shù)據(jù)的祖宗一樣的存在,對(duì)于云真是錯(cuò)過(guò)了一波又一波,虛擬化錯(cuò)過(guò)一波讓 VMWare 和 Docker 搶先了(Google 早在十年前就開(kāi)始容器的方案,要知道容器賴以生存的 cgroups 的 patch 就是 Google 提交的),云服務(wù)錯(cuò)過(guò)一波讓 Amazon 搶先了(Google App Engine 真是可惜),大數(shù)據(jù)存儲(chǔ)錯(cuò)過(guò)一波讓開(kāi)源的 Hadoop 拿下了事實(shí)標(biāo)準(zhǔn),以至于我覺(jué)得 Google Cloud BigTable 服務(wù)中兼容 Hadoop HBase API 的決定,當(dāng)時(shí)實(shí)現(xiàn)這些 Hadoop API for BigTable 的工程師心中應(yīng)該是滴血的 :)
不過(guò)在被 Amazon / Docker / Hadoop 刺激到以后,Google 終于意識(shí)到社區(qū)和云化的力量,開(kāi)始對(duì) Google Cloud 輸出 Google 內(nèi)部各種牛逼的基礎(chǔ)設(shè)施,2015 年終于在 Google Cloud Platform 上正式亮相,對(duì)于 BigTable 的架構(gòu)相信大多數(shù)分布式存儲(chǔ)系統(tǒng)工程師都比較了解,畢竟 BigTable 的論文也是和 Amazon Dynamo 一樣是必讀的經(jīng)典,我就不贅述了。
BigTable 云服務(wù)的 API 和 HBase 兼容,所以也是 {Key : 二維表格結(jié)構(gòu)},由于在 Tablet Server 這個(gè)層次還是一個(gè)主從的結(jié)構(gòu),對(duì)一個(gè) Tablet 的讀寫默認(rèn)都只能通過(guò) Tablet Master 進(jìn)行,這樣使得 BigTable 是一個(gè)強(qiáng)一致的系統(tǒng),這里的強(qiáng)一致指的是對(duì)于單 Key 的寫入,如果服務(wù)端返回成功,接下來(lái)發(fā)生的讀取,都能是最新的值。
由于 BigTable 仍然不支持 ACID 事務(wù),所以這里的強(qiáng)一致只是對(duì)于單 Key 的操作而言的。對(duì)于水平擴(kuò)展能力來(lái)說(shuō), BigTable 其實(shí)并沒(méi)有什么限制,文檔里很囂張的號(hào)稱 Incredible scalability,但是 BigTable 并沒(méi)有提供跨數(shù)據(jù)中心(Zone)高可用和跨 Zone 訪問(wèn)的能力,也就是說(shuō),一個(gè) BigTable 集群只能部署在一個(gè)數(shù)據(jù)中心內(nèi)部,這其實(shí)看得出 BigTable 在 Google 內(nèi)部的定位,就是一個(gè)高性能低延遲的分布式存儲(chǔ)服務(wù),如果需要做跨 Zone 高可用需要業(yè)務(wù)層自己做復(fù)制在兩個(gè) Zone 之間同步,構(gòu)建一個(gè)鏡像的 BigTable 集群。
其實(shí) Google 很多業(yè)務(wù)在 MegaStore 和 Spanner 出來(lái)之前,就是這么搞的,對(duì)于 BigTable 來(lái)說(shuō)如果需要搞跨數(shù)據(jù)中心高可用,強(qiáng)一致,還要保證低延遲那是不太可能的,也不符合 BigTable 的定位。另外值得吐槽的是 BigTable 團(tuán)隊(duì)發(fā)過(guò)一個(gè) Blog (https://cloudplatform.googleblog.com/2015/05/introducing-Google-Cloud-Bigtable.html)
里面把 HBase 的延遲黑得夠嗆,一個(gè) .99 的響應(yīng)延遲 6 ms, HBase 280ms. 其實(shí)看平均響應(yīng)延遲的差距不會(huì)那么大....BigTable 由于是 C++ 寫的,優(yōu)勢(shì)就是延遲是相當(dāng)平穩(wěn)的。但是據(jù)我所知 HBase 社區(qū)也在做很多工作將 GC 帶來(lái)的影響降到最小,比如 off-heap 等優(yōu)化做完以后,HBase 的延遲表現(xiàn)會(huì)好一些。
Google Cloud Datastore
在 2011 年,Google 發(fā)表了 Megastore 的論文,第一次描述了一個(gè)支持跨數(shù)據(jù)中心高可用 + 可以水平擴(kuò)展 + 支持 ACID 事務(wù)語(yǔ)義的分布式存儲(chǔ)系統(tǒng), Google Megastore 構(gòu)建在 BigTable 之上,不同數(shù)據(jù)中心之間通過(guò) Paxos 同步,數(shù)據(jù)按照 Entity Group 來(lái)進(jìn)行分片,Entity Group 本身跨數(shù)據(jù)中心使用 Paxos 復(fù)制,跨 Entity Group 的 ACID 事務(wù)需要走兩階段的提交,實(shí)現(xiàn)了 Timestamp-based 的 MVCC。
不過(guò)也正是因?yàn)?Timstamp 的分配需要走一遍 Paxos,另外不同 Entity Groups 之間的 2PC 通信需要通過(guò)一個(gè)隊(duì)列來(lái)進(jìn)行異步的通信,所以實(shí)際的 Megastore 的 2PC 的延遲是比較大的,論文也提到大多數(shù)的寫請(qǐng)求的平均響應(yīng)延遲是 100~400ms 左右,據(jù) Google 內(nèi)部的朋友提到過(guò),Megastore 用起來(lái)是挺慢的,秒級(jí)別的延遲也是常有的事情...
作為應(yīng)該是 Google 內(nèi)部第一個(gè)支持 ACID 事務(wù)和 SQL 的分布式數(shù)據(jù)庫(kù),還是有大量的應(yīng)用跑在 Megastore 上,主要是用 SQL 和事務(wù)寫程序確實(shí)能輕松得多。為什么說(shuō)那么多 Megastore 的事情呢?因?yàn)?Google Cloud Datastore 的后端就是 Megastore…
其實(shí) Cloud Datastore 在 2011 年就已經(jīng)在 Google App Engine 中上線,也就是當(dāng)年的 Data Engine 的 High Replication Datastore,現(xiàn)在改了個(gè)名字叫 Cloud Datastore,當(dāng)時(shí)不知道背后原來(lái)就是大名鼎鼎的 Megastore 實(shí)在是失敬。雖然功能看上去很牛,又是支持高可用,又支持 ACID,還支持 SQL(只不過(guò)是 Google 精簡(jiǎn)版的 GQL)但是從 Megastore 的原理上來(lái)看延遲是非常大的,另外 Cloud Datastore 提供的接口是一套類似的 ORM 的 SDK,對(duì)業(yè)務(wù)仍然是有一定的侵入性。
Google Spanner雖然 Megastore 慢,但是架不住好用,在 Spanner 論文中提到,2012 年大概已經(jīng)有 300+ 的業(yè)務(wù)跑在 Megastore 上,在越來(lái)越多的業(yè)務(wù)在 BigTable 上造 ACID Transaction 實(shí)現(xiàn)的輪子后,Google 實(shí)在受不了了,開(kāi)始造一個(gè)大輪子 Spanner,項(xiàng)目的野心巨大,和 Megastore 一樣,ACID 事務(wù) + 水平擴(kuò)展 + SQL 支持,但是和 Megastore 不一樣的是,Spanner 沒(méi)有選擇在 BigTable 之上構(gòu)建事務(wù)層,而是直接在 Google 的第二代分布式文件系統(tǒng) Colossus 之上開(kāi)始構(gòu)建 Paxos-replicated tablet。
另外不像 Megastore 實(shí)現(xiàn)事務(wù)那樣通過(guò)各個(gè)協(xié)調(diào)者通過(guò) Paxos 來(lái)決定事務(wù)的 timestamp,而是引入了硬件,也就是 GPS 時(shí)鐘和原子鐘組成的 TrueTime API 來(lái)實(shí)現(xiàn)事務(wù),這樣一來(lái),不同數(shù)據(jù)中心發(fā)起的事務(wù)就不需要跨數(shù)據(jù)中心協(xié)調(diào)時(shí)間戳,而是直接通過(guò)本地?cái)?shù)據(jù)中心的 TrueTime API 來(lái)分配,這樣延遲就降低了很多。
Spanner 近乎完美的一個(gè)分布式存儲(chǔ),在 Google 內(nèi)部也是的 BigTable 的互補(bǔ),想做跨數(shù)據(jù)中心高可用和強(qiáng)一致和事務(wù)的話,用 Spanner,代價(jià)是可能犧牲一點(diǎn)延遲,但是并沒(méi)有Megastore 犧牲那么多;想高性能(低延遲)的話,用 BigTable。
Google Spanner
目前沒(méi)有在 Google Cloud Platform 中提供服務(wù),但是看趨勢(shì)簡(jiǎn)直是一定的事情,至少作為 Cloud Datastore 的下一代是一定的。另外一方面來(lái)看 Google 仍然沒(méi)有辦法將 Spanner 開(kāi)源,原因和 BigTable 一樣,底層依賴了 Colossus 和一堆 Google 內(nèi)部的組件,另外比 BigTable 更困難的是,TrueTime 是一套硬件...
所以在 12 年底發(fā)布 Spanner 的論文后,社區(qū)也有開(kāi)源的實(shí)現(xiàn),比如目前比較成熟的 TiDB 和 CockroachDB,一會(huì)提到社區(qū)的云數(shù)據(jù)庫(kù)實(shí)現(xiàn)的時(shí)候會(huì)介紹。Spanner 的接口比 BigTable 稍微豐富一些,支持了它稱之為 Semi-relational 的表結(jié)構(gòu),可以像關(guān)系型數(shù)據(jù)庫(kù)那樣進(jìn)行 DDL,雖然仍然要指定每行的 primary key,但是比簡(jiǎn)單的 kv 還是好太多。
Google F1
在 Spanner 項(xiàng)目開(kāi)始的同時(shí),Google 啟動(dòng)了另外一個(gè)和 Spanner 配套使用的分布式 SQL 引擎的項(xiàng)目 F1,底層有那么一個(gè)強(qiáng)一致高性能的 Spanner,那么就可以在上層嘗試將 OLTP 和部分的 OLAP 打通,F(xiàn)1 其實(shí)論文題目說(shuō)是一個(gè)數(shù)據(jù)庫(kù),但是它并不存儲(chǔ)數(shù)據(jù),數(shù)據(jù)都在 Spanner 上,它只是一個(gè)分布式查詢引擎,底層依賴 Spanner 提供的事務(wù)接口,將用戶的 SQL 請(qǐng)求翻譯成分布式執(zhí)行計(jì)劃。
Google F1提供了一種可能性,這是在其他的數(shù)據(jù)庫(kù)中一直沒(méi)有實(shí)現(xiàn)過(guò)的,OLTP 與 OLAP 融合的可能性,因?yàn)?Google F1 設(shè)計(jì)目標(biāo)是給 Google 的廣告系統(tǒng)使用,廣告投放系統(tǒng)這類系統(tǒng)一是對(duì)于一致性要求很高,壓力也很大,是典型的 OLTP 場(chǎng)景;第二是可能會(huì)有很多復(fù)雜的廣告投放效果評(píng)估的查詢,而且這類的查詢?cè)绞菍?shí)時(shí)越好,這又有點(diǎn)實(shí)時(shí) OLAP 的意思。
傳統(tǒng)的做法是 OLTP 的數(shù)據(jù)庫(kù)將數(shù)據(jù)每隔一段時(shí)間同步一份到數(shù)據(jù)倉(cāng)庫(kù)中,在數(shù)據(jù)倉(cāng)庫(kù)中離線的進(jìn)行計(jì)算,稍微好點(diǎn)的使用一些流式計(jì)算框架進(jìn)行實(shí)時(shí)計(jì)算,第一種使用數(shù)據(jù)倉(cāng)庫(kù)的方案,實(shí)時(shí)性是比較差的,倒騰數(shù)據(jù)是很麻煩的事情;至于使用流式計(jì)算框架的方案,一是靈活性不好,很多查詢邏輯需要提前寫好,沒(méi)法做很多 Ad-hoc 的事情,另外因?yàn)閮蛇吺钱悩?gòu)的存儲(chǔ),導(dǎo)致 ETL 也是很麻煩的工作。
F1 其實(shí)依靠 Spanner 的 ACID 事務(wù)和 MVCC 的特性實(shí)現(xiàn)了 100% 的 OLTP,并且自身作為一個(gè)分布式 SQL 引擎,可以利用集群的計(jì)算資源實(shí)現(xiàn)分布式的 OLAP 查詢。這帶來(lái)的好處就是并不需要額外在設(shè)置一個(gè)數(shù)據(jù)倉(cāng)庫(kù)進(jìn)行數(shù)據(jù)分析,而是直接在同一個(gè)數(shù)據(jù)庫(kù)里實(shí)時(shí)分析,另外由于 Spanner 的 MVCC 和多副本帶來(lái)的 Lock-free snapshot read 的特性,這類 OLAP 查詢并不會(huì)影響正常 OLTP 的操作。
對(duì)于 OLTP 來(lái)說(shuō),瓶頸經(jīng)常出現(xiàn)在 IO 上,對(duì)于 OLAP 來(lái)說(shuō),瓶頸反而經(jīng)常出現(xiàn)在 CPU 也就是計(jì)算上,其實(shí)看上去是能融合起來(lái),提升整個(gè)集群的資源利用率,這也是我看好 Google F1 + Spanner 這個(gè)組合的原因,未來(lái)的數(shù)據(jù)庫(kù)可能會(huì)融合數(shù)據(jù)倉(cāng)庫(kù),提供更完整且更實(shí)時(shí)的體驗(yàn)。
(其實(shí)這個(gè)下面的 GFS 不太準(zhǔn)確,現(xiàn)在應(yīng)該是 Colossus)
Open source cloud-native database
2016 年在硅谷突然有個(gè)新詞火了起來(lái) GIFEE,Google Infrastructure For Everyone Else,大家意識(shí)到好像隨著新一代的開(kāi)源基礎(chǔ)軟件的繁榮發(fā)展,原來(lái)在 Google 內(nèi)部的基礎(chǔ)設(shè)施已經(jīng)有很多高質(zhì)量的開(kāi)源實(shí)現(xiàn),比如容器方面有 Docker,調(diào)度器方面 Google 主動(dòng)開(kāi)源的 Borg 的第二代 Kubernetes,傳統(tǒng)的 BigTable 和 GFS 社區(qū)還有雖然屎但是還是能湊合用的 Hadoop,而且很多大廠覺(jué)得 Hadoop 屎的都基本自己都造了類似的輪子... 更別說(shuō)最近 Google 開(kāi)源上癮,Kubernetes 就不提了,從大熱的 Tensorflow 到相對(duì)冷門但是我個(gè)人認(rèn)為意義重大的 Apache Beam(Google Cloud Dataflow 的基礎(chǔ)),基本能獨(dú)立開(kāi)源的都在積極的擁抱社區(qū)。
這就造成了社區(qū)與 Google 內(nèi)部差距正在縮小,但是目前來(lái)說(shuō), 其他都好說(shuō), 只是 Spanner 和 F1 并不是那么容易造的,就算拋開(kāi) TrueTime 的硬件不提,實(shí)現(xiàn)一個(gè)穩(wěn)定的 Multi-Paxos 都不是容易的事情,另外分布式 SQL 優(yōu)化器這種事情也是有很高技術(shù)門檻的,另外就算造出來(lái)了,測(cè)試的復(fù)雜度也一點(diǎn)不比實(shí)現(xiàn)的復(fù)雜度低(可以參考 PingCAP 的分布式測(cè)試哲學(xué)的幾篇分享)。
目前從全球范圍內(nèi)來(lái)看,我認(rèn)為開(kāi)源世界只有兩個(gè)團(tuán)隊(duì):一個(gè) PingCAP 的 TiDB,一個(gè) CockroachLabs 的 CockroachDB 是有足夠的技術(shù)能力和視野能將 Spanner 的開(kāi)源實(shí)現(xiàn)造出來(lái)的,目前 TiDB 已經(jīng) RC1 并有不少使用者在生產(chǎn)環(huán)境使用,比 CockroachDB 的成熟度稍好,架構(gòu)上更接近正統(tǒng)的 F1 above Spanner 的架構(gòu),CockroachDB 的成熟度稍微落后一些,并且協(xié)議選擇 PostgreSQL,TiDB 選擇的是 MySQL 的協(xié)議兼容。
而且從 TiDB 的子項(xiàng)目 TiKV 中,我們看到了新一代分布式 KV 的雛形,RocksDB + Multi-Raft 不依賴第三方分布式文件系統(tǒng)(DFS)提供水平擴(kuò)展能力,正在成為新一代分布式 KV 存儲(chǔ)標(biāo)準(zhǔn)架構(gòu)。另外也很欣喜的看到竟然是由一個(gè)國(guó)內(nèi)團(tuán)隊(duì)發(fā)起并維護(hù)的這樣級(jí)別的開(kāi)源項(xiàng)目,即使放到硅谷也是頂級(jí)的設(shè)計(jì)和實(shí)現(xiàn),從 Github 的活躍度和使用的工具及運(yùn)營(yíng)社區(qū)的流程上來(lái)看,很難看出是一個(gè)國(guó)內(nèi)團(tuán)隊(duì)。
Kubernetes + Operator
剛才提到了一個(gè)詞 Cloud-Native, 其實(shí)這個(gè)詞還沒(méi)有準(zhǔn)確的定義,不過(guò)我的理解是應(yīng)用開(kāi)發(fā)者和物理設(shè)施隔離,也就是業(yè)務(wù)層不需要再去關(guān)心存儲(chǔ)的容量性能等等一切都可以透明水平擴(kuò)展,集群高度自動(dòng)化乃至支持自我修復(fù)。對(duì)于一個(gè)大規(guī)模的分布式存儲(chǔ)系統(tǒng)來(lái)說(shuō)人工是很難介入其中的,比如一個(gè)上千個(gè)節(jié)點(diǎn)的分布式系統(tǒng),幾乎每天都可能有各種各樣的節(jié)點(diǎn)故障,瞬時(shí)網(wǎng)絡(luò)抖動(dòng)甚至整個(gè)數(shù)據(jù)中心直接掛掉,人工去做數(shù)據(jù)遷移,數(shù)據(jù)恢復(fù)幾乎是不可能的事情。
很多人非常看好 Docker,認(rèn)為它改變了運(yùn)維和軟件部署方式,但是我認(rèn)為更有意義的是 Kubernetes,調(diào)度器才是 Cloud-native 架構(gòu)的核心,容器只是一個(gè)載體而已并不重要,Kubernetes 相當(dāng)于是一個(gè)分布式的操作系統(tǒng),物理層是整個(gè)數(shù)據(jù)中心,也就是 DCOS,這也是我們?cè)?Kubernetes 上下重注的原因,我認(rèn)為大規(guī)模分布式數(shù)據(jù)庫(kù)未來(lái)不可能脫離 DCOS。
不過(guò) Kubernetes 上對(duì)于有狀態(tài)的服務(wù)編排是一件比較頭疼的事情。而一般的分布式系統(tǒng)的特點(diǎn),他不僅每個(gè)節(jié)點(diǎn)都有存儲(chǔ)的數(shù)據(jù),而且他還要根據(jù)用戶需要做擴(kuò)容,縮容,當(dāng)程序更新時(shí)要可以做到不停服務(wù)的滾動(dòng)升級(jí),當(dāng)遇到數(shù)據(jù)負(fù)載不均衡情況下系統(tǒng)要做 Rebalance,同時(shí)為了保證高可用性,每個(gè)節(jié)點(diǎn)的數(shù)據(jù)會(huì)有多個(gè)副本,當(dāng)單個(gè)節(jié)點(diǎn)遇到故障,還需要自動(dòng)恢復(fù)總的副本數(shù)。而這些對(duì)于 Kubernetes 上的編排一個(gè)分布式系統(tǒng)來(lái)說(shuō)都是非常有挑戰(zhàn)的。
Kubernetes 在 1.3 版本推出了 Petset ,現(xiàn)在已經(jīng)改名叫 StatefulSet, 核心思想是給 Pod 賦予身份,并且建立和維護(hù) Pod 和 存儲(chǔ)之間的聯(lián)系。當(dāng) Pod 可能被調(diào)度的時(shí)候,對(duì)應(yīng)的 Persistent Volume 能夠跟隨他綁定。但是它并沒(méi)有完全解決我們的問(wèn)題,PS 仍然需要依賴于 Persistent Volume,目前 Kubernetes 的 Persistent Volume 只提供了基于共享存儲(chǔ),分布式文件系統(tǒng)或者 NFS 的實(shí)現(xiàn),還沒(méi)有提供 Local Storage 的支持,而且 Petset 本身還處于 Alpha 版本階段,我們還在觀望。
不過(guò)除了 Kubernetes 官方社區(qū)還是有其他人在嘗試,我們欣喜的看到,就在不久之前,CoreOS 提出了一個(gè)新的擴(kuò)展 Kubernetes 的新方法和思路。CoreOS 為 Kubernetes 增加了一個(gè)新成員,叫作 Operator。Operator 其實(shí)是一種對(duì) Controller 的擴(kuò)展,具體的實(shí)現(xiàn)由于篇幅的原因我就不羅嗦了,簡(jiǎn)單來(lái)說(shuō)是一個(gè)讓 Kubernetes 調(diào)度帶狀態(tài)的存儲(chǔ)服務(wù)的方案,CoreOS 官方給出了一個(gè) Etcd-cluster 的備份和滾動(dòng)升級(jí)的 operator 實(shí)現(xiàn),我們也在開(kāi)發(fā) TiDB 的 operator, 感興趣的可以關(guān)注我們的 Github 及微信公眾號(hào)了解最新的進(jìn)展。
作者介紹
黃東旭,PingCAP 聯(lián)合創(chuàng)始人/CTO, 資深 infrastructure 工程師,擅長(zhǎng)分布式存儲(chǔ)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn),開(kāi)源狂熱分子,著名的開(kāi)源分布式緩存服務(wù) Codis 的作者,對(duì)于開(kāi)源文化和技術(shù)社區(qū)建設(shè)有獨(dú)到的理解。