十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂(yōu)售后,網(wǎng)站問(wèn)題一站解決
像MongoDB, Cassandra, HBase, DynamoDB, 和
瑪納斯網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站開(kāi)發(fā)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
Riak這些NoSQL缺乏傳統(tǒng)的原子事務(wù)機(jī)制,所謂原子事務(wù)機(jī)制是可以保證一系列寫(xiě)操作要么全部完成,要么全部不會(huì)完成,不會(huì)發(fā)生只完成一系列中一兩個(gè)
寫(xiě)操作;因?yàn)閿?shù)據(jù)庫(kù)不提供這種事務(wù)機(jī)制支持,開(kāi)發(fā)者需要自己編寫(xiě)代碼來(lái)確保一系列寫(xiě)操作的事務(wù)機(jī)制,比較復(fù)雜和測(cè)試。
這些NoSQL數(shù)據(jù)庫(kù)不提供事務(wù)機(jī)制原因在于其分布式特點(diǎn),一系列寫(xiě)操作中訪(fǎng)問(wèn)的數(shù)據(jù)可能位于不同的分區(qū)服務(wù)器,這樣的事務(wù)就變成分布式事務(wù),在分
布式事務(wù)中實(shí)現(xiàn)原子性需要彼此協(xié)調(diào),而協(xié)調(diào)是耗費(fèi)時(shí)間的,每臺(tái)機(jī)器在一個(gè)大事務(wù)過(guò)程中必須依次確認(rèn),這就需要一種協(xié)議確保一個(gè)事務(wù)中沒(méi)有任何一臺(tái)機(jī)器寫(xiě)操
作失敗。
這種協(xié)調(diào)是昂貴的,會(huì)增加延遲時(shí)間,關(guān)鍵問(wèn)題是,當(dāng)協(xié)調(diào)沒(méi)有完成時(shí),其他操作是不能讀取事務(wù)中寫(xiě)操作結(jié)果的,這是因?yàn)槭聞?wù)的all-or-
nothing原理導(dǎo)致,萬(wàn)一協(xié)調(diào)過(guò)程發(fā)現(xiàn)某個(gè)寫(xiě)操作不能完成,那么需要將其他寫(xiě)操作成功的進(jìn)行回滾。針對(duì)分布式事務(wù)的分布式協(xié)調(diào)對(duì)整體數(shù)據(jù)庫(kù)性能有嚴(yán)重
影響,不只是吞吐量還包括延遲時(shí)間,這樣大部分NoSQL數(shù)據(jù)庫(kù)因?yàn)樾阅軉?wèn)題就選擇不提供分布式事務(wù)。
MongoDB, Riak, HBase, 和 Cassandra提供基于單一鍵的事務(wù),這是因?yàn)樗行畔⒍己鸵粋€(gè)鍵key有關(guān),這個(gè)鍵是存儲(chǔ)在單個(gè)服務(wù)器上,這樣基于單鍵的事務(wù)不會(huì)帶來(lái)復(fù)雜的分布式協(xié)調(diào)。
那么看來(lái)擴(kuò)展性性能和分布式事務(wù)是一對(duì)矛盾,總要有取舍?實(shí)際上是不完全是,現(xiàn)在完全有可能提供高擴(kuò)展的性能同時(shí)提供分布式原子事務(wù)。
FIT是這樣一個(gè)在分布式系統(tǒng)提供原子事務(wù)的策略,在fairness公平性, isolation隔離性, 和throughput吞吐量(簡(jiǎn)稱(chēng)FIT)可以權(quán)衡。
一個(gè)支持分布式事務(wù)的可伸縮分布式系統(tǒng)能夠完成這三個(gè)屬性中兩個(gè),公平是事務(wù)之間不會(huì)相互影響造成延遲;隔離性提供一種幻覺(jué)好像整個(gè)數(shù)據(jù)庫(kù)只有它自
己一個(gè)事務(wù),隔離性保證當(dāng)任何同時(shí)發(fā)生的事務(wù)發(fā)生沖突時(shí),能夠保證彼此能看到彼此的寫(xiě)操作結(jié)果,因此減輕了程序員為避免事務(wù)讀寫(xiě)沖突的強(qiáng)邏輯推理要求;吞
吐量是指每單元時(shí)間數(shù)據(jù)庫(kù)能夠并發(fā)處理多少事務(wù)。
FIT是如下進(jìn)行權(quán)衡:
保證公平性fairness 和隔離性isolation, 但是犧牲吞吐量
保證公平性fairness和吞吐量, 犧牲隔離性isolation
保證隔離性isolation和吞吐量throughput, 但是犧牲公平性fairness.
犧牲公平性:放棄公平性,數(shù)據(jù)庫(kù)能有更多機(jī)會(huì)降低分布式事務(wù)的成本,主要成本是分布式協(xié)調(diào)帶來(lái)的,也就是說(shuō),不需要在每個(gè)事務(wù)過(guò)程內(nèi)對(duì)每個(gè)機(jī)器都依
次確認(rèn)事務(wù)完成,這樣排隊(duì)式的確認(rèn)commit事務(wù)是很浪費(fèi)時(shí)間的,放棄公平性,意味著可以在事務(wù)外面進(jìn)行協(xié)調(diào),這樣就只是增加了協(xié)調(diào)時(shí)間,不會(huì)增加互相
沖突事務(wù)因?yàn)楸舜藳_突而不能運(yùn)行所耽擱的時(shí)間,當(dāng)系統(tǒng)不需要公平性時(shí),需要根據(jù)事務(wù)的優(yōu)先級(jí)或延遲等標(biāo)準(zhǔn)進(jìn)行指定先后執(zhí)行順序,這樣就能夠獲得很好的吞吐
量。
G-Store是一種放棄公平性的 Isolation-Throughput
的分布式key-value存儲(chǔ),支持多鍵事務(wù)(multi-key transactions),MongoDB 和
HBase在鍵key在同樣分區(qū)上也支持多鍵事務(wù),但是不支持跨分區(qū)的事務(wù)。
總之:傳統(tǒng)分布式事務(wù)性能不佳的原因是確保原子性(分布式協(xié)調(diào))和隔離性同時(shí)重疊,創(chuàng)建一個(gè)高吞吐量分布式事務(wù)的關(guān)鍵是分離這兩種關(guān)注,這種分離原
子性和隔離性的視角將導(dǎo)致兩種類(lèi)型的系統(tǒng),第一種選擇是弱隔離性能讓沖突事務(wù)并行執(zhí)行和確認(rèn)提交;第二個(gè)選擇重新排序原子性和隔離性機(jī)制保證它們不會(huì)某個(gè)
時(shí)間重疊,這是一種放棄公平的事務(wù)執(zhí)行,所謂放棄公平就是不再同時(shí)照顧原子性和隔離性了,有所傾斜,放棄高標(biāo)準(zhǔn)道德要求就會(huì)帶來(lái)高自由高效率。
最近與同行 科技 交流,經(jīng)常被問(wèn)到分庫(kù)分表與分布式數(shù)據(jù)庫(kù)如何選擇,網(wǎng)上也有很多關(guān)于中間件+傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)(分庫(kù)分表)與NewSQL分布式數(shù)據(jù)庫(kù)的文章,但有些觀(guān)點(diǎn)與判斷是我覺(jué)得是偏激的,脫離環(huán)境去評(píng)價(jià)方案好壞其實(shí)有失公允。
本文通過(guò)對(duì)兩種模式關(guān)鍵特性實(shí)現(xiàn)原理對(duì)比,希望可以盡可能客觀(guān)、中立的闡明各自真實(shí)的優(yōu)缺點(diǎn)以及適用場(chǎng)景。
首先關(guān)于“中間件+關(guān)系數(shù)據(jù)庫(kù)分庫(kù)分表”算不算NewSQL分布式數(shù)據(jù)庫(kù)問(wèn)題,國(guó)外有篇論文pavlo-newsql-sigmodrec,如果根據(jù)該文中的分類(lèi),Spanner、TiDB、OB算是第一種新架構(gòu)型,Sharding-Sphere、Mycat、DRDS等中間件方案算是第二種(文中還有第三種云數(shù)據(jù)庫(kù),本文暫不詳細(xì)介紹)。
基于中間件(包括SDK和Proxy兩種形式)+傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)(分庫(kù)分表)模式是不是分布式架構(gòu)?我覺(jué)得是的,因?yàn)榇鎯?chǔ)確實(shí)也分布式了,也能實(shí)現(xiàn)橫向擴(kuò)展。但是不是"偽"分布式數(shù)據(jù)庫(kù)?從架構(gòu)先進(jìn)性來(lái)看,這么說(shuō)也有一定道理。"偽"主要體現(xiàn)在中間件層與底層DB重復(fù)的SQL解析與執(zhí)行計(jì)劃生成、存儲(chǔ)引擎基于B+Tree等,這在分布式數(shù)據(jù)庫(kù)架構(gòu)中實(shí)際上冗余低效的。為了避免引起真?zhèn)畏植际綌?shù)據(jù)庫(kù)的口水戰(zhàn),本文中NewSQL數(shù)據(jù)庫(kù)特指這種新架構(gòu)NewSQL數(shù)據(jù)庫(kù)。
NewSQL數(shù)據(jù)庫(kù)相比中間件+分庫(kù)分表的先進(jìn)在哪兒?畫(huà)一個(gè)簡(jiǎn)單的架構(gòu)對(duì)比圖:
這些大多也是NewSQL數(shù)據(jù)庫(kù)產(chǎn)品主要宣傳的點(diǎn),不過(guò)這些看起來(lái)很美好的功能是否真的如此?接下來(lái)針對(duì)以上幾點(diǎn)分別闡述下的我的理解。
這是把雙刃劍。
CAP限制
想想更早些出現(xiàn)的NoSQL數(shù)據(jù)庫(kù)為何不支持分布式事務(wù)(最新版的mongoDB等也開(kāi)始支持了),是缺乏理論與實(shí)踐支撐嗎?并不是,原因是CAP定理依然是分布式數(shù)據(jù)庫(kù)頭上的頸箍咒,在保證強(qiáng)一致的同時(shí)必然會(huì)犧牲可用性A或分區(qū)容忍性P。為什么大部分NoSQL不提供分布式事務(wù)?
那么NewSQL數(shù)據(jù)庫(kù)突破CAP定理限制了嗎?并沒(méi)有。NewSQL數(shù)據(jù)庫(kù)的鼻主Google Spanner(目前絕大部分分布式數(shù)據(jù)庫(kù)都是按照Spanner架構(gòu)設(shè)計(jì)的)提供了一致性和大于5個(gè)9的可用性,宣稱(chēng)是一個(gè)“實(shí)際上是CA”的,其真正的含義是 系統(tǒng)處于 CA 狀態(tài)的概率非常高,由于網(wǎng)絡(luò)分區(qū)導(dǎo)致的服務(wù)停用的概率非常小 ,究其真正原因是其打造私有全球網(wǎng)保證了不會(huì)出現(xiàn)網(wǎng)絡(luò)中斷引發(fā)的網(wǎng)絡(luò)分區(qū),另外就是其高效的運(yùn)維隊(duì)伍,這也是cloud spanner的賣(mài)點(diǎn)。詳細(xì)可見(jiàn)CAP提出者Eric Brewer寫(xiě)的《Spanner, TrueTime 和CAP理論》。
完備性 :
兩階段提交協(xié)議是否嚴(yán)格支持ACID,各種異常場(chǎng)景是不是都可以覆蓋?
2PC在commit階段發(fā)送異常,其實(shí)跟最大努力一階段提交類(lèi)似也會(huì)有部分可見(jiàn)問(wèn)題,嚴(yán)格講一段時(shí)間內(nèi)并不能保證A原子性和C一致性(待故障恢復(fù)后recovery機(jī)制可以保證最終的A和C)。完備的分布式事務(wù)支持并不是一件簡(jiǎn)單的事情,需要可以應(yīng)對(duì)網(wǎng)絡(luò)以及各種硬件包括網(wǎng)卡、磁盤(pán)、CPU、內(nèi)存、電源等各類(lèi)異常,通過(guò)嚴(yán)格的測(cè)試。之前跟某友商交流,他們甚至說(shuō)目前已知的NewSQL在分布式事務(wù)支持上都是不完整的,他們都有案例跑不過(guò),圈內(nèi)人士這么篤定,也說(shuō)明了 分布式事務(wù)的支持完整程度其實(shí)是層次不齊的。
但分布式事務(wù)又是這些NewSQL數(shù)據(jù)庫(kù)的一個(gè)非常重要的底層機(jī)制,跨資源的DML、DDL等都依賴(lài)其實(shí)現(xiàn),如果這塊的性能、完備性打折扣,上層跨分片SQL執(zhí)行的正確性會(huì)受到很大影響。
性能
傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)也支持分布式事務(wù)XA,但為何很少有高并發(fā)場(chǎng)景下用呢? 因?yàn)閄A的基礎(chǔ)兩階段提交協(xié)議存在網(wǎng)絡(luò)開(kāi)銷(xiāo)大,阻塞時(shí)間長(zhǎng)、死鎖等問(wèn)題,這也導(dǎo)致了其實(shí)際上很少大規(guī)模用在基于傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的OLTP系統(tǒng)中。
NewSQL數(shù)據(jù)庫(kù)的分布式事務(wù)實(shí)現(xiàn)也仍然多基于兩階段提交協(xié)議,例如google percolator分布式事務(wù)模型,
采用原子鐘+MVCC+ Snapshot Isolation(SI),這種方式通過(guò)TSO(Timestamp Oracle)保證了全局一致性,通過(guò)MVCC避免了鎖,另外通過(guò)primary lock和secondary lock將提交的一部分轉(zhuǎn)為異步,相比XA確實(shí)提高了分布式事務(wù)的性能。
但不管如何優(yōu)化,相比于1PC,2PC多出來(lái)的GID獲取、網(wǎng)絡(luò)開(kāi)銷(xiāo)、prepare日志持久化還是會(huì)帶來(lái)很大的性能損失,尤其是跨節(jié)點(diǎn)的數(shù)量比較多時(shí)會(huì)更加顯著,例如在銀行場(chǎng)景做個(gè)批量扣款,一個(gè)文件可能上W個(gè)賬戶(hù),這樣的場(chǎng)景無(wú)論怎么做還是吞吐都不會(huì)很高。
雖然NewSQL分布式數(shù)據(jù)庫(kù)產(chǎn)品都宣傳完備支持分布式事務(wù),但這并不是說(shuō)應(yīng)用可以完全不用關(guān)心數(shù)據(jù)拆分,這些數(shù)據(jù)庫(kù)的最佳實(shí)踐中仍然會(huì)寫(xiě)到,應(yīng)用的大部分場(chǎng)景盡可能避免分布式事務(wù)。
既然強(qiáng)一致事務(wù)付出的性能代價(jià)太大,我們可以反思下是否真的需要這種強(qiáng)一致的分布式事務(wù)?尤其是在做微服務(wù)拆分后,很多系統(tǒng)也不太可能放在一個(gè)統(tǒng)一的數(shù)據(jù)庫(kù)中。嘗試將一致性要求弱化,便是柔性事務(wù),放棄ACID(Atomicity,Consistency, Isolation, Durability),轉(zhuǎn)投BASE(Basically Available,Soft state,Eventually consistent),例如Saga、TCC、可靠消息保證最終一致等模型,對(duì)于大規(guī)模高并發(fā)OLTP場(chǎng)景,我個(gè)人更建議使用柔性事務(wù)而非強(qiáng)一致的分布式事務(wù)。關(guān)于柔性事務(wù),筆者之前也寫(xiě)過(guò)一個(gè)技術(shù)組件,最近幾年也涌現(xiàn)出了一些新的模型與框架(例如阿里剛開(kāi)源的Fescar),限于篇幅不再贅述,有空再單獨(dú)寫(xiě)篇文章。
HA與異地多活
主從模式并不是最優(yōu)的方式,就算是半同步復(fù)制,在極端情況下(半同步轉(zhuǎn)異步)也存在丟數(shù)問(wèn)題,目前業(yè)界公認(rèn)更好的方案是基于paxos分布式一致性協(xié)議或者其它類(lèi)paxos如raft方式,Google Spanner、TiDB、cockcoachDB、OB都采用了這種方式,基于Paxos協(xié)議的多副本存儲(chǔ),遵循過(guò)半寫(xiě)原則,支持自動(dòng)選主,解決了數(shù)據(jù)的高可靠,縮短了failover時(shí)間,提高了可用性,特別是減少了運(yùn)維的工作量,這種方案技術(shù)上已經(jīng)很成熟,也是NewSQL數(shù)據(jù)庫(kù)底層的標(biāo)配。
當(dāng)然這種方式其實(shí)也可以用在傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù),阿里、微信團(tuán)隊(duì)等也有將MySQL存儲(chǔ)改造支持paxos多副本的,MySQL也推出了官方版MySQL Group Cluster,預(yù)計(jì)不遠(yuǎn)的未來(lái)主從模式可能就成為 歷史 了。
需要注意的是很多NewSQL數(shù)據(jù)庫(kù)廠(chǎng)商宣傳基于paxos或raft協(xié)議可以實(shí)現(xiàn)【異地多活】,這個(gè)實(shí)際上是有前提的,那就是異地之間網(wǎng)絡(luò)延遲不能太高 。以銀行“兩地三中心”為例,異地之間多相隔數(shù)千里,延時(shí)達(dá)到數(shù)十毫秒,如果要多活,那便需異地副本也參與數(shù)據(jù)庫(kù)日志過(guò)半確認(rèn),這樣高的延時(shí)幾乎沒(méi)有OLTP系統(tǒng)可以接受的。
數(shù)據(jù)庫(kù)層面做異地多活是個(gè)美好的愿景,但距離導(dǎo)致的延時(shí)目前并沒(méi)有好的方案。 之前跟螞蟻團(tuán)隊(duì)交流,螞蟻異地多活的方案是在應(yīng)用層通過(guò)MQ同步雙寫(xiě)交易信息,異地DC將交易信息保存在分布式緩存中,一旦發(fā)生異地切換,數(shù)據(jù)庫(kù)同步中間件會(huì)告之?dāng)?shù)據(jù)延遲時(shí)間,應(yīng)用從緩存中讀取交易信息,將這段時(shí)間內(nèi)涉及到的業(yè)務(wù)對(duì)象例如用戶(hù)、賬戶(hù)進(jìn)行黑名單管理,等數(shù)據(jù)同步追上之后再將這些業(yè)務(wù)對(duì)象從黑名單中剔除。由于雙寫(xiě)的不是所有數(shù)據(jù)庫(kù)操作日志而只是交易信息,數(shù)據(jù)延遲只影響一段時(shí)間內(nèi)數(shù)據(jù),這是目前我覺(jué)得比較靠譜的異地度多活方案。
另外有些系統(tǒng)進(jìn)行了單元化改造,這在paxos選主時(shí)也要結(jié)合考慮進(jìn)去,這也是目前很多NewSQL數(shù)據(jù)庫(kù)欠缺的功能。
Scale橫向擴(kuò)展與分片機(jī)制
paxos算法解決了高可用、高可靠問(wèn)題,并沒(méi)有解決Scale橫向擴(kuò)展的問(wèn)題,所以分片是必須支持的。NewSQL數(shù)據(jù)庫(kù)都是天生內(nèi)置分片機(jī)制的,而且會(huì)根據(jù)每個(gè)分片的數(shù)據(jù)負(fù)載(磁盤(pán)使用率、寫(xiě)入速度等)自動(dòng)識(shí)別熱點(diǎn),然后進(jìn)行分片的分裂、數(shù)據(jù)遷移、合并,這些過(guò)程應(yīng)用是無(wú)感知的,這省去了DBA的很多運(yùn)維工作量。以TiDB為例,它將數(shù)據(jù)切成region,如果region到64M時(shí),數(shù)據(jù)自動(dòng)進(jìn)行遷移。
分庫(kù)分表模式下需要應(yīng)用設(shè)計(jì)之初就要明確各表的拆分鍵、拆分方式(range、取模、一致性哈希或者自定義路由表)、路由規(guī)則、拆分庫(kù)表數(shù)量、擴(kuò)容方式等。相比NewSQL數(shù)據(jù)庫(kù),這種模式給應(yīng)用帶來(lái)了很大侵入和復(fù)雜度,這對(duì)大多數(shù)系統(tǒng)來(lái)說(shuō)也是一大挑戰(zhàn)。
這里有個(gè)問(wèn)題是NewSQL數(shù)據(jù)庫(kù)統(tǒng)一的內(nèi)置分片策略(例如tidb基于range)可能并不是最高效的,因?yàn)榕c領(lǐng)域模型中的劃分要素并不一致,這導(dǎo)致的后果是很多交易會(huì)產(chǎn)生分布式事務(wù)。 舉個(gè)例子,銀行核心業(yè)務(wù)系統(tǒng)是以客戶(hù)為維度,也就是說(shuō)客戶(hù)表、該客戶(hù)的賬戶(hù)表、流水表在絕大部分場(chǎng)景下是一起寫(xiě)的,但如果按照各表主鍵range進(jìn)行分片,這個(gè)交易并不能在一個(gè)分片上完成,這在高頻OLTP系統(tǒng)中會(huì)帶來(lái)性能問(wèn)題。
分布式SQL支持
常見(jiàn)的單分片SQL,這兩者都能很好支持。NewSQL數(shù)據(jù)庫(kù)由于定位與目標(biāo)是一個(gè)通用的數(shù)據(jù)庫(kù),所以支持的SQL會(huì)更完整,包括跨分片的join、聚合等復(fù)雜SQL。中間件模式多面向應(yīng)用需求設(shè)計(jì),不過(guò)大部分也支持帶拆分鍵SQL、庫(kù)表遍歷、單庫(kù)join、聚合、排序、分頁(yè)等。但對(duì)跨庫(kù)的join以及聚合支持就不夠了。
NewSQL數(shù)據(jù)庫(kù)一般并不支持存儲(chǔ)過(guò)程、視圖、外鍵等功能,而中間件模式底層就是傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù),這些功能如果只是涉及單庫(kù)是比較容易支持的。
NewSQL數(shù)據(jù)庫(kù)往往選擇兼容MySQL或者PostgreSQL協(xié)議,所以SQL支持僅局限于這兩種,中間件例如驅(qū)動(dòng)模式往往只需做簡(jiǎn)單的SQL解析、計(jì)算路由、SQL重寫(xiě),所以可以支持更多種類(lèi)的數(shù)據(jù)庫(kù)SQL。
SQL支持的差異主要在于分布式SQL執(zhí)行計(jì)劃生成器,由于NewSQL數(shù)據(jù)庫(kù)具有底層數(shù)據(jù)的分布、統(tǒng)計(jì)信息,因此可以做CBO,生成的執(zhí)行計(jì)劃效率更高,而中間件模式下沒(méi)有這些信息,往往只能基于規(guī)則RBO(Rule-Based-Opimization),這也是為什么中間件模式一般并不支持跨庫(kù)join,因?yàn)閷?shí)現(xiàn)了效率也往往并不高,還不如交給應(yīng)用去做。
存儲(chǔ)引擎
傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的存儲(chǔ)引擎設(shè)計(jì)都是面向磁盤(pán)的,大多都基于B+樹(shù)。B+樹(shù)通過(guò)降低樹(shù)的高度減少隨機(jī)讀、進(jìn)而減少磁盤(pán)尋道次數(shù),提高讀的性能,但大量的隨機(jī)寫(xiě)會(huì)導(dǎo)致樹(shù)的分裂,從而帶來(lái)隨機(jī)寫(xiě),導(dǎo)致寫(xiě)性能下降。NewSQL的底層存儲(chǔ)引擎則多采用LSM,相比B+樹(shù)LSM將對(duì)磁盤(pán)的隨機(jī)寫(xiě)變成順序?qū)?,大大提高了?xiě)的性能。不過(guò)LSM的的讀由于需要合并數(shù)據(jù)性能比B+樹(shù)差,一般來(lái)說(shuō)LSM更適合應(yīng)在寫(xiě)大于讀的場(chǎng)景。當(dāng)然這只是單純數(shù)據(jù)結(jié)構(gòu)角度的對(duì)比,在數(shù)據(jù)庫(kù)實(shí)際實(shí)現(xiàn)時(shí)還會(huì)通過(guò)SSD、緩沖、bloom filter等方式優(yōu)化讀寫(xiě)性能,所以讀性能基本不會(huì)下降太多。NewSQL數(shù)據(jù)由于多副本、分布式事務(wù)等開(kāi)銷(xiāo),相比單機(jī)關(guān)系數(shù)據(jù)庫(kù)SQL的響應(yīng)時(shí)間并不占優(yōu),但由于集群的彈性擴(kuò)展,整體QPS提升還是很明顯的,這也是NewSQL數(shù)據(jù)庫(kù)廠(chǎng)商說(shuō)分布式數(shù)據(jù)庫(kù)更看重的是吞吐,而不是單筆SQL響應(yīng)時(shí)間的原因。
成熟度與生態(tài)
分布式數(shù)據(jù)庫(kù)是個(gè)新型通用底層軟件,準(zhǔn)確的衡量與評(píng)價(jià)需要一個(gè)多維度的測(cè)試模型,需包括發(fā)展現(xiàn)狀、使用情況、社區(qū)生態(tài)、監(jiān)控運(yùn)維、周邊配套工具、功能滿(mǎn)足度、DBA人才、SQL兼容性、性能測(cè)試、高可用測(cè)試、在線(xiàn)擴(kuò)容、分布式事務(wù)、隔離級(jí)別、在線(xiàn)DDL等等,雖然NewSQL數(shù)據(jù)庫(kù)發(fā)展經(jīng)過(guò)了一定時(shí)間檢驗(yàn),但多集中在互聯(lián)網(wǎng)以及傳統(tǒng)企業(yè)非核心交易系統(tǒng)中,目前還處于快速迭代、規(guī)模使用不斷優(yōu)化完善的階段。
相比而言,傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)則經(jīng)過(guò)了多年的發(fā)展,通過(guò)完整的評(píng)測(cè),在成熟度、功能、性能、周邊生態(tài)、風(fēng)險(xiǎn)把控、相關(guān)人才積累等多方面都具有明顯優(yōu)勢(shì),同時(shí)對(duì)已建系統(tǒng)的兼容性也更好。
對(duì)于互聯(lián)網(wǎng)公司,數(shù)據(jù)量的增長(zhǎng)壓力以及追求新技術(shù)的基因會(huì)更傾向于嘗試NewSQL數(shù)據(jù)庫(kù),不用再考慮庫(kù)表拆分、應(yīng)用改造、擴(kuò)容、事務(wù)一致性等問(wèn)題怎么看都是非常吸引人的方案。
對(duì)于傳統(tǒng)企業(yè)例如銀行這種風(fēng)險(xiǎn)意識(shí)較高的行業(yè)來(lái)說(shuō),NewSQL數(shù)據(jù)庫(kù)則可能在未來(lái)一段時(shí)間內(nèi)仍處于 探索 、審慎試點(diǎn)的階段?;谥虚g件+分庫(kù)分表模式架構(gòu)簡(jiǎn)單,技術(shù)門(mén)檻更低,雖然沒(méi)有NewSQL數(shù)據(jù)庫(kù)功能全面,但大部分場(chǎng)景最核心的訴求也就是拆分后SQL的正確路由,而此功能中間件模式應(yīng)對(duì)還是綽綽有余的,可以說(shuō)在大多數(shù)OLTP場(chǎng)景是夠用的。
限于篇幅,其它特性例如在線(xiàn)DDL、數(shù)據(jù)遷移、運(yùn)維工具等特性就不在本文展開(kāi)對(duì)比。
總結(jié)
如果看完以上內(nèi)容,您還不知道選哪種模式,那么結(jié)合以下幾個(gè)問(wèn)題,先思考下NewSQL數(shù)據(jù)庫(kù)解決的點(diǎn)對(duì)于自身是不是真正的痛點(diǎn):
如果以上有2到3個(gè)是肯定的,那么你可以考慮用NewSQL數(shù)據(jù)庫(kù)了,雖然前期可能需要一定的學(xué)習(xí)成本,但它是數(shù)據(jù)庫(kù)的發(fā)展方向,未來(lái)收益也會(huì)更高,尤其是互聯(lián)網(wǎng)行業(yè),隨著數(shù)據(jù)量的突飛猛進(jìn),分庫(kù)分表帶來(lái)的痛苦會(huì)與日俱增。當(dāng)然選擇NewSQL數(shù)據(jù)庫(kù)你也要做好承擔(dān)一定風(fēng)險(xiǎn)的準(zhǔn)備。
如果你還未做出抉擇,不妨再想想下面幾個(gè)問(wèn)題:
如果這些問(wèn)題有多數(shù)是肯定的,那還是分庫(kù)分表吧。在軟件領(lǐng)域很少有完美的解決方案,NewSQL數(shù)據(jù)庫(kù)也不是數(shù)據(jù)分布式架構(gòu)的銀彈。相比而言分庫(kù)分表是一個(gè)代價(jià)更低、風(fēng)險(xiǎn)更小的方案,它最大程度復(fù)用傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)生態(tài),通過(guò)中間件也可以滿(mǎn)足分庫(kù)分表后的絕大多數(shù)功能,定制化能力更強(qiáng)。 在當(dāng)前NewSQL數(shù)據(jù)庫(kù)還未完全成熟的階段,分庫(kù)分表可以說(shuō)是一個(gè)上限低但下限高的方案,尤其傳統(tǒng)行業(yè)的核心系統(tǒng),如果你仍然打算把數(shù)據(jù)庫(kù)當(dāng)做一個(gè)黑盒產(chǎn)品來(lái)用,踏踏實(shí)實(shí)用好分庫(kù)分表會(huì)被認(rèn)為是個(gè)穩(wěn)妥的選擇。
很多時(shí)候軟件選型取決于領(lǐng)域特征以及架構(gòu)師風(fēng)格,限于筆者知識(shí)與所屬行業(yè)特點(diǎn)所限,以上僅為個(gè)人粗淺的一些觀(guān)點(diǎn),歡迎討論。
這兩年來(lái),隨著NoSQL系統(tǒng)、CAP理論和Eventual Consistency的大熱,關(guān)于分布式操作要保證強(qiáng)一致還是弱一致性的討論絡(luò)驛不絕。雙方各執(zhí)一詞,傾向?qū)崿F(xiàn)強(qiáng)一致性的一方認(rèn)為弱一致性滿(mǎn)足不了應(yīng)用開(kāi)發(fā)的需要,傾向?qū)崿F(xiàn)弱一致性的一方則認(rèn)為保證強(qiáng)一致性將導(dǎo)致系統(tǒng)性能與可伸縮性難以接受。弱一致性能否滿(mǎn)足應(yīng)用開(kāi)發(fā)的需求這一點(diǎn)由應(yīng)用特征決定,難以一概而論,但強(qiáng)一致性對(duì)系統(tǒng)性能、可伸縮性和可用性的影響則是可以作技術(shù)分析的。奇怪的是,找了很久,也沒(méi)找到對(duì)這一問(wèn)題的深入分析,決定自己來(lái)做一個(gè)。
對(duì)于分布式操作,一般來(lái)說(shuō)有以下兩種實(shí)現(xiàn)選擇:
1、 在每個(gè)節(jié)點(diǎn)上使用單獨(dú)的事務(wù),只實(shí)現(xiàn)弱一致性。
2、 使用2PC保證強(qiáng)一致性。即分布式事務(wù)協(xié)調(diào)者先要求所有參與節(jié)點(diǎn)PREPARE,大家都說(shuō)PREPARE成功后,再要求所有節(jié)點(diǎn)COMMIT。只要有一個(gè)節(jié)點(diǎn)PREPARE不成功,大家都要回滾。這樣參與者要強(qiáng)制寫(xiě)兩次日志,協(xié)調(diào)者在決定要COMMIT時(shí)也要強(qiáng)制寫(xiě)一次日志。
首先,假設(shè)用戶(hù)發(fā)起分布式操作的速率為T(mén)pS(Transactions per Second),每個(gè)分布式操作平均會(huì)操作K個(gè)節(jié)點(diǎn)。在每個(gè)節(jié)點(diǎn)上,平均要操作RpT(Rows per Transaction)條記錄,而操作每條記錄平均要用時(shí)TpR(Time per Row),這樣在每個(gè)節(jié)點(diǎn)上事務(wù)操作的執(zhí)行時(shí)間為:
TExec=RpT×TpR
另外,設(shè)定以下參數(shù):
- N:數(shù)據(jù)庫(kù)中所有節(jié)點(diǎn)上的總記錄數(shù)
- TCommit:在每個(gè)節(jié)點(diǎn)上PREPARE或COMMIT的時(shí)間,PREPARE和COMMIT的主要工作都是寫(xiě)相應(yīng)的日志,執(zhí)行時(shí)間接近
對(duì)分布式操作性能方面一種常見(jiàn)的認(rèn)識(shí)是若使用2PC,將導(dǎo)致事務(wù)執(zhí)行時(shí)間大為延長(zhǎng),從而導(dǎo)致過(guò)高的事務(wù)并發(fā)沖突和死鎖。當(dāng)然,從趨勢(shì)上使用2PC自然會(huì)導(dǎo)致并發(fā)沖突和死鎖增長(zhǎng),但是否能滿(mǎn)足應(yīng)用需求,需要定量的來(lái)分析。由于死鎖的概率完全取決于沖突概率,以下只分析沖突概率。
對(duì)選擇1,即每個(gè)節(jié)點(diǎn)用獨(dú)立事務(wù)時(shí),用戶(hù)發(fā)起的每個(gè)事務(wù)都會(huì)被分成K個(gè)小事務(wù),這時(shí)系統(tǒng)中的并發(fā)事務(wù)數(shù)是事務(wù)速率與事務(wù)持續(xù)時(shí)間之積,即:
CT_1=TpS×K×(RpT×TpR+TCommit)
當(dāng)某事務(wù)要鎖定并操作某條記錄時(shí),系統(tǒng)中被其它事務(wù)所鎖定的記錄數(shù)是(CT_1-1)×RpT≈CT_1×RpT。假設(shè)事務(wù)操作的記錄是純隨機(jī)的,則該事務(wù)要鎖定的記錄與其它事務(wù)沖突的概率是(CT_1×RpT)/N。而這個(gè)事務(wù)總共要鎖定RpT條記錄,則該事務(wù)與其它事務(wù)沖突的概率是:
TWait_1=1-(1-(CT_1×RpT)/N )^RpT≈CT_1×RpT^2/N
對(duì)選擇2,即使用2PC保證強(qiáng)一致性時(shí),每個(gè)節(jié)點(diǎn)上需要強(qiáng)制寫(xiě)兩次日志,在事務(wù)協(xié)調(diào)者上還要強(qiáng)制寫(xiě)一次PREPARE日志(事務(wù)協(xié)調(diào)者上的COMMIT日志不需要強(qiáng)制寫(xiě),這一時(shí)間可以忽略)。系統(tǒng)中的并發(fā)事務(wù)數(shù)是:
CT_2=TpS×((RpT×TpR+2×TCommit)×K+TCommit)
但此時(shí)系統(tǒng)中被其它事務(wù)所鎖定的記錄數(shù)是選擇1的K倍,且事務(wù)要鎖定的記錄數(shù)也是選擇1的K倍,這時(shí)事務(wù)的沖突概率是:
TWait_2≈CT_2×RpT^2×K^2/N
這個(gè)公式比較復(fù)雜,我們先簡(jiǎn)化一下,假設(shè)TCommit和TPrepare時(shí)間相對(duì)于TExec來(lái)說(shuō)可以忽略,則可以得到有:
TWait_2=TWait_1×K^2
也就是說(shuō)事務(wù)沖突的概率將會(huì)隨著分布式操作涉及的節(jié)點(diǎn)數(shù)K的平方數(shù)增長(zhǎng)。平方數(shù)增長(zhǎng)聽(tīng)起來(lái)比較厲害,但實(shí)際上在真實(shí)應(yīng)用中K通常是很小的,絕大多數(shù)情況下等于2。如經(jīng)典的轉(zhuǎn)賬問(wèn)題,就只涉及兩個(gè)節(jié)點(diǎn),還有比如建立好友關(guān)系時(shí)也只涉及兩個(gè)節(jié)點(diǎn)。在使用我們分布式數(shù)據(jù)庫(kù)的大量應(yīng)用中(總共包含約500張表,上千個(gè)索引,幾千種SQL模式),絕大多數(shù)情況下K為2,很少有3,超過(guò)3的更是絕無(wú)僅有。因此,如果我們忽略2PC PREPARE和提交的時(shí)間,則使用2PC時(shí)會(huì)導(dǎo)致事務(wù)沖突概率4~9倍的增長(zhǎng)。
換一種情況,如果執(zhí)行很快但提交寫(xiě)日志很慢,即TExec相對(duì)于TCommit來(lái)說(shuō)可以忽略,則可以得到:
TWait_2=TWait_1×(2×K+1)/K×K^2
這時(shí)的情況比只考慮執(zhí)行時(shí)間時(shí)差一些,但還是隨著分布式操作涉及的節(jié)點(diǎn)數(shù)K的平方數(shù)增長(zhǎng),只不過(guò)從4~9倍變成10~21倍。
真實(shí)的情況一般在這兩者之間,作為估算,可以大致認(rèn)為采用2PC保證強(qiáng)一致性時(shí)將導(dǎo)致事務(wù)沖突概率增加8倍左右。
性能方面還涉及到吞吐率和響應(yīng)時(shí)間。類(lèi)似的進(jìn)行分析,可以發(fā)現(xiàn)如果TCommit相對(duì)于TExec可以忽略,則響應(yīng)時(shí)間不受2PC影響,反之,則2PC會(huì)導(dǎo)致響應(yīng)時(shí)間增加為原來(lái)的3倍,平均的估計(jì)可以取增加1倍。對(duì)大多數(shù)應(yīng)用,日志提交的吞吐率完全足夠,則事務(wù)吞吐率不受2PC影響,反之,事務(wù)吞吐率會(huì)下降一半。
對(duì)大多數(shù)WEB應(yīng)用沖突概率非常低,分布式操作只涉及2~3個(gè)節(jié)點(diǎn),日志提交的吞吐率完全足夠,則使用2PC可能帶來(lái)的影響是事務(wù)沖突與死鎖增加8倍左右,響應(yīng)時(shí)間延長(zhǎng)1倍,吞吐率不受影響。這些性能影響應(yīng)該說(shuō)是完全可以接受的,此時(shí)2PC帶來(lái)的強(qiáng)一致性?xún)?yōu)點(diǎn)可以說(shuō)遠(yuǎn)遠(yuǎn)超過(guò)其對(duì)性能的影響。
當(dāng)然,以上分析中忽略了很多因素,比如網(wǎng)絡(luò)延時(shí),比如客戶(hù)端在發(fā)起事務(wù)的多個(gè)操作之間還可能休息一會(huì)。加入這些因素后的性能分析會(huì)更復(fù)雜,但這些因素,本質(zhì)上是使事務(wù)的持續(xù)時(shí)間增加,跟是否使用2PC無(wú)關(guān)。使用2PC與不使用2PC之間的性能差異比例,與這些因素關(guān)系不大。
但有一個(gè)問(wèn)題需要注意。如果讓客戶(hù)端直接充當(dāng)分布式事務(wù)的協(xié)調(diào)者,由于客戶(hù)端上通常不像數(shù)據(jù)庫(kù)服務(wù)器那樣配置帶電池的寫(xiě)緩存,fsync的性能很差,2PC將導(dǎo)致簡(jiǎn)單分布式事務(wù)的響應(yīng)時(shí)間增加一個(gè)數(shù)量級(jí),沖突概率更是可能增加兩個(gè)數(shù)量級(jí),事務(wù)提交的吞吐率也可能受到影響。解決方法是部署專(zhuān)職的高性能分布式事務(wù)協(xié)調(diào)者集群,配置高性能的日志存儲(chǔ)設(shè)備如SSD。
基于這一基本的性能分析,還有一些變種:
1、如果分布式操作在各節(jié)點(diǎn)上并行執(zhí)行,可以計(jì)算出沖突概率將是不并行的1/K。這仍比不用2PC串行高K倍,但不再是K的平方倍。比如BigTable中對(duì)二級(jí)索引和主記錄的修改,就可以并行。
2、如果分布式操作是否沖突只取決于其中一個(gè)節(jié)點(diǎn),可以計(jì)算出2PC并不會(huì)導(dǎo)致沖突概率顯著增加。符合這一特征的應(yīng)用模式還是BigTable中對(duì)主記錄及其所有二級(jí)索引的修改,沖不沖突,完全取決于是否更新同一條記錄,跟索引無(wú)關(guān)。
根據(jù)這兩點(diǎn)也可以看出,如果用并行的2PC來(lái)保證主記錄及其二級(jí)索引之間的一致性,其所帶來(lái)的性能影響弱于2PC對(duì)一般分布式事務(wù)的影響,是完全可以實(shí)用的方案。
對(duì)使用2PC分布式事務(wù)的另外一個(gè)比較大的擔(dān)心是如果2PC在PREPARE之后事務(wù)協(xié)調(diào)者崩潰,則參與分布式事務(wù)的各個(gè)節(jié)點(diǎn)只能長(zhǎng)時(shí)間的鎖定資源,等待協(xié)調(diào)者復(fù)活后告訴它事務(wù)應(yīng)該提交還是回滾。如果直接讓客戶(hù)端直接充當(dāng)分布式事務(wù)的協(xié)調(diào)者,這一問(wèn)題可能很?chē)?yán)重,因?yàn)榭蛻?hù)端多而雜,崩潰概率高。但如果部署了專(zhuān)職的高性能分布式事務(wù)協(xié)調(diào)者集群,則這一問(wèn)題基本可以避免。
1 基本思想之什么是分庫(kù)分表?
從字面上簡(jiǎn)單理解,就是把原本存儲(chǔ)于一個(gè)庫(kù)的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)庫(kù)上,把原本存儲(chǔ)于一個(gè)表的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)表上。
2 基本思想之為什么要分庫(kù)分表?
數(shù)
據(jù)庫(kù)中的數(shù)據(jù)量不一定是可控的,在未進(jìn)行分庫(kù)分表的情況下,隨著時(shí)間和業(yè)務(wù)的發(fā)展,庫(kù)中的表會(huì)越來(lái)越多,表中的數(shù)據(jù)量也會(huì)越來(lái)越大,相應(yīng)地,數(shù)據(jù)操作,增
刪改查的開(kāi)銷(xiāo)也會(huì)越來(lái)越大;另外,由于無(wú)法進(jìn)行分布式式部署,而一臺(tái)服務(wù)器的資源(CPU、磁盤(pán)、內(nèi)存、IO等)是有限的,最終數(shù)據(jù)庫(kù)所能承載的數(shù)據(jù)量、
數(shù)據(jù)處理能力都將遭遇瓶頸。
3 分庫(kù)分表的實(shí)施策略。
分庫(kù)分表有垂直切分和水平切分兩種。
3.1
何謂垂直切分,即將表按照功能模塊、關(guān)系密切程度劃分出來(lái),部署到不同的庫(kù)上。例如,我們會(huì)建立定義數(shù)據(jù)庫(kù)workDB、商品數(shù)據(jù)庫(kù)payDB、用戶(hù)數(shù)據(jù)
庫(kù)userDB、日志數(shù)據(jù)庫(kù)logDB等,分別用于存儲(chǔ)項(xiàng)目數(shù)據(jù)定義表、商品定義表、用戶(hù)數(shù)據(jù)表、日志數(shù)據(jù)表等。
3.2
何謂水平切分,當(dāng)一個(gè)表中的數(shù)據(jù)量過(guò)大時(shí),我們可以把該表的數(shù)據(jù)按照某種規(guī)則,例如userID散列,進(jìn)行劃分,然后存儲(chǔ)到多個(gè)結(jié)構(gòu)相同的表,和不同的庫(kù)
上。例如,我們的userDB中的用戶(hù)數(shù)據(jù)表中,每一個(gè)表的數(shù)據(jù)量都很大,就可以把userDB切分為結(jié)構(gòu)相同的多個(gè)userDB:part0DB、
part1DB等,再將userDB上的用戶(hù)數(shù)據(jù)表userTable,切分為很多userTable:userTable0、userTable1等,
然后將這些表按照一定的規(guī)則存儲(chǔ)到多個(gè)userDB上。
3.3 應(yīng)該使用哪一種方式來(lái)實(shí)施數(shù)據(jù)庫(kù)分庫(kù)分表,這要看數(shù)據(jù)庫(kù)中數(shù)據(jù)量的瓶頸所在,并綜合項(xiàng)目的業(yè)務(wù)類(lèi)型進(jìn)行考慮。
如果數(shù)據(jù)庫(kù)是因?yàn)楸硖喽斐珊A繑?shù)據(jù),并且項(xiàng)目的各項(xiàng)業(yè)務(wù)邏輯劃分清晰、低耦合,那么規(guī)則簡(jiǎn)單明了、容易實(shí)施的垂直切分必是首選。
而
如果數(shù)據(jù)庫(kù)中的表并不多,但單表的數(shù)據(jù)量很大、或數(shù)據(jù)熱度很高,這種情況之下就應(yīng)該選擇水平切分,水平切分比垂直切分要復(fù)雜一些,它將原本邏輯上屬于一體
的數(shù)據(jù)進(jìn)行了物理分割,除了在分割時(shí)要對(duì)分割的粒度做好評(píng)估,考慮數(shù)據(jù)平均和負(fù)載平均,后期也將對(duì)項(xiàng)目人員及應(yīng)用程序產(chǎn)生額外的數(shù)據(jù)管理負(fù)擔(dān)。
在現(xiàn)實(shí)項(xiàng)目中,往往是這兩種情況兼而有之,這就需要做出權(quán)衡,甚至既需要垂直切分,又需要水平切分。我們的游戲項(xiàng)目便綜合使用了垂直與水平切分,我們首先對(duì)數(shù)據(jù)庫(kù)進(jìn)行垂直切分,然后,再針對(duì)一部分表,通常是用戶(hù)數(shù)據(jù)表,進(jìn)行水平切分。
4 分庫(kù)分表存在的問(wèn)題。
4.1 事務(wù)問(wèn)題。
在執(zhí)行分庫(kù)分表之后,由于數(shù)據(jù)存儲(chǔ)到了不同的庫(kù)上,數(shù)據(jù)庫(kù)事務(wù)管理出現(xiàn)了困難。如果依賴(lài)數(shù)據(jù)庫(kù)本身的分布式事務(wù)管理功能去執(zhí)行事務(wù),將付出高昂的性能代價(jià);如果由應(yīng)用程序去協(xié)助控制,形成程序邏輯上的事務(wù),又會(huì)造成編程方面的負(fù)擔(dān)。
4.2 跨庫(kù)跨表的join問(wèn)題。
在執(zhí)行了分庫(kù)分表之后,難以避免會(huì)將原本邏輯關(guān)聯(lián)性很強(qiáng)的數(shù)據(jù)劃分到不同的表、不同的庫(kù)上,這時(shí),表的關(guān)聯(lián)操作將受到限制,我們無(wú)法join位于不同分庫(kù)的表,也無(wú)法join分表粒度不同的表,結(jié)果原本一次查詢(xún)能夠完成的業(yè)務(wù),可能需要多次查詢(xún)才能完成。
4.3 額外的數(shù)據(jù)管理負(fù)擔(dān)和數(shù)據(jù)運(yùn)算壓力。
額
外的數(shù)據(jù)管理負(fù)擔(dān),最顯而易見(jiàn)的就是數(shù)據(jù)的定位問(wèn)題和數(shù)據(jù)的增刪改查的重復(fù)執(zhí)行問(wèn)題,這些都可以通過(guò)應(yīng)用程序解決,但必然引起額外的邏輯運(yùn)算,例如,對(duì)于
一個(gè)記錄用戶(hù)成績(jī)的用戶(hù)數(shù)據(jù)表userTable,業(yè)務(wù)要求查出成績(jī)最好的100位,在進(jìn)行分表之前,只需一個(gè)order
by語(yǔ)句就可以搞定,但是在進(jìn)行分表之后,將需要n個(gè)order
by語(yǔ)句,分別查出每一個(gè)分表的前100名用戶(hù)數(shù)據(jù),然后再對(duì)這些數(shù)據(jù)進(jìn)行合并計(jì)算,才能得出結(jié)果。