數(shù)據(jù)庫作為業(yè)務(wù)的核心,在整個基礎(chǔ)軟件棧中是非常重要的一環(huán)。近幾年社區(qū)也是新的方案和思想層出不窮,接下來我將總結(jié)一下近幾年一些主流的開源數(shù)據(jù)庫方案,其背后的設(shè)計思想以及適用場景。本人才疏學(xué)淺如有遺漏或者錯誤請見諒。本次分享聚焦于數(shù)據(jù)庫既結(jié)構(gòu)化數(shù)據(jù)存儲OLTP及NoSQL領(lǐng)域,不會涉及OLAP、對象存儲、分布式文件系統(tǒng)。
很長時間以來,關(guān)系型數(shù)據(jù)庫一直是大公司的專利,市場被Oracle/DB2等企業(yè)數(shù)據(jù)庫牢牢把持。但是隨著互聯(lián)網(wǎng)的崛起、開源社區(qū)的發(fā)展,上世紀(jì)九十年代MySQL1.0的發(fā)布,標(biāo)志著關(guān)系型數(shù)據(jù)庫的領(lǐng)域社區(qū)終于有可選擇的方案。
第一個介紹的單機RDBMS就是MySQL。相信大多數(shù)朋友都已經(jīng)對MySQL非常熟悉,基本上MySQL的成長史就是互聯(lián)網(wǎng)的成長史。我接觸的第一個MySQL版本是MySQL4.0,到后來的MySQL5.5更是經(jīng)典——基本所有的互聯(lián)網(wǎng)公司都在使用。
MySQL也普及了「可插拔」引擎這一概念,針對不同的業(yè)務(wù)場景選用不同的存儲引擎是MySQLtuning的一個重要的方式。比如對于有事務(wù)需求的場景使用InnoDB:對于并發(fā)讀取的場景MyISAM可能比較合適:但是現(xiàn)在我推薦絕大多數(shù)情況還是使用InnoDB,畢竟5.6后已經(jīng)成為了官方的默認(rèn)引擎。大多數(shù)朋友都基本知道什么場景適用MySQL(幾乎所有需要持久化結(jié)構(gòu)化數(shù)據(jù)的場景),我就不贅述了。
另外值得一提的是MySQL5.6中引入了多線程復(fù)制和GTID,使得故障恢復(fù)和主從的運維變得比較方便。另外,5.7(目前處于GA版本)是MySQL的一個重大更新,主要是讀寫性能和復(fù)制性能上有了長足的進(jìn)步(在5.6版本中實現(xiàn)了SCHEMA級別的并行復(fù)制,不過意義不大,倒是MariaDB的多線程并行復(fù)制大放異彩,有不少人因為這個特性選擇MariaDB。MySQL5.7MTS支持兩種模式,一種是和5.6一樣,另一種則是基于binloggroupcommit實現(xiàn)的多線程復(fù)制,也就是MASTER上同時提交的binlog在SLAVE端也可以同時被apply,實現(xiàn)并行復(fù)制)。
如果有單機數(shù)據(jù)庫技術(shù)選型的朋友,基本上只需要考慮5.7或者M(jìn)ariaDB就好了,而且5.6、5.7由Oracle接手后,性能和穩(wěn)定性上都有了明顯的提升。
PostgreSQL的歷史也非常悠久,其前身是UCB的Ingres,主持這個項目的MichaelStronebraker于2015年獲得圖靈獎。后來項目更名為Post-Ingres,項目基于BSDlicense下開源。1995年幾個UCB的學(xué)生為Post-Ingres開發(fā)了SQL的接口,正式發(fā)布了PostgreSQL95,隨后一步步在開源社區(qū)中成長起來。
和MySQL一樣,PostgreSQL也是一個單機的關(guān)系型數(shù)據(jù)庫,但是與MySQL方便用戶過度擴(kuò)展的SQL文法不一樣的是,PostgreSQL的SQL支持非常強大,不管是內(nèi)置類型、JSON支持、GIS類型以及對于復(fù)雜查詢的支持,PL/SQL等都比MySQL強大得多。而且從代碼質(zhì)量上來看,PostgreSQL的代碼質(zhì)量是優(yōu)于MySQL的,另外PostgreSQL的SQL優(yōu)化器比MySQL強大很多,幾乎所有稍微復(fù)雜的查詢(當(dāng)然,我沒有對比MySQL5.7,也可能這個信息outdated了)PostgreSQL的表現(xiàn)都優(yōu)于MySQL。
從近幾年的趨勢上來看,PostgreSQL的勢頭也很強勁,我認(rèn)為PostgreSQL的不足之處在于沒有MySQL這樣強大的社區(qū)和群眾基礎(chǔ)。MySQL經(jīng)過那么多年的發(fā)展,積累了很多的運維工具和最佳實踐,但是PostgreSQL作為后起之秀,擁有更優(yōu)秀的設(shè)計和更豐富的功能。PostgreSQL9以后的版本也足夠穩(wěn)定,在做新項目技術(shù)選型的時候,是一個很好的選擇。另外也有很多新的數(shù)據(jù)庫項目是基于PostgreSQL源碼的基礎(chǔ)上進(jìn)行二次開發(fā),比如Greenplum等。
我認(rèn)為,單機數(shù)據(jù)庫的時代很快就會過去。榨取摩爾定律帶來的硬件紅利總是有上限的,現(xiàn)代業(yè)務(wù)的數(shù)據(jù)規(guī)模、流量以及現(xiàn)代的數(shù)據(jù)科學(xué)對于數(shù)據(jù)庫的要求單機已經(jīng)很難滿足。網(wǎng)卡磁盤IO和CPU總有瓶頸,線上敏感的業(yè)務(wù)系統(tǒng)可能還得承擔(dān)SPOF(單點故障)的風(fēng)險,主從復(fù)制模型在主掛掉時到底切還是不切?切了以后數(shù)據(jù)如何恢復(fù)?如果只是出現(xiàn)主從機器網(wǎng)絡(luò)分區(qū)問題呢?甚至是監(jiān)控環(huán)境出現(xiàn)網(wǎng)絡(luò)分區(qū)問題呢?這些都是問題。
所以我的觀點是,無論單機性能多棒(很多令人乍舌的評測數(shù)據(jù)都是針對特定場景的優(yōu)化,另外甚至有些都是本機不走網(wǎng)絡(luò),而大多數(shù)情況數(shù)據(jù)庫出現(xiàn)的第一個瓶頸其實是網(wǎng)卡和并發(fā)連接……),隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,移動互聯(lián)網(wǎng)的出現(xiàn)使得數(shù)據(jù)庫系統(tǒng)迎來了第一次分布式的洗禮。
Google應(yīng)該是第一個將分布式存儲技術(shù)應(yīng)用到大規(guī)模生產(chǎn)環(huán)境的公司,同時也是在分布式系統(tǒng)上積累最深的公司,可以說目前工業(yè)界的分布式系統(tǒng)的工程實踐及思想大都來源于Google。比如2003年的GFS開創(chuàng)了分布式文件系統(tǒng),2006年的Bigtable論文開創(chuàng)了分布式鍵值系統(tǒng),直接催生的就是Hadoop的生態(tài):至于2012年發(fā)表論文的Spanner和F1更是一個指明未來關(guān)系型數(shù)據(jù)庫發(fā)展方向的里程碑式的項目,這個我們后續(xù)會說。
另一個公司是Amazon。2007年發(fā)表的Dynamo的論文嘗試引入了最終一致性的概念,WRN的模型及向量時鐘的應(yīng)用,同時將一致性HASH、merkletree等當(dāng)時一些很新潮的技術(shù)整合起來,正式標(biāo)志著NoSQL的誕生——對后來業(yè)界的影響也是很大,包括后來的Cassandra、RiakDB、Voldemort等數(shù)據(jù)庫都是基于Dynamo的設(shè)計發(fā)展起來的。
另外這個時期(2006年前后持續(xù)至今)一個比較重要的思潮就是數(shù)據(jù)庫(持久化)和緩存開始有明確的分離——我覺得這個趨勢是從memcached開始的。隨著業(yè)務(wù)的并發(fā)越來越高,對于低延遲的要求也越來越高:另外一個原因是隨著內(nèi)存越來越便宜,基于內(nèi)存的存儲方案漸漸開始普及。當(dāng)然內(nèi)存緩存方案也經(jīng)歷了一個從單機到分布式的過程,但是這個過程相比關(guān)系型數(shù)據(jù)庫的進(jìn)化要快得多。
這是因為NoSQL的另外一個重要的標(biāo)志——數(shù)據(jù)模型的變化——大多NoSQL都拋棄了關(guān)系模型,選擇更簡單的鍵值或者文檔類型進(jìn)行存儲。數(shù)據(jù)結(jié)構(gòu)和查詢接口都相對簡單,沒有了SQL的包袱,實現(xiàn)的難度會降低很多。
另外NoSQL的設(shè)計幾乎都選擇犧牲掉復(fù)雜SQL的支持及ACID事務(wù)換取彈性擴(kuò)展能力,也是從當(dāng)時互聯(lián)網(wǎng)的實際情況出發(fā):業(yè)務(wù)模型簡單、爆發(fā)性增長帶來的海量并發(fā)及數(shù)據(jù)總量爆炸、歷史包袱小、工程師強悍,等。其中最重要的還是業(yè)務(wù)模型相對簡單。
在開始介紹具體的開源的完整方案前,我想介紹一下嵌入式存儲引擎?zhèn)儭?/div>
隨著NoSQL的發(fā)展,不僅僅緩存和持久化存儲開始細(xì)分,再往后的存儲引擎也開始分化并走上前臺。之前很難想象一個存儲引擎獨立于數(shù)據(jù)庫直接對外提供服務(wù),就像你不會直接拿著InnoDB或者M(jìn)yISAM甚至一個B-tree出來用一樣(當(dāng)然,bdb這樣鼎鼎大名的除外)。人們基于這些開源的存儲引擎進(jìn)行進(jìn)一步的封裝,比如加上網(wǎng)絡(luò)協(xié)議層、加上復(fù)制機制等等,一步步構(gòu)建出完整的風(fēng)格各異的NoSQL產(chǎn)品。
這里我挑選幾個比較著名存儲引擎介紹一下。
TC
我最早接觸的是TokyoCabinet(TC)。TC相信很多人也都聽說過,TC是由日本最大的社交網(wǎng)站Mixi開發(fā)并開源的一個混合Key-Value存儲引擎,其中包括HASHTable和B+Tree的實現(xiàn)。但是這個引擎的一個缺陷是隨著數(shù)據(jù)量的膨脹,性能的下降會非常明顯,而且現(xiàn)在也基本不怎么維護(hù)了,所以入坑請慎重。于TC配合使用的TokyoTyrant(TT)是一個網(wǎng)絡(luò)庫,為TC提供網(wǎng)絡(luò)的接口使其變成一個數(shù)據(jù)庫服務(wù),TT+TC應(yīng)該是比較早的NoSQL的一個嘗試。
LevelDB
在2011年,Google開源了Bigtable的底層存儲擎:LevelDB。LevelDB是一個使用C++開發(fā)的嵌入式的Key-Value存儲引擎,數(shù)據(jù)結(jié)構(gòu)采用了LSM-Tree,具體LSM-Tree的算法分析可以很容易在網(wǎng)上搜索到,我就不贅述了。其特點是,對于寫入極其友好,LSM的設(shè)計避免了大量的隨機寫入:對于特定的讀也能達(dá)到不錯的性能(熱數(shù)據(jù)在內(nèi)存中):另外LSM-Tree和B-tree一樣是支持有序Scan的:而且LevelDB是出自JeffDean之手,他的事跡做分布式系統(tǒng)的朋友一定都知道,不知道的可以去Google搜一下。
LevelDB擁有極好的寫性能,線程安全,BaTChWrite和Snapshot等特性,使其很容易的在上層構(gòu)建MVCC系統(tǒng)或者事務(wù)模型,對于數(shù)據(jù)庫來說非常重要。
另外值得一說的是,F(xiàn)acebook維護(hù)了一個活躍的LevelDB的分支,名為RocksDB。RocksDB在LevelDB上做了很多的改進(jìn),比如多線程Compactor、分層自定義壓縮、多MemTable等。另外RocksDB對外暴露了很多Configration,可以根據(jù)不同業(yè)務(wù)的形態(tài)進(jìn)行調(diào)優(yōu):同時Facebook在內(nèi)部正在用RocksDB來實現(xiàn)一個全新的MySQL存儲引擎:MyRocks,值得關(guān)注。RocksDB的社區(qū)響應(yīng)速度很快也很友好,實際上PingCAP也是RocksDB的社區(qū)貢獻(xiàn)者。我建議新的項目如果在LevelDB和RocksDB之間糾結(jié)的話,請果斷選擇RocksDB。
B-tree家族
當(dāng)然,除了LSM-Tree外,B-tree的家族也還是有很多不錯的引擎。首先大多數(shù)傳統(tǒng)的單機數(shù)據(jù)庫的存儲引擎都選擇了B+Tree,B+Tree對磁盤的讀比較友好,第三方存儲引擎比較著名的純B+Tree實現(xiàn)是LMDB。首先LMDB選擇在內(nèi)存映像文件(mmap)實現(xiàn)B+Tree,同時使用了Copy-On-Write實現(xiàn)了MVCC實現(xiàn)并發(fā)事務(wù)無鎖讀的能力,對于高并發(fā)讀的場景比較友好:同時因為使用的是mmap所以擁有跨進(jìn)程讀取的能力。因為我并沒有在生產(chǎn)環(huán)境中使用過LMDB,所以并不能給出LMDB的一些缺陷,見諒。
混合引擎
還有一部分的存儲引擎選擇了多種引擎混合,比如最著名的應(yīng)該是WiredTiger,大概是去年被MongoDB收購,現(xiàn)在成為了MongoDB的默認(rèn)存儲引擎。WiredTiger內(nèi)部有LSM-Tree和B-tree兩種實現(xiàn)提供一套接口,根據(jù)業(yè)務(wù)的情況可自由選擇。另外一些特殊數(shù)據(jù)結(jié)構(gòu)的存儲引擎在某些特殊場合下非常搶眼,比如極高壓縮比TokuDB,采用了名為分形樹的數(shù)據(jù)結(jié)構(gòu),在維持一個可接受的讀寫壓力的情況下,能擁有10倍以上的壓縮率。
NoSQL
說完了幾個比較著名的存儲引擎,我們來講講比較著名的NoSQL。在我的定義中,NoSQL是NotOnlySQL的縮寫,所以可能包含的范圍有內(nèi)存數(shù)據(jù)庫,持久化數(shù)據(jù)庫等。總之就是和單機的關(guān)系型數(shù)據(jù)庫不一樣的結(jié)構(gòu)化數(shù)據(jù)存儲系統(tǒng)。
我們先從緩存開始。
memcached
前面提到了memcached應(yīng)該是第一個大規(guī)模在業(yè)界使用的緩存數(shù)據(jù)庫,memcached的實現(xiàn)極其簡單,相當(dāng)于將內(nèi)存用作大的HASHTable,只能在上面get/set/計數(shù)器等操作,在此之上用libevent封裝了一層網(wǎng)絡(luò)層和文本協(xié)議(也有簡單的二進(jìn)制協(xié)議),雖然支持一些CAS的操作,但是總體上來看,還是非常簡單的。
但是memcached的內(nèi)存利用率并不太高,這個因為memcached為了避免頻繁申請內(nèi)存導(dǎo)致的內(nèi)存碎片的問題,采用了自己實現(xiàn)的slaballocator的方式。即內(nèi)存的分配都是一塊一塊的,最終存儲在固定長度的chunk上,內(nèi)存最小的分配單元是chunk,另外libevent的性能也并沒有優(yōu)化到極致,但是不妨礙memcached成為當(dāng)時的開源緩存事實標(biāo)準(zhǔn)(另外,八卦一下,memcached的作者BradFitzpatrick,現(xiàn)在在Google,大家如果用Golang的話,Go的官方HTTP包就是這哥們寫的,是個很高產(chǎn)的工程師)。
Redis
如果我沒記錯的話,在2009年前后,一位意大利的工程師Antirez,開源了Redis。從此徹底顛覆了緩存的市場,到現(xiàn)在大多數(shù)緩存的業(yè)務(wù)都已用上Redis,memcached基本退出了歷史舞臺。Redis最大的特點是擁有豐富的數(shù)據(jù)結(jié)構(gòu)支持,不僅僅是簡單的Key-Value,包括隊列、集合、SortedSet等等,提供了非常豐富的表達(dá)力,而且Redis還提供sub/pub等超出數(shù)據(jù)庫范疇的便捷功能,使得幾乎一夜之間大家紛紛投入Redis的懷抱。
Twemproxy
但是隨著Redis漸漸的普及,而且越用越狠,另外內(nèi)存也越來越便宜,人們開始尋求擴(kuò)展單機Redis的方案,最早的嘗試是twitter開源的twemproxy,twemproxy是一個Redis中間件,基本只有最簡單的數(shù)據(jù)路由功能,并沒有動態(tài)的伸縮能力,但是還是受到了很多公司的追捧,因為確實沒方案。隨后的RedisCluster也是難產(chǎn)了好久,時隔好幾年,中間出了7個RC版本,最后才發(fā)布:
2014年底,我們開源了Codis,解決了Redis中間件的數(shù)據(jù)彈性伸縮問題,目前廣泛應(yīng)用于國內(nèi)各大互聯(lián)網(wǎng)公司中,這個在網(wǎng)上也有很多文章介紹,我也就不展開了。所以在緩存上面,開源社區(qū)現(xiàn)在倒是非常統(tǒng)一,就是Redis極其周邊的擴(kuò)展方案。
MongoDB
在NoSQL的大家庭中,MongoDB其實是一個異類,大多NoSQL舍棄掉SQL是為了追求更極致的性能和可擴(kuò)展能力,而MongoDB主動選擇了文檔作為對外的接口,非常像JSON的格式。Schema-less的特性對于很多輕量級業(yè)務(wù)和快速變更了互聯(lián)網(wǎng)業(yè)務(wù)意義很大,而且MongoDB的易用性很好,基本做到了開箱即用,開發(fā)者不需要費心研究數(shù)據(jù)的表結(jié)構(gòu),只需要往里存就好了,這確實籠絡(luò)了一大批開發(fā)者。
盡管MongoDB早期的版本各種不穩(wěn)定,性能也不太好(早期的Mongo并沒有存儲引擎,直接使用了mmap文件),集群模式還全是問題(比如至今還未解決的Cluster同步帶寬占用過多的問題),但是因為確實太方便了,在早期的項目快速迭代中,Mongo是一個不錯的選擇。
但是這也正是它的問題,我不止一次聽到當(dāng)項目變得龐大或者「嚴(yán)肅」的時候,團(tuán)隊最后還是回歸了關(guān)系型數(shù)據(jù)庫。Anyway,在2014年底MongoDB收購了WiredTiger后,在2.8版本中正式亮相,同時3.0版本后更是作為默認(rèn)存儲引擎提供,性能和穩(wěn)定性有了非常大的提升。
但是,從另一方面講,Schema-less到底對軟件工程是好事還是壞事這個問題還是有待商榷。我個人是站在Schema這邊的,不過在一些小項目或者需要快速開發(fā)的項目中使用Mongo確實能提升很多的開發(fā)效率,這是毋庸置疑的。
HBase
說到NoSQL不得不提的是HBase,HBase作為Hadoop旗下的重要產(chǎn)品,GoogleBigtable的正統(tǒng)開源實現(xiàn),是不是有一種欽定的感覺:)。提到HBase就不得不提一下Bigtable,Bigtable是Google內(nèi)部廣泛使用的分布式數(shù)據(jù)庫,接口也不是簡單的Key-Value,按照論文的說法叫:multi-dimensionalsortedmap,也就是Value是按照列劃分的。Bigtable構(gòu)建在GFS之上,彌補了分布式文件系統(tǒng)對于海量、小的、結(jié)構(gòu)化數(shù)據(jù)的插入、更新、隨機讀請求的缺陷。
HBase就是這么一個系統(tǒng)的實現(xiàn),底層依賴HDFS。HBase本身并不實際存儲數(shù)據(jù),持久化的日志和SSTfile(HBase也是LSM-Tree的結(jié)構(gòu))直接存儲在HDFS上,RegionServer(RS)維護(hù)了MemTable以提供快速的查詢,寫入都是寫日志,后臺進(jìn)行Compact,避免了直接隨機讀寫HDFS。
數(shù)據(jù)通過Region在邏輯上進(jìn)行分割,負(fù)載均衡通過調(diào)節(jié)各個RegionServer負(fù)責(zé)的Region區(qū)間實現(xiàn)。當(dāng)某Region太大時,這個Region會分裂,后續(xù)可能由不同的RS負(fù)責(zé),但是前面提到了,HBase本身并不存儲數(shù)據(jù),這里的Region僅是邏輯上的,數(shù)據(jù)還是以文件的形式存儲在HDFS上,所以HBase并不關(guān)心Replication、水平擴(kuò)展和數(shù)據(jù)的分布,統(tǒng)統(tǒng)交給HDFS解決。
和Bigtable一樣,HBase提供行級的一致性,嚴(yán)格來說在CAP理論中它是一個CP的系統(tǒng),但遺憾的是并沒有更進(jìn)一步提供ACID的跨行事務(wù)。HBase的好處就不用說了,顯而易見,通過擴(kuò)展RS可以幾乎線性提升系統(tǒng)的吞吐,及HDFS本身就具有的水平擴(kuò)展能力。
但是缺點仍然是有的。
首先,Hadoop的軟件棧是Java,JVM的GCTuning是一個非常煩人的事情,即使已經(jīng)調(diào)得很好了,平均延遲也得幾十毫秒:
另外在架構(gòu)設(shè)計上,HBase本身并不存儲數(shù)據(jù),所以可能造成客戶端請求的RS并不知道數(shù)據(jù)到底存在哪臺HDFSDataNode上,憑空多了一次RPC:
第三,HBase和Bigtable一樣,并不支持跨行事務(wù),在Google內(nèi)部不停的有團(tuán)隊基于Bigtable來做分布式事務(wù)的支持,比如MegaStore、Percolator。后來JeffDean有次接受采訪也提到非常后悔沒有在Bigtable中加入跨行事務(wù),不過還好這個遺憾在Spanner中得到了彌補,這個一會兒說。
總體來說,HBase還是一個非常健壯且久經(jīng)考驗的系統(tǒng),但是需要你有對于Java和Hadoop比較深入的了解后,才能玩轉(zhuǎn),這也是Hadoop生態(tài)的一個問題,易用性真是不是太好,而且社區(qū)演進(jìn)速度相對緩慢,也是因為歷史包袱過重的緣故吧。
Cassandra
提到Cassandra(C*),雖然也是Dynamo的開源實現(xiàn),但就沒有這種欽定的感覺了。C*確實命途多舛,最早2008由Facebook開發(fā)并開源,早期的C*幾乎全是bug,F(xiàn)acebook后來索性也不再維護(hù)轉(zhuǎn)過頭搞HBase去了,一個爛攤子直接丟給社區(qū)。還好DataStax把這個項目撿起來商業(yè)化,搞了兩年,終于漸漸開始流行起來。
C*不能簡單的歸納為讀快寫慢,或者讀慢寫快,因為采用了qourm的模型,調(diào)整復(fù)制的副本數(shù)以及讀的數(shù)量,可以達(dá)到不同的效果,對于一致性不是特別高的場景,可以選擇只從一個節(jié)點讀取數(shù)據(jù),達(dá)到最高的讀性能。另外C*并不依賴分布式文件系統(tǒng),數(shù)據(jù)直接存儲在磁盤上,各個存儲節(jié)點之間自己維護(hù)復(fù)制關(guān)系,減少了一層RPC調(diào)用,延遲上對比HBase還是有一定優(yōu)勢的。
不過即使使用qourm的模型也并不代表C*是一個強一致的系統(tǒng)。C*并不幫你解決沖突,即使你W(寫的副本數(shù))+R(讀請求的副本數(shù))>N(節(jié)點總數(shù)),C*也沒辦法幫你決定哪些副本擁有更新的版本,因為每個數(shù)據(jù)的版本是一個NTP的時間戳或者客戶端自行提供,每臺機器可能都有誤差,所以有可能并不準(zhǔn)確,這也就是為什么C*是一個AP的系統(tǒng)。不過C*一個比較友好的地方是提供了CQL,一個簡單的SQL方言,比起HBase在易用性上有明顯優(yōu)勢。
即使作為一個AP系統(tǒng),C*已經(jīng)挺快了,但是人們追求更高性能的腳步還是不會停止。應(yīng)該是今年年初,ScyllaDB的發(fā)布就是典型的證明,ScyllaDB是一個兼容C*的NoSQL數(shù)據(jù)庫,不一樣的是,ScyllaDB完全用C++開發(fā),同時使用了類似DPDK這樣的黑科技,具體我就不展開了,有興趣可以到Scylla的官網(wǎng)去看看。BTW,國內(nèi)的蘑菇街第一時間使用了ScyllaDB,同時在Scylla的官網(wǎng)上share了他們的方案,性能還是很不錯的。
3、中間件與分庫分表
NoSQL就先介紹到這里,接下來我想說的是一些在基于單機關(guān)系型數(shù)據(jù)庫之上的中間件和分庫分表方案。
在這方面確實歷史悠久,而且也是沒有辦法的選擇,關(guān)系型數(shù)據(jù)庫不比Redis,并不是簡單的寫一個類似Twemproxy的中間件就搞定了。數(shù)據(jù)庫的中間件需要考慮很多,比如解析SQL,解析出shardingkey,然后根據(jù)shardingkey分發(fā)請求,再合并:另外數(shù)據(jù)庫有事務(wù),在中間件這層還需要維護(hù)Session及事務(wù)狀態(tài),而且大多數(shù)方案并沒有辦法支持跨shard的事務(wù)。
這就不可避免的導(dǎo)致了業(yè)務(wù)使用起來會比較麻煩,需要重寫代碼,而且會增加邏輯的復(fù)雜度,更別提動態(tài)的擴(kuò)容縮容和自動的故障恢復(fù)了。在集群規(guī)模越來越大的情況下,運維和DDL的復(fù)雜度是指數(shù)級上升的。
中間件項目盤點
數(shù)據(jù)庫中間件最早的項目大概是MySQLProxy,用于實現(xiàn)讀寫分離。后來國人在這個領(lǐng)域有過很多的著名的開源項目,比如阿里的Cobar和DDL(并未完全開源:后來社區(qū)基于Cobar改進(jìn)的MyCAT、360開源的Atlas等,都屬于這一類中間件產(chǎn)品:
在中間件這個方案上基本走到頭的開源項目應(yīng)該是YoutubeVitesse。Vitess基本上是一個集大成的中間件產(chǎn)品,內(nèi)置了熱數(shù)據(jù)緩存、水平動態(tài)分片、讀寫分離等等,但是代價也是整個項目非常復(fù)雜,另外文檔也不太好。大概1年多以前,我們嘗試搭建起完整的Vitess集群,但是并未成功,可見其復(fù)雜度。
另外一個值得一提的是Postgres-XC這個項目,Postgres-XC的野心還是很大的,整體的架構(gòu)有點像早期版本的OceanBase,由一個中央節(jié)點來處理協(xié)調(diào)分布式事務(wù)/解決沖突,數(shù)據(jù)分散在各個存儲節(jié)點上,應(yīng)該是目前PostgreSQL社區(qū)最好的分布式擴(kuò)展方案。其他的就不提了。
4、未來在哪里?NewSQL?
一句話,NewSQL是未來。
2012年Google在OSDI上發(fā)表了Spanner的論文,2013年在SIGMOD發(fā)表了F1的論文。這兩篇論文讓業(yè)界第一次看到了關(guān)系模型和NoSQL的擴(kuò)展性在超龐大集群規(guī)模上融合的可能性。在此之前,大家普遍認(rèn)為這個是不可能的,即使是Google也經(jīng)歷了Megastore這樣系統(tǒng)的失敗。
Spanner綜述
但是Spanner的創(chuàng)新之處在于通過硬件(GPS時鐘+原子鐘)來解決時鐘同步的問題。在分布式系統(tǒng)里,時鐘是最讓人頭痛的問題,剛才提到了C*為什么不是一個強C的系統(tǒng),正是因為時鐘的問題。而Spanner的厲害之處在于即使兩個數(shù)據(jù)中心隔得非常遠(yuǎn),不需要有通信(因為通信的代價太大,最快也就是光速)就能保證TrueTimeAPI的時鐘誤差在一個很小的范圍內(nèi)(10ms)。另外Spanner沿用了很多Bigtable的設(shè)計,比如Tablet/Directory等,同時在Replica這層使用Paxos復(fù)制,并未完全依賴底層的分布式文件系統(tǒng)。但是Spanner的設(shè)計底層仍然沿用了Colossus,不過論文里也說是可以未來改進(jìn)的點。
Google的內(nèi)部的數(shù)據(jù)庫存儲業(yè)務(wù),大多是3~5副本,重要一點的7副本,遍布全球各大洲的數(shù)據(jù)中心,由于普遍使用了Paxos,延遲是可以縮短到一個可以接受的范圍(Google的風(fēng)格一向是追求吞吐的水平擴(kuò)展而不是低延遲,從悲觀鎖的選擇也能看得出來,因為跨數(shù)據(jù)中心復(fù)制是必選的,延遲不可能低,對于低延遲的場景,業(yè)務(wù)層自己解決或者依賴緩存)。
另外由Paxos帶來的Auto-Failover能力,更是能讓整個集群即使數(shù)據(jù)中心癱瘓,業(yè)務(wù)層都是透明無感知的。另外F1構(gòu)建在Spanner之上,對外提供了更豐富的SQL語法支持,F(xiàn)1更像一個分布式MPPSQL——F1本身并不存儲數(shù)據(jù),而是將客戶端的SQL翻譯成類似MapReduce的任務(wù),調(diào)用Spanner來完成請求。
其實除了TrueTime整個系統(tǒng)并沒有用什么全新的算法,而是近些年分布式系統(tǒng)的技術(shù)Spanner和F1的出現(xiàn)標(biāo)志著第一個NewSQL在生產(chǎn)環(huán)境中提供服務(wù)。
有以下幾個重點:
1.完整的SQL支持,ACID事務(wù):
2.彈性伸縮能力:
3.自動的故障轉(zhuǎn)移和故障恢復(fù),多機房異地災(zāi)備。
NewSQL特性確實非常誘人,在Google內(nèi)部,大量的業(yè)務(wù)已經(jīng)從原來的Bigtable切換到Spanner之上。我相信未來幾年,整個業(yè)界的趨勢也是如此,就像當(dāng)年的Hadoop一樣,Google的基礎(chǔ)軟件的技術(shù)趨勢是走在社區(qū)前面的。
社區(qū)反應(yīng)
Spanner的論文發(fā)表之后,當(dāng)然也有社區(qū)的追隨者開始實現(xiàn)(比如我們:D),第一個團(tuán)隊是在紐約的Cockr
OAchDB。CockroachDB的團(tuán)隊的組成還是非常豪華的,早期團(tuán)隊由是Google的分布式文件系統(tǒng)Colossus團(tuán)隊的成員組成:技術(shù)上來說,Cockroach的設(shè)計和Spanner很像,不一樣的地方是沒有選擇TrueTime而是HLC(Hybridlogicalclock),也就是NTP+邏輯時鐘來代替TrueTime時間戳:另外Cockroach選用了Raft代替Paxos實現(xiàn)復(fù)制和自動容災(zāi),底層存儲依賴RocksDB實現(xiàn),整個項目使用Go語言開發(fā),對外接口選用PostgreSQL的SQL子集。
CockroachDB
CockroachDB的技術(shù)選型比較激進(jìn),比如依賴了HLC來做事務(wù)的時間戳。但是在Spanner的事務(wù)模型的CommitWait階段等待時間的選擇,CockroachDB并沒有辦法做到10ms內(nèi)的延遲:CockroachDB的CommitWait需要用戶自己指定,但是誰能拍胸脯說NTP的時鐘誤差在多少毫秒內(nèi)?我個人認(rèn)為在處理跨洲際機房時鐘同步的問題上,基本只有硬件時鐘一種辦法。HLC是沒辦法解決的。
另外Cockroach采用了gossip來同步節(jié)點信息,當(dāng)集群變得比較大的時候,gossip心跳會是一個非常大的開銷。當(dāng)然CockroachDB的這些技術(shù)選擇帶來的優(yōu)勢就是非常好的易用性,所有邏輯都在一個binary中,開箱即用,這個是非常大的優(yōu)點。
TiDB
目前從全球范圍來看,另一個在朝著Spanner/F1的開源實現(xiàn)這個目標(biāo)上走的產(chǎn)品是TiDB(終于談到我們的產(chǎn)品了)。TiDB本質(zhì)上是一個更加正統(tǒng)的Spanner和F1實現(xiàn),并不像CockroachDB那樣選擇將SQL和Key-Value融合,而是像Spanner和F1一樣選擇分離,這樣分層的思想也是貫穿整個TiDB項目始終的。對于測試、滾動升級以及各層的復(fù)雜度控制會比較有優(yōu)勢:另外TiDB選擇了MySQL協(xié)議和語法的兼容,MySQL社區(qū)的ORM框架,運維工具,直接可以應(yīng)用在TiDB上。
和Spanner一樣,TiDB是一個無狀態(tài)的MPPSQLLayer,整個系統(tǒng)的底層是依賴TiKey-Value來提供分布式存儲和分布式事務(wù)的支持。TiKey-Value的分布式事務(wù)模型采用的是GooglePercolator的模型,但是在此之上做了很多優(yōu)化。Percolator的優(yōu)點是去中心化程度非常高,整個集群不需要一個獨立的事務(wù)管理模塊,事務(wù)提交狀態(tài)這些信息其實是均勻分散在系統(tǒng)的各個Key的meta中,整個模型唯一依賴的是一個授時服務(wù)器。
在我們的系統(tǒng)上,極限情況這個授時服務(wù)器每秒能分配400w以上個單調(diào)遞增的時間戳,大多數(shù)情況基本夠用了(畢竟有Google量級的場景并不多見):同時在TiKey-Value中,這個授時服務(wù)本身是高可用的,也不存在單點故障的問題。
TiKey-Value和CockroachDB一樣也是選擇了Raft作為整個數(shù)據(jù)庫的基礎(chǔ):不一樣的是,TiKey-Value整體采用Rust語言開發(fā),作為一個沒有GC和Runtime的語言,在性能上可以挖掘的潛力會更大。
關(guān)于未來
我覺得未來的數(shù)據(jù)庫會有幾個趨勢,也是TiDB項目追求的目標(biāo):
數(shù)據(jù)庫會隨著業(yè)務(wù)云化,未來一切的業(yè)務(wù)都會跑在云端,不管是私有云或者公有云,運維團(tuán)隊接觸的可能再也不是真實的物理機,而是一個個隔離的容器或者「計算資源」。這對數(shù)據(jù)庫也是一個挑戰(zhàn),因為數(shù)據(jù)庫天生就是有狀態(tài)的,數(shù)據(jù)總是要存儲在物理的磁盤上,而數(shù)據(jù)的移動的代價比移動容器的代價可能大很多。
多租戶技術(shù)會成為標(biāo)配,一個大數(shù)據(jù)庫承載一切的業(yè)務(wù),數(shù)據(jù)在底層打通,上層通過權(quán)限,容器等技術(shù)進(jìn)行隔離:但是數(shù)據(jù)的打通和擴(kuò)展會變得異常簡單,結(jié)合第一點提到的云化,業(yè)務(wù)層可以再也不用關(guān)心物理機的容量和拓?fù)洌恍枰J(rèn)為底層是一個無窮大的數(shù)據(jù)庫平臺即可,不用再擔(dān)心單機容量和負(fù)載均衡等問題。
OLAP和OLTP會進(jìn)一步細(xì)分,底層存儲也許會共享一套,但是SQL優(yōu)化器這層的實現(xiàn)一定是千差萬別的。對于用戶而言,如果能使用同一套標(biāo)準(zhǔn)的語法和規(guī)則來進(jìn)行數(shù)據(jù)的讀寫和分析,會有更好的體驗。
在未來分布式數(shù)據(jù)庫系統(tǒng)上,主從日志同步這樣落后的備份方式會被Multi-Paxos/Raft這樣更強的分布式一致性算法替代,人工的數(shù)據(jù)庫運維在管理大規(guī)模數(shù)據(jù)庫集群時是不可能的,所有的故障恢復(fù)和高可用都會是高度自動化的。
5、答疑環(huán)節(jié)
問:HANA等內(nèi)存數(shù)據(jù)庫怎么保證系統(tǒng)掉電而處理結(jié)果不丟?傳統(tǒng)數(shù)據(jù)庫也用緩存,可是HANA用的內(nèi)存太大。
黃東旭:沒用過HANA,但是直觀感覺這類內(nèi)存數(shù)據(jù)庫的可用性可能通過集中方式保證:
寫入會先寫WAL:
寫入可能會通過主從或者paxos之類的算法做同步和冗余復(fù)制還有HANA本身就是內(nèi)存數(shù)據(jù)庫,會盡可能把數(shù)據(jù)放到內(nèi)存里,這樣查詢才能快呀。
問:對于傳統(tǒng)創(chuàng)業(yè)公司如何彌補NoSQL的技術(shù)短板?快速的引入NoSQL提高效率?
黃東旭:選用NoSQL主要注意兩點:
做好業(yè)務(wù)的調(diào)研,估計并發(fā)量,數(shù)據(jù)量,數(shù)據(jù)的結(jié)構(gòu)看看適不適合:
對各種NoSQL擅長和不擅長的地方都盡可能了解。
不要盲目相信關(guān)系型數(shù)據(jù)庫,也不要盲目相信NoSQL,沒有銀彈的。
問:有多個條件,比如年齡20到30或年齡35到40,并且加入購物車或下單,這種數(shù)據(jù)怎么存儲?
黃東旭:購物車這種場景是典型的OLTP的場景,可以選用關(guān)系型數(shù)據(jù)庫MySQLPostgreSQL什么的,如果對于擴(kuò)展性的數(shù)據(jù)跨機房有要求的話,可以調(diào)研一下NewSQL,比如我們的TiDB。
問:多緯度查詢應(yīng)該選擇哪種數(shù)據(jù)庫?
黃東旭:多緯度查詢可以說是一個OLAP的場景,可以選用Greenplum或者Vertica之類的分析性數(shù)據(jù)庫。
問:想知道為什么需要這些開源的數(shù)據(jù)庫,既然已經(jīng)有了MySQL、DB2、Oracle這些成熟的數(shù)據(jù)庫,成本考慮,還是傳統(tǒng)數(shù)據(jù)庫滿足不了需求?
黃東旭:對,傳統(tǒng)數(shù)據(jù)庫的擴(kuò)展性是有問題的,在海量并發(fā)和數(shù)據(jù)量的場景下很難支持業(yè)務(wù)。所以可以看到比較大的互聯(lián)網(wǎng)公司基本都有自己的分布式數(shù)據(jù)庫方案。
黃東旭:大家可以想想數(shù)據(jù)倉庫的定義,如果是還需要離線的從線上庫倒騰數(shù)據(jù)到數(shù)據(jù)倉庫上,這樣很難做到實時查詢,而且空間的利用率也低,我認(rèn)為是目前并沒有太好的方案的情況下的折衷……
核心關(guān)注:拓步ERP系統(tǒng)平臺是覆蓋了眾多的業(yè)務(wù)領(lǐng)域、行業(yè)應(yīng)用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業(yè)務(wù)管理理念,功能涉及供應(yīng)鏈、成本、制造、CRM、HR等眾多業(yè)務(wù)領(lǐng)域的管理,全面涵蓋了企業(yè)關(guān)注ERP管理系統(tǒng)的核心領(lǐng)域,是眾多中小企業(yè)信息化建設(shè)首選的ERP管理軟件信賴品牌。
轉(zhuǎn)載請注明出處:拓步ERP資訊網(wǎng)http://www.guhuozai8.cn/
本文標(biāo)題:一文掌握所有開源數(shù)據(jù)庫的現(xiàn)狀
本文網(wǎng)址:http://www.guhuozai8.cn/html/support/11121519536.html