日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一篇文章,掌握所有開源數(shù)據(jù)庫的現(xiàn)狀

 

數(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)。

1

開源RDBMS與互聯(lián)網(wǎng)的崛起

很長時間以來,關(guān)系型數(shù)據(jù)庫一直是大公司的專利,市場被 Oracle / DB2 等企業(yè)數(shù)據(jù)庫牢牢把持。但是隨著互聯(lián)網(wǎng)的崛起、開源社區(qū)的發(fā)展,上世紀九十年代 MySQL 1.0 的發(fā)布,標志著關(guān)系型數(shù)據(jù)庫的領(lǐng)域社區(qū)終于有可選擇的方案。

MySQL

第一個介紹的單機RDBMS就是MySQL。相信大多數(shù)朋友都已經(jīng)對 MySQL 非常熟悉,基本上 MySQL 的成長史就是互聯(lián)網(wǎng)的成長史。我接觸的第一個 MySQL 版本是 MySQL 4.0,到后來的 MySQL 5.5 更是經(jīng)典——基本所有的互聯(lián)網(wǎng)公司都在使用。

MySQL 也普及了「可插拔」引擎這一概念,針對不同的業(yè)務(wù)場景選用不同的存儲引擎是 MySQL tuning 的一個重要的方式。比如對于有事務(wù)需求的場景使用 InnoDB;對于并發(fā)讀取的場景 MyISAM 可能比較合適;但是現(xiàn)在我推薦絕大多數(shù)情況還是使用 InnoDB,畢竟 5.6 后已經(jīng)成為了官方的默認引擎。大多數(shù)朋友都基本知道什么場景適用 MySQL(幾乎所有需要持久化結(jié)構(gòu)化數(shù)據(jù)的場景),我就不贅述了。

另外值得一提的是 MySQL 5.6中引入了多線程復(fù)制和 GTID,使得故障恢復(fù)和主從的運維變得比較方便。另外,5.7(目前處于 GA 版本) 是 MySQL 的一個重大更新,主要是讀寫性能和復(fù)制性能上有了長足的進步(在5.6版本中實現(xiàn)了SCHEMA級別的并行復(fù)制,不過意義不大,倒是MariaDB的多線程并行復(fù)制大放異彩,有不少人因為這個特性選擇MariaDB。MySQL 5.7 MTS支持兩種模式,一種是和5.6一樣,另一種則是基于binlog group commit實現(xiàn)的多線程復(fù)制,也就是MASTER上同時提交的binlog在SLAVE端也可以同時被Apply,實現(xiàn)并行復(fù)制)。

如果有單機數(shù)據(jù)庫技術(shù)選型的朋友,基本上只需要考慮 5.7 或者 MariaDB 就好了,而且 5.6、5.7 由 Oracle 接手后,性能和穩(wěn)定性上都有了明顯的提升。

PostgreSQL

PostgreSQL的歷史也非常悠久,其前身是UCB的Ingres,主持這個項目的 Michael Stronebraker 于 2015 年獲得圖靈獎。后來項目更名為 Post-Ingres,項目基于 BSD license 下開源。 1995 年幾個 UCB 的學(xué)生為 Post-Ingres 開發(fā)了 SQL 的接口,正式發(fā)布了 PostgreSQL95,隨后一步步在開源社區(qū)中成長起來。

和 MySQL 一樣,PostgreSQL 也是一個單機的關(guān)系型數(shù)據(jù)庫,但是與 MySQL 方便用戶過度擴展的 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)然,我沒有對比 MySQL 5.7,也可能這個信息 outdated 了)PostgreSQL 的表現(xiàn)都優(yōu)于 MySQL。

從近幾年的趨勢上來看,PostgreSQL 的勢頭也很強勁,我認為 PostgreSQL 的不足之處在于沒有 MySQL 這樣強大的社區(qū)和群眾基礎(chǔ)。MySQL 經(jīng)過那么多年的發(fā)展,積累了很多的運維工具和最佳實踐,但是 PostgreSQL 作為后起之秀,擁有更優(yōu)秀的設(shè)計和更豐富的功能。PostgreSQL 9 以后的版本也足夠穩(wěn)定,在做新項目技術(shù)選型的時候,是一個很好的選擇。另外也有很多新的數(shù)據(jù)庫項目是基于 PostgreSQL 源碼的基礎(chǔ)上進行二次開發(fā),比如Greenplum等。

