京東云總監(jiān)帶你吃透分布式精髓(含視頻)
1953年,埃布·格羅希提出Grosch定律,即計(jì)算機(jī)性能會隨著成本的平方而增加。1965年,高登·摩爾提出摩爾定律:當(dāng)價(jià)格不變時(shí),集成電路上可容納的元器件的數(shù)目,約每隔18-24個(gè)月便會增加一倍。
當(dāng)今,計(jì)算機(jī)的普及,也讓越來越多的電腦處于閑置狀態(tài),即使在開機(jī)狀態(tài)下CPU的潛力也遠(yuǎn)未被完全利用。而互聯(lián)網(wǎng)的出現(xiàn),使得連接和調(diào)用閑置計(jì)算資源的計(jì)算機(jī)系統(tǒng)成為了現(xiàn)實(shí)。
于是,分布式計(jì)算開始普及,分布式難不難?難!所以更需名師指路!下面要介紹的課程,由京東云高級總監(jiān)親自授課哦,趕快往下看吧!
本次直播課程由京東云高級總監(jiān)郭理靖數(shù)據(jù)庫基礎(chǔ)入手,從實(shí)踐應(yīng)用出發(fā),深度解析從單機(jī)數(shù)據(jù)庫到分布式數(shù)據(jù)庫的技術(shù)發(fā)展與迭代,同時(shí)并理論結(jié)合實(shí)際為大家講述企業(yè)選擇數(shù)據(jù)庫服務(wù)的金科玉律以及京東云針對此方面的應(yīng)用實(shí)踐等干貨內(nèi)容。
課程概要
此次課程的分享內(nèi)容更多關(guān)于數(shù)據(jù)庫服務(wù)的演變史,重點(diǎn)講述單機(jī)到分布式的變化從何而來以及從單機(jī)數(shù)據(jù)庫如何進(jìn)行改進(jìn)才可達(dá)成分布式數(shù)據(jù)庫的服務(wù)。
以下是郭理靖老師分享的全部內(nèi)容,希望給各位開發(fā)者帶來更多幫助:
從單機(jī)到分布式,數(shù)據(jù)庫服務(wù)的演變史
京東云高級總監(jiān) 郭理靖
1從Redis到MongoDB
從Redis到MongoDB,最初的產(chǎn)生都很簡單
很多時(shí)候,一門技術(shù)甚至一種產(chǎn)品,最初的產(chǎn)生往往都來源非常簡單的想法,例如2019年,我們看到DB-Engines Ranking中有兩個(gè)比較熟悉的身影,MongoDB和Redis。
很有意思的是,MongoDB屬于DocumentDB。如果我們調(diào)頭去看DocumentDB-Engines Ranking的話,可以發(fā)現(xiàn)MongoDB是排在***位,而且是以絕對性的優(yōu)勢“吊打”第二位到第十位(第二名只有56分),整個(gè)DB-Engines中,Oracle和MySQL的分?jǐn)?shù)靠得特別近;但是在DocumentDB中,MongoDB是400多分,但第二名可能就只有100多分。
同樣,Redis在K/V的領(lǐng)域,分?jǐn)?shù)也特別靠前,它146分,第三名是MemcacheD(第二名為Amazon DynamoDB,為56分) 只有28.7分。
所以這兩個(gè)數(shù)據(jù)庫在自己的專業(yè)領(lǐng)域中都是排名特別靠前的兩個(gè)數(shù)據(jù)庫,而且彼此出現(xiàn)的時(shí)間都不算特別長,不到十年:Redis出現(xiàn)的比MongoDB早一些,Redis是2009年,MongoDB差不多也是在2009年左右出現(xiàn)的。
為什么Redis會出現(xiàn),并且成為K/VDB排名***的一個(gè)數(shù)據(jù)庫呢?
其實(shí),在Redis出現(xiàn)之前已經(jīng)有一個(gè)K/V的數(shù)據(jù)庫叫Memcached,早在2003年發(fā)布,最初用Perl寫了一個(gè)版本,***用C語言重寫了。在Redis沒有出現(xiàn)之前,Memcached一直是K/V數(shù)據(jù)庫的領(lǐng)頭,為什么在2009年,當(dāng)Redis出現(xiàn)時(shí)就飛快地代替了Memcached,直至今日,大部分的緩存我們都用Redis。甚至剛?cè)胄械耐瑢W(xué)們根本沒有聽說過還有Memcached這樣的數(shù)據(jù)庫,這個(gè)過程中Redis到底做了什么事情?
事情比較簡單,從設(shè)計(jì)理念出發(fā),就是把原先Memcached的存儲結(jié)構(gòu)進(jìn)行了改變。之前是一個(gè)Key對應(yīng)一個(gè)String,然后Redis把String變化成一個(gè)可以結(jié)構(gòu)化的Structured storage,也就是說Redis可以支持一些結(jié)構(gòu)化的數(shù)據(jù),包括List、sorted set、hashes等 。
如此小的變化為什么能夠讓它取得這么大的優(yōu)勢?關(guān)于此還是要回溯下Memcached。
假設(shè)我們自己要設(shè)計(jì)一個(gè)緩存系統(tǒng)的話,設(shè)計(jì)目標(biāo)與Memcached一樣,過程中就需要設(shè)計(jì)一個(gè)Key String的緩存系統(tǒng),那么在這個(gè)緩存系統(tǒng)上到底能夠提供哪些服務(wù)呢?更進(jìn)一步來說,當(dāng)存儲對象是String,針對此我們可以做到哪些操作?
可以想見,在一個(gè)編程語言中,以以C++或者Java為例,一個(gè)字符串可以set一個(gè)字符串,還可以get一個(gè)字符串,當(dāng)然也可以delete一個(gè)字符串。此外,對于字符串我們還可以做一些其他操作,例如append、prepend等,也就是字符串的尾巴和頭部加些內(nèi)容,甚至可以將整個(gè)字符串替換掉。當(dāng)然,也可以做insert、erase,還有trim這種操作以及find、substr等。
大家在設(shè)計(jì)過程中不妨想一想,為什么在Memcached中不支持insert或find、substr這樣的操作呢?
這其實(shí)是一個(gè)很有意思的話題。理論上Memcached可以支持這些操作,包括針對Memcached的源代碼進(jìn)行修改之后,也可以支持這些函數(shù)和調(diào)用,但之所以選擇不支持可能更多還是效率方面的考量。
例如在Memcached中支持substr或者find的操作的過程中,卻浪費(fèi)了Memcached服務(wù)器的性能。因?yàn)閒ind可以把整個(gè)字符串轉(zhuǎn)移到本地再做find,substr也是一樣,其實(shí)都?xì)w功于性能。
當(dāng)然Memcached也可以提供更高級的一些操作,例如add或者一些gets操作,還可以做incr/decr,對一個(gè)數(shù)字進(jìn)行原子性加減,都可以。如果去研究Memcached整個(gè)release history的話,它是2003年開始發(fā)布的一個(gè)版本,前期支持的工作是非常有限的,所以后續(xù)的高級功能也是慢慢逐漸加進(jìn)去的。
再看一下Redis,可以支持的數(shù)據(jù)結(jié)構(gòu)有很多,包括Strings、Lists、Sets、Sorted sets、Hashes、Bit arrays,還有HyperLogLogs、streams,streams是5.0,***的版本甚至可以支持一些時(shí)序性的數(shù)據(jù)。
縱觀整個(gè)迭代歷程,Redis最初的簡單想法就是能不能將Strings的結(jié)構(gòu)和存儲結(jié)構(gòu),讓其支持的多一些。從這個(gè)想法出發(fā),才會逐漸發(fā)展成慢慢去支持越來越多的數(shù)據(jù)結(jié)構(gòu),支持越來越多操作類型的局面。
以C++為例,一個(gè)List操作支持pop/push,也可以支持在List中間去Insert/erase。對于Redis而言,除了常見的操作之外,我看了一下Redis整體的release history,最開始的時(shí)候也支持的是一些比較簡單的操作,例如pop/push;隨著時(shí)間的發(fā)展,支持越來越多的高級功能,都是建立在普通的操作上。
比方說BRPOPLPUSH這個(gè)功能,就是從一個(gè)List中POP一個(gè)數(shù)據(jù)出來,插入到另外一個(gè)List中去,這算是比較高級的功能體現(xiàn)了,但這個(gè)也是在用戶發(fā)現(xiàn)其需要此種場景之后才去增加的事項(xiàng)。
再來探究下MongoDB。MongoDB的“工作”其實(shí)與Redis有點(diǎn)類似,可以認(rèn)為Redis就是利用K/V結(jié)構(gòu),將Strings換成了一個(gè)類似于JSON的類型,JSON中可以支持的數(shù)據(jù)結(jié)構(gòu)也非常多。
MongoDB所體現(xiàn)的功能相似度很高。以前在設(shè)計(jì)數(shù)據(jù)庫的時(shí)候,如果是關(guān)系型數(shù)據(jù)庫,一開始就需要將Schema設(shè)計(jì)好,然后去做一個(gè)DDL操作。當(dāng)需要增加一列或者減少一列的時(shí)候,以上的操作并不是很方便;特別在表單很龐大的情況下,操作時(shí)間會很長。
隨著業(yè)務(wù)的發(fā)展,是否可以用一個(gè)JSON來代替原型MySQL Schema?以這樣一種簡單的想法出發(fā),如今盡管MySQL或者關(guān)系型數(shù)據(jù)庫還是以Schema為核心,但是MongoDB就以Document,也就是JSON這個(gè)格式為核心去構(gòu)建整個(gè)數(shù)據(jù)庫的功能和生態(tài)。
可以看到,MySQL的常見SQL語句在MongoDB中命令長度不太一樣,因?yàn)樗械拿疃寂cJSON的格式有關(guān),包括底層的存儲結(jié)構(gòu)也會因?yàn)橐4鍶SON格式而做出很大變化。
這部分集中想要表達(dá)的觀點(diǎn)就是很多數(shù)據(jù)庫以及技術(shù)產(chǎn)品的演進(jìn),其實(shí)都是有脈絡(luò)可尋的,主要就是設(shè)定解決問題的目標(biāo)進(jìn)而完成底層數(shù)據(jù)結(jié)構(gòu)的修改,其中底層結(jié)構(gòu)確定之后還會在一定程度上影響產(chǎn)品功能,例如MongoDB在很長一段時(shí)間內(nèi)都不支持事務(wù),不是不想去嘗試支持,而是取決于底層存儲結(jié)構(gòu)的存儲引擎,無法支持事務(wù)。
同樣的道理,探究Memcached和Redis的內(nèi)存管理設(shè)計(jì),也會發(fā)現(xiàn),Memcached的開發(fā)者或者說社區(qū),也想去支持像Redis一樣的功能,但事實(shí)上由于底層的存儲結(jié)構(gòu)注定無法提供此類服務(wù)。
2分布式從何而來?
為什么會有分布式?主要還是由于處在信息爆炸的時(shí)代,業(yè)務(wù)量逐漸龐大導(dǎo)致單機(jī)數(shù)據(jù)庫并不能更好滿足需求,自然要尋找一些可行的解決方案。
這里的解決方案可以分為兩種,一類相當(dāng)于表層的解決方案,操作起來比較簡單,其中涉及客戶端的方案以及統(tǒng)一代理的方案等,例如proxy的方案。
相比之下,底層的方案可以分為三類。***類是分布式塊存儲方案,第二類是計(jì)算與存儲分離方案,第三類就是要另起爐灶了。
首先客戶端方案,可以以友商開源的項(xiàng)目稱為TDDL為代表,方案思路較為清晰。如果我們自身需要做一個(gè)分布式系統(tǒng)的話,將分布式解決方案放入客戶端內(nèi),最重要的就是“告訴”客戶端SQL語句應(yīng)該鏈接到背后哪個(gè)數(shù)據(jù)庫,畢竟不同的數(shù)據(jù)存儲在不同的機(jī)器當(dāng)中。對于客戶端的方案,比較重要的就是與后端的一些連接,以及如何解析這個(gè)SQL語句。
第二種方案就是Proxy方案。Proxy方案相對客戶端方案而言,開發(fā)難度稍微高一些,但思路上還是非常一致的。舉例說明,一張用戶表,用戶表的組件是ID,我們對ID的分布式key進(jìn)行分布,查詢具體某一個(gè)用戶ID的時(shí)候其實(shí)就有一個(gè)Proxy,如果說查詢這個(gè)用戶ID為0,進(jìn)而就知道0是存在于后臺的哪一臺MySQL。
所以對于Proxy而言,非常重要的一點(diǎn)還是需要去解析具體的SQL語句,這個(gè)過程中必須需要有一個(gè)自己的路由,就可以完成識別。
客戶端的方案與Proxy方案的區(qū)別在哪里?區(qū)別在于客戶端的方案開發(fā)起來相對比較簡單一點(diǎn),在JDBC中或者要求客戶端調(diào)用時(shí),客戶端可以不解析SQL語句,完成導(dǎo)向很容易。
對于Proxy方案,它需要兼容原有的MySQL協(xié)議,怎么建立MySQL連接,怎么與后端保持連接,這個(gè)難度比較大。但相對而言,Proxy方案的限制也比較多,不管是客戶端的表層方案,還是Proxy的表層方案,它們對SQL的使用要求都是比較高的,例如一些join是比較難支持的,而且要與業(yè)務(wù)方達(dá)成一致。
此外,無論是客戶端方案還是Proxy方案,整體架構(gòu)還是比較類似的。例如Proxy方案,它會涉及前端如何與客戶端進(jìn)行連接以及后端的Backend connection,還要與后端真正提供MySQL服務(wù)的保持連接,這是兩個(gè)連接的管理。
經(jīng)過了解,整個(gè)Proxy一般的設(shè)計(jì)都會采取無狀態(tài),因?yàn)槁酚尚畔⒍际潜4嬖赑roxy本機(jī)的;但路由方面肯定有一個(gè)相對的路由管理中心去分發(fā)和更改控制。業(yè)界大部分Proxy設(shè)計(jì),大家都會發(fā)現(xiàn),Proxy代理的方案其架構(gòu)設(shè)計(jì)非常相像,區(qū)別在于工程質(zhì)量不同而已。
另外,對于Proxy方案的缺點(diǎn)就是怎么去做一個(gè)分布式事務(wù),沒辦法保證次序。通常在一個(gè)分布式的情況下,其實(shí)很難保證每個(gè)節(jié)點(diǎn)上的事務(wù)執(zhí)行是按照我們想像中的次序去做。
講完表層的解決方案之后,我們還需要講講比較深層次的底層解決方案。從表層出發(fā),不管是客戶端方案還是Proxy方案,都并沒有去改變底層MySQL的整體協(xié)議,也沒有改變數(shù)據(jù)庫原生服務(wù),可以認(rèn)為根本就沒有讓MySQL底層代碼發(fā)生變動。
如今可知曉的底層解決方案主要有三個(gè),***個(gè)方案是塊存儲方案,包括SAN解決方案,涉及云端就是云硬盤解決方案,都是同一類型的。
但如果真正要做一個(gè)數(shù)據(jù)庫的解決方案,目前的主流思路還是計(jì)算與存儲分離,為什么會出現(xiàn)計(jì)算與存儲分離呢?主要原因有以下幾點(diǎn):現(xiàn)在的網(wǎng)絡(luò)延時(shí)一直在下降,帶寬一直在增長,從我個(gè)人的工作經(jīng)驗(yàn)來看,未來可能還有更大的網(wǎng)絡(luò)帶寬出現(xiàn);但與此同時(shí),磁盤IO的吞吐量并沒有增長得像網(wǎng)絡(luò)這么快。
此外,存儲的虛擬化有利于成本下降,分布式存儲有利于提高IOPS。如果在一個(gè)機(jī)器上做Raid的話,它的性能會比單個(gè)硬盤要好很多;如果采用分布式系統(tǒng)寫入,它的IOPS其實(shí)會更高。
目前業(yè)界比較有名的幾個(gè)計(jì)算與存儲分離的解決方案,***的就是亞馬遜的Aurora。
Aurora為什么選擇計(jì)算存儲分離?關(guān)于這一點(diǎn),還需要探究當(dāng)時(shí)亞馬遜做RDS的解決方案如何。亞馬遜RDS,就是它們的Realtional Database Service,整體數(shù)據(jù)存在local disk/EBS上面。
我們可以看到,整個(gè)IO的寫入鏈條是比較長的,要把數(shù)據(jù)落盤,binlog落盤,redo log落盤,而且整個(gè)binlog兩邊要同步,***還要把EBS的數(shù)據(jù)適當(dāng)?shù)貍浞莸皆拼鎯χ腥ァ?這個(gè)只是備份,與實(shí)時(shí)寫入無關(guān))。
由于鏈路比較長,而且包括整個(gè)EBS的實(shí)現(xiàn)中,EBS就是個(gè)分布式的快存儲,本質(zhì)上也是多副本的。在多副本的情況下,EBS在遠(yuǎn)端也要做整個(gè)數(shù)據(jù)的同步,所以Aurora的設(shè)計(jì)目標(biāo)就是思考能不能把存儲與計(jì)算做一些相應(yīng)的分離。出發(fā)點(diǎn)就是數(shù)據(jù)庫存儲引擎能不能與分布式塊存儲融合在一塊,融合成一個(gè)新的存儲引擎。
另外一個(gè)方案是F1/Spanner的方案,思路又是什么呢?
做一個(gè)分布式系統(tǒng),如果去兼容MySQL比較麻煩的話,那是不是可以另起爐灶,做一個(gè)新的分布式系統(tǒng)。
它的思路很簡單,就是重新去改寫一些SQL,所以像F1/Spanner并不兼容MySQL的一些協(xié)議時(shí),就會引入新的分布式事務(wù)管理,把SQL都拆解成K/V的一些操作結(jié)構(gòu),對這種方案而言,SQL的兼容性是個(gè)長期耗時(shí)而且是***接近的一個(gè)過程,主要需兼容已有的生態(tài)會比較費(fèi)力。但如果是一個(gè)新業(yè)務(wù),用這種分布式方案就沒有問題;如果是個(gè)舊業(yè)務(wù),有自己成熟的SQL,想用它就比較困難了。
可以看到對一個(gè)MySQL服務(wù)而言,其實(shí)有兩部分組成,一部分是Server,一部分Storage。Storage標(biāo)準(zhǔn)的架構(gòu)是redo log加個(gè)data,這是InnoDB的一個(gè)結(jié)構(gòu),如今InnoDB已經(jīng)成為MySQL的一個(gè)標(biāo)準(zhǔn),大家都是按照這種方式去做的。
關(guān)于主從同步,是用binlog復(fù)制的方式,把binlog復(fù)制到Slave這邊,Slave對binlog重放,然后Slave就有完整數(shù)據(jù),這是傳統(tǒng)的一個(gè)數(shù)據(jù)庫組成模式。
對于MySQL而言,它的數(shù)據(jù)流向會是什么樣子的?***步,如果針對一個(gè)事務(wù)或者一個(gè)SQL語句,它會寫很多redo log。第二步,會寫到binlog中,binlog以后會做半同步,會同步到Slave中,返回一個(gè)信息,這時(shí)候可以進(jìn)行一個(gè)整體的commit。
對于整個(gè)數(shù)據(jù)流向的一個(gè)示意圖,主從之間用了整體的binlog復(fù)制方式去做。如果想做一個(gè)分布式系統(tǒng)的話,而且出發(fā)點(diǎn)是不能夠?qū)⑦@些一樣的數(shù)據(jù)放在同一個(gè)分布式系統(tǒng)中,需要做哪些事情?
我們發(fā)現(xiàn),如果計(jì)算和存儲分離之后,把所有的存儲都放在一個(gè)分布式存儲系統(tǒng)中去,master與slave讀的是同一個(gè)數(shù)據(jù),其實(shí)就不需要binlog了,這個(gè)是比較容易理解的。binlog用來傳輸具體的數(shù)據(jù),因?yàn)閿?shù)據(jù)都放在一起。
3計(jì)算和存儲分離的優(yōu)點(diǎn)
在于分布式存儲的存儲空間會相對大一些;另外一點(diǎn),如果說要增加一個(gè)新的slave,以前在MySQL的主從復(fù)制中增加一個(gè)新的slave,通常怎么做?
要么就新建一個(gè)空白的slave,慢慢從組合開始同步數(shù)據(jù),總而言之就是利用binlog同步數(shù)據(jù);但如果整個(gè)數(shù)據(jù)量比較大的話,建立一個(gè)新的從時(shí)間會非常長,或者說根據(jù)備份去重建一個(gè)新的從,進(jìn)而拷貝數(shù)據(jù)庫備份。在這個(gè)基礎(chǔ)上再去追新日志,無論如何增加一個(gè)節(jié)點(diǎn),時(shí)間應(yīng)該還是要以分鐘計(jì),至少以10分鐘為單位。
但在計(jì)算與存儲分離之后,新建一個(gè)slave時(shí)間就非常快了,而且備份數(shù)據(jù)的時(shí)候會快很多。因?yàn)獒槍鹘y(tǒng)主從系統(tǒng)做備份,其實(shí)都要去做一個(gè)文件系統(tǒng)的備份。做文件系統(tǒng)快照也行,用mysql dump也行,需要把本地文件傳到云端存儲;在分布式存儲系統(tǒng)中,可以把這個(gè)任務(wù)轉(zhuǎn)移給底層系統(tǒng)去做,當(dāng)然數(shù)據(jù)的強(qiáng)一致還要靠底層存儲去保證。
如果把計(jì)算、存儲分離之后,整個(gè)高可用切換會是什么樣子的?對于以前的MySQL而言,一個(gè)主從切換其實(shí)比較簡單,因?yàn)橹鞲鷱氖莾蓚€(gè)獨(dú)立的存儲和計(jì)算,之間沒有關(guān)聯(lián)關(guān)系,主切換到從,最多就是binlog還沒有回放完;但對于整個(gè)計(jì)算存儲分離之后,它的變化還是有一些的。
例如***個(gè)變化,我們可以看到對于傳統(tǒng)數(shù)據(jù)庫而言,它的Redo日志是一個(gè)循環(huán)的文件系統(tǒng),可以是三個(gè)Redo日志循環(huán)使用;如果在一個(gè)存儲分離,計(jì)算分離的環(huán)境,它的Redo日志基本會設(shè)計(jì)成按編號去排序的情況。
等主從切換之后,log buffer和buffer pool,也許需要一點(diǎn)時(shí)間去重建它的兩個(gè)buffer pool。因?yàn)樵趥鹘y(tǒng)意義上,傳統(tǒng)的MySQL主從切換都需要去根據(jù)日志稍微重建一下buffer pool。
對于備份而言,基本上變化也比較大,整個(gè)備份會基于底層的塊存儲:一部分可以去備份整個(gè)page頁的數(shù)據(jù);另外一部分,需要去做Redo日志的增量備份,這樣很快能完成一個(gè)數(shù)據(jù)庫的備份。
其實(shí)在云端去做一個(gè)數(shù)據(jù)庫的備份會比自己搭建兩臺物理機(jī)去做備份更快,為什么?
因?yàn)樵谠贫朔植际较到y(tǒng)中,做備份的時(shí)候不是一臺機(jī)器在備份,因?yàn)榇鎯υ诓煌臋C(jī)器上。 對于一個(gè)新建的slave而言,如果我們在云端計(jì)算、存儲分離的情況下去新建一個(gè)slave的話,新建slave的速度也會比傳統(tǒng)的方式快非常多,因?yàn)檎麄€(gè)數(shù)據(jù)塊是已經(jīng)存在了,直接去讀就行,不需要重新再復(fù)制一份。
但是這種情況也帶來不少問題。因?yàn)榈讓拥奈募到y(tǒng)其備份數(shù)是有限的,副本數(shù)也是有限的,深層次的原因是因?yàn)榈讓拥姆植际轿募到y(tǒng)的IOPS是有限的,對于一個(gè)主從關(guān)系,像傳統(tǒng)模式下的MySQL,其實(shí)并沒有這種限制。
4總結(jié)
***總結(jié)一下這幾個(gè)方案的優(yōu)缺點(diǎn):
比如客戶端方案,它的優(yōu)點(diǎn)是可以接多種數(shù)據(jù)源,只要數(shù)據(jù)庫是兼容JDBC的,都可以去對接,而且性能上比較好。但提高性能的同時(shí)也帶來另外一個(gè)問題,連接數(shù)可能會比較多,因?yàn)榭蛻舳朔浅6?,每個(gè)客戶端都與MySQL進(jìn)行連接的話,MySQL連接會特別多。
缺點(diǎn)也非常明顯,如果公司中只以Java為主,那沒問題,開發(fā)一個(gè)jar包,大家用起來會非常熟悉;如果說一個(gè)公司用Python、C++,還用Go,每個(gè)語言都要寫一個(gè)客戶端,其實(shí)是非常痛苦的。另外客戶端發(fā)布了,SDK發(fā)布之后升級起來也非常麻煩。
所以絕大部分的廠商會采用Proxy的方案,因?yàn)镻roxy的方案容易管理,升級也比較容易,而且語法基本兼容,不存在多語言SDK的問題。兼容了MySQL的一些語法之后,傳統(tǒng)的MySQL客戶端,各種語言的SDK都能用,所有MySQL第三方開發(fā)的SDK也都能用,缺點(diǎn)在于不支持事務(wù),或者對事務(wù)的支持是有限的。
對于計(jì)算與存理分離方案而言,它的優(yōu)點(diǎn)非常明顯且性價(jià)比特別高,為什么?
云端購買云數(shù)據(jù)庫的時(shí)候,很多時(shí)候性能與購買有關(guān)系。例如買個(gè)1C2G10GB的小型數(shù)據(jù)庫,OPS可能只有幾百上千;但對于真正的計(jì)算與存儲分離的方案而言,開始購買的類型可能是比較小的,購買的規(guī)格可能也比較小,但是可以達(dá)到很高的IOPS性能,數(shù)據(jù)庫性能并不會受限于你購買的規(guī)格。
關(guān)于缺點(diǎn),還是整體的存儲空間有限,可能***只能支持64T或者128T,因?yàn)槊總€(gè)數(shù)據(jù)庫的分布式存儲中其副本數(shù)是有限的,只讀節(jié)點(diǎn)可能受限于,只能有15個(gè)或者14個(gè),但這個(gè)都不要緊。我相信對于絕大多數(shù)的用戶而言,這個(gè)還是足夠用的。另外一個(gè)缺點(diǎn)是開發(fā)難度,但這個(gè)缺點(diǎn)只是開發(fā)廠商的痛點(diǎn),與用戶沒有關(guān)系。
對于另起爐灶,像Spanner/TiDB這種數(shù)據(jù)庫方案,它的可擴(kuò)展性就比較高。因?yàn)閷τ谙馎urora這種計(jì)算與存儲分離的數(shù)據(jù)庫而言存儲空間畢竟是有限的,但對這種數(shù)據(jù)庫,它的存儲空間可以被認(rèn)為是***擴(kuò)展的,可以支持一個(gè)上P的數(shù)據(jù)庫也沒問題。
依舊談?wù)勅秉c(diǎn)。就是很難去兼容現(xiàn)有的一些SQL語法,是一個(gè)比較大的挑戰(zhàn)。例如TiDB是國產(chǎn)比較優(yōu)秀的數(shù)據(jù)庫了,也號稱對MySQL的語法兼容是比較***的,但事實(shí)上還是很多語句是沒法做到兼容的,不是不想,是因?yàn)樽銎饋硖貏e難!因?yàn)榈讓拥臄?shù)據(jù)結(jié)構(gòu)決定了一些功能,也決定了要去兼容一些SQL語句其代價(jià)是非常大的。
【本文為51CTO專欄作者“京東云”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號JD-jcloud獲取授權(quán)】