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