我認為,單機數(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)迎來了第一次分布式的洗禮。

2

分布式時代:NoSQL的復(fù)興和模型簡化的力量

在介紹 NoSQL 之前,我想提兩個公司,一個是google,另一個是Amazon。

Google

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ù)會說。

一篇文章,掌握所有開源數(shù)據(jù)庫的現(xiàn)狀

 

Amazon

另一個公司是 Amazon。2007 年發(fā)表的Dynamo的論文嘗試引入了最終一致性的概念, WRN 的模型及向量時鐘的應(yīng)用,同時將一致性 HASH、merkle tree 等當(dāng)時一些很新潮的技術(shù)整合起來,正式標志著 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ù)庫的進化要快得多。

這是因為 NoSQL 的另外一個重要的標志——數(shù)據(jù)模型的變化——大多 NoSQL 都拋棄了關(guān)系模型,選擇更簡單的鍵值或者文檔類型進行存儲。數(shù)據(jù)結(jié)構(gòu)和查詢接口都相對簡單,沒有了SQL 的包袱,實現(xiàn)的難度會降低很多。

另外 NoSQL 的設(shè)計幾乎都選擇犧牲掉復(fù)雜 SQL 的支持及 ACID 事務(wù)換取彈性擴展能力,也是從當(dāng)時互聯(lián)網(wǎng)的實際情況出發(fā):業(yè)務(wù)模型簡單、爆發(fā)性增長帶來的海量并發(fā)及數(shù)據(jù)總量爆炸、歷史包袱小、工程師強悍,等。其中最重要的還是業(yè)務(wù)模型相對簡單。

嵌入式存儲引擎

在開始介紹具體的開源的完整方案前,我想介紹一下嵌入式存儲引擎?zhèn)儭?/p>

隨著 NoSQL 的發(fā)展,不僅僅緩存和持久化存儲開始細分,再往后的存儲引擎也開始分化并走上前臺。之前很難想象一個存儲引擎獨立于數(shù)據(jù)庫直接對外提供服務(wù),就像你不會直接拿著 InnoDB 或者 MyISAM甚至一個 B-tree 出來用一樣(當(dāng)然,bdb 這樣鼎鼎大名的除外)。人們基于這些開源的存儲引擎進行進一步的封裝,比如加上網(wǎng)絡(luò)協(xié)議層、加上復(fù)制機制等等,一步步構(gòu)建出完整的風(fēng)格各異的 NoSQL 產(chǎn)品。

這里我挑選幾個比較著名存儲引擎介紹一下。

TC

我最早接觸的是Tokyo Cabinet(TC)。TC 相信很多人也都聽說過,TC 是由日本最大的社交網(wǎng)站 Mixi 開發(fā)并開源的一個混合 Key-Value 存儲引擎,其中包括 HASH Table 和 B+ Tree 的實現(xiàn)。但是這個引擎的一個缺陷是隨著數(shù)據(jù)量的膨脹,性能的下降會非常明顯,而且現(xiàn)在也基本不怎么維護了,所以入坑請慎重。于 TC 配合使用的Tokyo Tyrant(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è)計避免了大量的隨機寫入;對于特定的讀也能達到不錯的性能(熱數(shù)據(jù)在內(nèi)存中);另外 LSM-Tree 和 B-tree 一樣是支持有序 Scan 的;而且 LevelDB 是出自 Jeff Dean 之手,他的事跡做分布式系統(tǒng)的朋友一定都知道,不知道的可以去 Google 搜一下。

LevelDB 擁有極好的寫性能,線程安全,BaTCh Write 和 Snapshot 等特性,使其很容易的在上層構(gòu)建 MVCC 系統(tǒng)或者事務(wù)模型,對于數(shù)據(jù)庫來說非常重要。

另外值得一說的是,F(xiàn)acebook 維護了一個活躍的 LevelDB 的分支,名為 RocksDB。RocksDB 在 LevelDB 上做了很多的改進,比如多線程 Compactor、分層自定義壓縮、多 MemTable 等。另外 RocksDB 對外暴露了很多 Configration ,可以根據(jù)不同業(yè)務(wù)的形態(tài)進行調(diào)優(yōu);同時 Facebook 在內(nèi)部正在用 RocksDB 來實現(xiàn)一個全新的 MySQL 存儲引擎:MyRocks,值得關(guān)注。RocksDB 的社區(qū)響應(yīng)速度很快也很友好,實際上 PingCAP 也是 RocksDB 的社區(qū)貢獻者。我建議新的項目如果在 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 所以擁有跨進程讀取的能力。因為我并沒有在生產(chǎn)環(huán)境中使用過 LMDB ,所以并不能給出 LMDB 的一些缺陷,見諒。

混合引擎

還有一部分的存儲引擎選擇了多種引擎混合,比如最著名的應(yīng)該是WiredTiger,大概是去年被 MongoDB 收購,現(xiàn)在成為了 MongoDB 的默認存儲引擎。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 是Not Only SQL 的縮寫,所以可能包含的范圍有內(nèi)存數(shù)據(jù)庫,持久化數(shù)據(jù)庫等??傊褪呛蛦螜C的關(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)存用作大的 HASH Table,只能在上面 get/set/ 計數(shù)器等操作,在此之上用 libevent 封裝了一層網(wǎng)絡(luò)層和文本協(xié)議(也有簡單的二進制協(xié)議),雖然支持一些 CAS 的操作,但是總體上來看,還是非常簡單的。

但是 memcached 的內(nèi)存利用率并不太高,這個因為 memcached 為了避免頻繁申請內(nèi)存導(dǎo)致的內(nèi)存碎片的問題,采用了自己實現(xiàn)的slab allocator 的方式。即內(nèi)存的分配都是一塊一塊的,最終存儲在固定長度的chunk 上,內(nèi)存最小的分配單元是chunk,另外 libevent 的性能也并沒有優(yōu)化到極致,但是不妨礙 memcached 成為當(dāng)時的開源緩存事實標準(另外,八卦一下,memcached 的作者Brad Fitzpatrick,現(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,包括隊列、集合、Sorted Set 等等,提供了非常豐富的表達力,而且 Redis 還提供 sub/pub 等超出數(shù)據(jù)庫范疇的便捷功能,使得幾乎一夜之間大家紛紛投入 Redis 的懷抱。

Twemproxy

但是隨著 Redis 漸漸的普及,而且越用越狠,另外內(nèi)存也越來越便宜,人們開始尋求擴展單機Redis的方案,最早的嘗試是twitter 開源的twemproxy,twemproxy 是一個 Redis 中間件,基本只有最簡單的數(shù)據(jù)路由功能,并沒有動態(tài)的伸縮能力,但是還是受到了很多公司的追捧,因為確實沒方案。隨后的 Redis Cluster 也是難產(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 極其周邊的擴展方案。

MongoDB

在 NoSQL 的大家庭中,MongoDB其實是一個異類,大多 NoSQL 舍棄掉 SQL 是為了追求更極致的性能和可擴展能力,而 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)項目變得龐大或者「嚴肅」的時候,團隊最后還是回歸了關(guān)系型數(shù)據(jù)庫。Anyway,在 2014 年底 MongoDB 收購了 WiredTiger 后,在 2.8 版本中正式亮相,同時 3.0 版本后更是作為默認存儲引擎提供,性能和穩(wěn)定性有了非常大的提升。

但是,從另一方面講,Schema-less 到底對軟件工程是好事還是壞事這個問題還是有待商榷。我個人是站在 Schema 這邊的,不過在一些小項目或者需要快速開發(fā)的項目中使用 Mongo 確實能提升很多的開發(fā)效率,這是毋庸置疑的。

HBase

說到 NoSQL 不得不提的是HBase,HBase 作為Hadoop 旗下的重要產(chǎn)品,Google Bigtable的正統(tǒng)開源實現(xiàn),是不是有一種欽定的感覺:)。提到 HBase 就不得不提一下Bigtable,Bigtable是Google內(nèi)部廣泛使用的分布式數(shù)據(jù)庫,接口也不是簡單的Key-Value,按照論文的說法叫:multi-dimensional sorted map,也就是 Value 是按照列劃分的。Bigtable 構(gòu)建在 GFS 之上,彌補了分布式文件系統(tǒng)對于海量、小的、結(jié)構(gòu)化數(shù)據(jù)的插入、更新、隨機讀請求的缺陷。

HBase 就是這么一個系統(tǒng)的實現(xiàn),底層依賴 HDFS。HBase 本身并不實際存儲數(shù)據(jù),持久化的日志和 SST file (HBase 也是 LSM-Tree 的結(jié)構(gòu)) 直接存儲在 HDFS 上,Region Server (RS) 維護了 MemTable 以提供快速的查詢,寫入都是寫日志,后臺進行 Compact,避免了直接隨機讀寫 HDFS。

數(shù)據(jù)通過 Region 在邏輯上進行分割,負載均衡通過調(diào)節(jié)各個 Region Server 負責(zé)的 Region 區(qū)間實現(xiàn)。當(dāng)某 Region 太大時,這個 Region 會分裂,后續(xù)可能由不同的 RS 負責(zé),但是前面提到了,HBase 本身并不存儲數(shù)據(jù),這里的 Region 僅是邏輯上的,數(shù)據(jù)還是以文件的形式存儲在 HDFS 上,所以 HBase 并不關(guān)心 Replication 、水平擴展和數(shù)據(jù)的分布,統(tǒng)統(tǒng)交給 HDFS 解決。

和 Bigtable 一樣,HBase 提供行級的一致性,嚴格來說在CAP理論中它是一個 CP 的系統(tǒng),但遺憾的是并沒有更進一步提供 ACID 的跨行事務(wù)。HBase 的好處就不用說了,顯而易見,通過擴展 RS 可以幾乎線性提升系統(tǒng)的吞吐,及 HDFS 本身就具有的水平擴展能力。

但是缺點仍然是有的。

首先,Hadoop 的軟件棧是 JAVA,JVM 的 GC Tuning 是一個非常煩人的事情,即使已經(jīng)調(diào)得很好了,平均延遲也得幾十毫秒;

另外在架構(gòu)設(shè)計上,HBase 本身并不存儲數(shù)據(jù),所以可能造成客戶端請求的 RS 并不知道數(shù)據(jù)到底存在哪臺 HDFS DataNode 上,憑空多了一次 RPC;

第三,HBase 和 Bigtable 一樣,并不支持跨行事務(wù),在 Google 內(nèi)部不停的有團隊基于 Bigtable 來做分布式事務(wù)的支持,比如 MegaStore、Percolator。后來Jeff Dean有次接受采訪也提到非常后悔沒有在 Bigtable 中加入跨行事務(wù),不過還好這個遺憾在 Spanner 中得到了彌補,這個一會兒說。

總體來說,HBase 還是一個非常健壯且久經(jīng)考驗的系統(tǒng),但是需要你有對于 Java 和 Hadoop 比較深入的了解后,才能玩轉(zhuǎn),這也是 Hadoop 生態(tài)的一個問題,易用性真是不是太好,而且社區(qū)演進速度相對緩慢,也是因為歷史包袱過重的緣故吧。

Cassandra

提到 Cassandra (C*),雖然也是 Dynamo 的開源實現(xiàn),但就沒有這種欽定的感覺了。C* 確實命途多舛,最早 2008 由 Facebook 開發(fā)并開源,早期的 C* 幾乎全是 bug,F(xiàn)acebook 后來索性也不再維護轉(zhuǎn)過頭搞 HBase 去了,一個爛攤子直接丟給社區(qū)。還好DataStax把這個項目撿起來商業(yè)化,搞了兩年,終于漸漸開始流行起來。

C* 不能簡單的歸納為讀快寫慢,或者讀慢寫快,因為采用了 qourm 的模型,調(diào)整復(fù)制的副本數(shù)以及讀的數(shù)量,可以達到不同的效果,對于一致性不是特別高的場景,可以選擇只從一個節(jié)點讀取數(shù)據(jù),達到最高的讀性能。另外 C* 并不依賴分布式文件系統(tǒng),數(shù)據(jù)直接存儲在磁盤上,各個存儲節(jié)點之間自己維護復(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 的時間戳或者客戶端自行提供,每臺機器可能都有誤差,所以有可能并不準確,這也就是為什么 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,解析出 sharding key,然后根據(jù) sharding key 分發(fā)請求,再合并;另外數(shù)據(jù)庫有事務(wù),在中間件這層還需要維護 Session 及事務(wù)狀態(tài),而且大多數(shù)方案并沒有辦法支持跨 shard 的事務(wù)。

這就不可避免的導(dǎo)致了業(yè)務(wù)使用起來會比較麻煩,需要重寫代碼,而且會增加邏輯的復(fù)雜度,更別提動態(tài)的擴容縮容和自動的故障恢復(fù)了。在集群規(guī)模越來越大的情況下,運維和 DDL 的復(fù)雜度是指數(shù)級上升的。

中間件項目盤點

數(shù)據(jù)庫中間件最早的項目大概是MySQL Proxy,用于實現(xiàn)讀寫分離。后來國人在這個領(lǐng)域有過很多的著名的開源項目,比如阿里的Cobar和DDL(并未完全開源;后來社區(qū)基于 Cobar 改進的MyCAT、360 開源的Atlas 等,都屬于這一類中間件產(chǎn)品;

在中間件這個方案上基本走到頭的開源項目應(yīng)該是Youtube Vitesse。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ū)最好的分布式擴展方案。其他的就不提了。

4

未來在哪里?NewSQL?

一句話,NewSQL 是未來。

2012 年 Google 在 OSDI 上發(fā)表了 Spanner 的論文,2013 年在 SIGMOD 發(fā)表了 F1 的論文。這兩篇論文讓業(yè)界第一次看到了關(guān)系模型和 NoSQL 的擴展性在超龐大集群規(guī)模上融合的可能性。在此之前,大家普遍認為這個是不可能的,即使是 Google 也經(jīng)歷了Megastore這樣系統(tǒng)的失敗。

Spanner綜述

但是 Spanner 的創(chuàng)新之處在于通過硬件(GPS時鐘+原子鐘)來解決時鐘同步的問題。在分布式系統(tǒng)里,時鐘是最讓人頭痛的問題,剛才提到了 C* 為什么不是一個強 C 的系統(tǒng),正是因為時鐘的問題。而 Spanner 的厲害之處在于即使兩個數(shù)據(jù)中心隔得非常遠,不需要有通信(因為通信的代價太大,最快也就是光速)就能保證 TrueTime API的時鐘誤差在一個很小的范圍內(nèi)(10ms)。另外 Spanner 沿用了很多 Bigtable 的設(shè)計,比如 Tablet / Directory 等,同時在 Replica 這層使用 Paxos 復(fù)制,并未完全依賴底層的分布式文件系統(tǒng)。但是 Spanner 的設(shè)計底層仍然沿用了 Colossus,不過論文里也說是可以未來改進的點。

Google 的內(nèi)部的數(shù)據(jù)庫存儲業(yè)務(wù),大多是 3~5 副本,重要一點的 7 副本,遍布全球各大洲的數(shù)據(jù)中心,由于普遍使用了 Paxos,延遲是可以縮短到一個可以接受的范圍(Google 的風(fēng)格一向是追求吞吐的水平擴展而不是低延遲,從悲觀鎖的選擇也能看得出來,因為跨數(shù)據(jù)中心復(fù)制是必選的,延遲不可能低,對于低延遲的場景,業(yè)務(wù)層自己解決或者依賴緩存)。

另外由 Paxos 帶來的 Auto-Failover 能力,更是能讓整個集群即使數(shù)據(jù)中心癱瘓,業(yè)務(wù)層都是透明無感知的。另外 F1 構(gòu)建在 Spanner 之上,對外提供了更豐富的 SQL 語法支持,F(xiàn)1 更像一個分布式 MPP SQL——F1 本身并不存儲數(shù)據(jù),而是將客戶端的 SQL 翻譯成類似 MapReduce 的任務(wù),調(diào)用 Spanner 來完成請求。

其實除了 TrueTime 整個系統(tǒng)并沒有用什么全新的算法,而是近些年分布式系統(tǒng)的技術(shù) Spanner 和 F1 的出現(xiàn)標志著第一個 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 ),第一個團隊是在紐約的CockroachDB。CockroachDB 的團隊的組成還是非常豪華的,早期團隊由是 Google 的分布式文件系統(tǒng)Colossus團隊的成員組成;技術(shù)上來說,Cockroach 的設(shè)計和 Spanner 很像,不一樣的地方是沒有選擇 TrueTime而是 HLC (Hybrid logical clock),也就是 NTP +邏輯時鐘來代替 TrueTime 時間戳;另外 Cockroach 選用了 Raft 代替 Paxos 實現(xiàn)復(fù)制和自動容災(zāi),底層存儲依賴 RocksDB 實現(xiàn),整個項目使用 Go 語言開發(fā),對外接口選用 PostgreSQL 的 SQL 子集。

CockroachDB

CockroachDB 的技術(shù)選型比較激進,比如依賴了 HLC 來做事務(wù)的時間戳。但是在 Spanner 的事務(wù)模型的 Commit Wait 階段等待時間的選擇,CockroachDB 并沒有辦法做到 10ms 內(nèi)的延遲;CockroachDB 的 Commit Wait 需要用戶自己指定,但是誰能拍胸脯說 NTP 的時鐘誤差在多少毫秒內(nèi)?我個人認為在處理跨洲際機房時鐘同步的問題上,基本只有硬件時鐘一種辦法。HLC 是沒辦法解決的。

另外Cockroach 采用了 gossip 來同步節(jié)點信息,當(dāng)集群變得比較大的時候,gossip 心跳會是一個非常大的開銷。當(dāng)然 CockroachDB 的這些技術(shù)選擇帶來的優(yōu)勢就是非常好的易用性,所有邏輯都在一個 binary 中,開箱即用,這個是非常大的優(yōu)點。

TiDB

目前從全球范圍來看,另一個在朝著 Spanner / F1 的開源實現(xiàn)這個目標上走的產(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)的 MPP SQL Layer,整個系統(tǒng)的底層是依賴 TiKey-Value 來提供分布式存儲和分布式事務(wù)的支持。TiKey-Value 的分布式事務(wù)模型采用的是 Google Percolator 的模型,但是在此之上做了很多優(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 項目追求的目標:

  • 數(shù)據(jù)庫會隨著業(yè)務(wù)云化,未來一切的業(yè)務(wù)都會跑在云端,不管是私有云或者公有云,運維團隊接觸的可能再也不是真實的物理機,而是一個個隔離的容器或者「計算資源」。這對數(shù)據(jù)庫也是一個挑戰(zhàn),因為數(shù)據(jù)庫天生就是有狀態(tài)的,數(shù)據(jù)總是要存儲在物理的磁盤上,而數(shù)據(jù)的移動的代價比移動容器的代價可能大很多。
  • 多租戶技術(shù)會成為標配,一個大數(shù)據(jù)庫承載一切的業(yè)務(wù),數(shù)據(jù)在底層打通,上層通過權(quán)限,容器等技術(shù)進行隔離;但是數(shù)據(jù)的打通和擴展會變得異常簡單,結(jié)合第一點提到的云化,業(yè)務(wù)層可以再也不用關(guān)心物理機的容量和拓撲,只需要認為底層是一個無窮大的數(shù)據(jù)庫平臺即可,不用再擔(dān)心單機容量和負載均衡等問題。
  • OLAP 和 OLTP 會進一步細分,底層存儲也許會共享一套,但是SQL優(yōu)化器這層的實現(xiàn)一定是千差萬別的。對于用戶而言,如果能使用同一套標準的語法和規(guī)則來進行數(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 主要注意兩點:

  1. 做好業(yè)務(wù)的調(diào)研,估計并發(fā)量,數(shù)據(jù)量,數(shù)據(jù)的結(jié)構(gòu)看看適不適合;
  2. 對各種 NoSQL 擅長和不擅長的地方都盡可能了解。

不要盲目相信關(guān)系型數(shù)據(jù)庫,也不要盲目相信 NoSQL,沒有銀彈的。

問:有多個條件,比如年齡20到30或年齡35到40,并且加入購物車或下單,這種數(shù)據(jù)怎么存儲?

黃東旭:購物車這種場景是典型的 OLTP 的場景,可以選用關(guān)系型數(shù)據(jù)庫 MySQL PostgreSQL 什么的,如果對于擴展性的數(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ù)庫的擴展性是有問題的,在海量并發(fā)和數(shù)據(jù)量的場景下很難支持業(yè)務(wù)。所以可以看到比較大的互聯(lián)網(wǎng)公司基本都有自己的分布式數(shù)據(jù)庫方案。

問:未來可能不再需要數(shù)據(jù)倉庫嗎?

黃東旭:大家可以想想數(shù)據(jù)倉庫的定義,如果是還需要離線的從線上庫倒騰數(shù)據(jù)到數(shù)據(jù)倉庫上,這樣很難做到實時查詢,而且空間的利用率也低,我認為是目前并沒有太好的方案的情況下的折衷……

如果有一個更好的數(shù)據(jù)庫能解決數(shù)據(jù)倉庫的場景,為什么還需要一個獨立的數(shù)據(jù)

分享到:
標簽:開源 數(shù)據(jù)庫
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定