您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“分庫分表與NewSQL怎么選擇”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“分庫分表與NewSQL怎么選擇”吧!
NewSQL 數(shù)據(jù)庫先進(jìn)在哪兒?
首先關(guān)于“中間件+關(guān)系數(shù)據(jù)庫分庫分表”算不算 NewSQL 分布式數(shù)據(jù)庫問題,國外有篇論文 pavlo-newsql-sigmodrec:
https://db.cs.cmu.edu/papers/2016/pavlo-newsql-sigmodrec2016.pdf
如果根據(jù)該文中的分類,Spanner、TiDB、OB 算是第一種新架構(gòu)型,Sharding-Sphere、Mycat、DRDS 等中間件方案算是第二種(文中還有第三種云數(shù)據(jù)庫,本文暫不詳細(xì)介紹)。
基于中間件(包括 SDK 和 Proxy 兩種形式)+傳統(tǒng)關(guān)系數(shù)據(jù)庫(分庫分表)模式是不是分布式架構(gòu)?
我覺得是的,因為存儲確實也分布式了,也能實現(xiàn)橫向擴(kuò)展。但是不是"偽"分布式數(shù)據(jù)庫?從架構(gòu)先進(jìn)性來看,這么說也有一定道理。
"偽"主要體現(xiàn)在中間件層與底層 DB 重復(fù)的 SQL 解析與執(zhí)行計劃生成、存儲引擎基于 B+Tree 等,這在分布式數(shù)據(jù)庫架構(gòu)中實際上冗余低效的。
為了避免引起真?zhèn)畏植际綌?shù)據(jù)庫的口水戰(zhàn),本文中 NewSQL 數(shù)據(jù)庫特指這種新架構(gòu) NewSQL 數(shù)據(jù)庫。
NewSQL 數(shù)據(jù)庫相比中間件+分庫分表的先進(jìn)在哪兒?畫一個簡單的架構(gòu)對比圖:
傳統(tǒng)數(shù)據(jù)庫面向磁盤設(shè)計,基于內(nèi)存的存儲管理及并發(fā)控制,不如 NewSQL 數(shù)據(jù)庫那般高效利用。
中間件模式 SQL 解析、執(zhí)行計劃優(yōu)化等在中間件與數(shù)據(jù)庫中重復(fù)工作,效率相比較低。
NewSQL 數(shù)據(jù)庫的分布式事務(wù)相比于 XA 進(jìn)行了優(yōu)化,性能更高。
新架構(gòu) NewSQL 數(shù)據(jù)庫存儲設(shè)計即為基于 Paxos(或 Raft)協(xié)議的多副本,相比于傳統(tǒng)數(shù)據(jù)庫主從模式(半同步轉(zhuǎn)異步后也存在丟數(shù)問題),在實現(xiàn)了真正的高可用、高可靠(RTO<30s,RPO=0)。
NewSQL 數(shù)據(jù)庫天生支持?jǐn)?shù)據(jù)分片,數(shù)據(jù)的遷移、擴(kuò)容都是自動化的,大大減輕了 DBA 的工作,同時對應(yīng)用透明,無需在 SQL 指定分庫分表鍵。
這些大多也是 NewSQL 數(shù)據(jù)庫產(chǎn)品主要宣傳的點,不過這些看起來很美好的功能是否真的如此?接下來針對以上幾點分別闡述下的我的理解。
分布式事務(wù)
首先要說的就是分布式事務(wù):這是一把雙刃劍。
CAP 限制
想想更早些出現(xiàn)的 NoSQL 數(shù)據(jù)庫為何不支持分布式事務(wù)(最新版的 MongoDB 等也開始支持了),是缺乏理論與實踐支撐嗎?
并不是,原因是 CAP 定理依然是分布式數(shù)據(jù)庫頭上的頸箍咒,在保證強(qiáng)一致的同時必然會犧牲可用性 A 或分區(qū)容忍性 P。
為什么大部分 NoSQL 不提供分布式事務(wù)?那么 NewSQL 數(shù)據(jù)庫突破 CAP 定理限制了嗎?并沒有。
NewSQL 數(shù)據(jù)庫的鼻主 Google Spanner(目前絕大部分分布式數(shù)據(jù)庫都是按照 Spanner 架構(gòu)設(shè)計的)提供了一致性和大于 5 個 9 的可用性,宣稱是一個“實際上是 CA”的。
其真正的含義是系統(tǒng)處于 CA 狀態(tài)的概率高由于網(wǎng)絡(luò)分區(qū)導(dǎo)致的服務(wù)停用的概率非常小,究其真正原因是其打造私有全球網(wǎng)保證了不會出現(xiàn)網(wǎng)絡(luò)中斷引發(fā)的網(wǎng)絡(luò)分區(qū)。
其中提到:分布式系統(tǒng)中,您可以知道工作在哪里,或者您可以知道工作何時完成,但您無法同時了解兩者;兩階段協(xié)議本質(zhì)上是反可用性協(xié)議。
完備性
兩階段提交協(xié)議是否嚴(yán)格支持 ACID,各種異常場景是不是都可以覆蓋?
2PC 在 Commit 階段發(fā)送異常,其實跟最大努力一階段提交類似也會有部分可見問題,嚴(yán)格講一段時間內(nèi)并不能保證 A 原子性和 C 一致性(待故障恢復(fù)后 Recovery 機(jī)制可以保證最終的 A 和 C)。
完備的分布式事務(wù)支持并不是一件簡單的事情,需要可以應(yīng)對網(wǎng)絡(luò)以及各種硬件包括網(wǎng)卡、磁盤、CPU、內(nèi)存、電源等各類異常,通過嚴(yán)格的測試。
之前跟某友商交流,他們甚至說目前已知的 NewSQL 在分布式事務(wù)支持上都是不完整的,他們都有案例跑不過,圈內(nèi)人士這么篤定,也說明了分布式事務(wù)的支持完整程度其實是層次不齊的。
但分布式事務(wù)又是這些 NewSQL 數(shù)據(jù)庫的一個非常重要的底層機(jī)制,跨資源的 DML、DDL 等都依賴其實現(xiàn),如果這塊的性能、完備性打折扣,上層跨分片 SQL 執(zhí)行的正確性會受到很大影響。
性能
傳統(tǒng)關(guān)系數(shù)據(jù)庫也支持分布式事務(wù) XA,但為何很少有高并發(fā)場景下用呢?
因為 XA 的基礎(chǔ)兩階段提交協(xié)議存在網(wǎng)絡(luò)開銷大,阻塞時間長、死鎖等問題,這也導(dǎo)致了其實際上很少大規(guī)模用在基于傳統(tǒng)關(guān)系數(shù)據(jù)庫的 OLTP 系統(tǒng)中。
NewSQL 數(shù)據(jù)庫的分布式事務(wù)實現(xiàn)也仍然多基于兩階段提交協(xié)議,例如 google percolator 分布式事務(wù)模型,采用原子鐘+MVCC+Snapshot Isolation(SI)。
這種方式通過 TSO(Timestamp Oracle)保證了全局一致性,通過 MVCC 避免了鎖,另外通過 primary lock 和 secondary lock 將提交的一部分轉(zhuǎn)為異步,相比 XA 確實提高了分布式事務(wù)的性能。
SI 是樂觀鎖,在熱點數(shù)據(jù)場景,可能會大量的提交失敗。另外 SI 的隔離級別與 RR 并無完全相同,它不會有幻想讀,但會有寫傾斜。
但不管如何優(yōu)化,相比于 1PC,2PC 多出來的 GID 獲取、網(wǎng)絡(luò)開銷、prepare 日志持久化還是會帶來很大的性能損失,尤其是跨節(jié)點的數(shù)量比較多時會更加顯著。
例如在銀行場景做個批量扣款,一個文件可能上 W 個賬戶,這樣的場景無論怎么做還是吞吐都不會很高。
Spanner 給出的分布式事務(wù)測試數(shù)據(jù):
雖然 NewSQL 分布式數(shù)據(jù)庫產(chǎn)品都宣傳完備支持分布式事務(wù),但這并不是說應(yīng)用可以完全不用關(guān)心數(shù)據(jù)拆分,這些數(shù)據(jù)庫的最佳實踐中仍然會寫到,應(yīng)用的大部分場景盡可能避免分布式事務(wù)。
既然強(qiáng)一致事務(wù)付出的性能代價太大,我們可以反思下是否真的需要這種強(qiáng)一致的分布式事務(wù)?
尤其是在做微服務(wù)拆分后,很多系統(tǒng)也不太可能放在一個統(tǒng)一的數(shù)據(jù)庫中。
嘗試將一致性要求弱化,便是柔性事務(wù),放棄 ACID(Atomicity,Consistency,Isolation,Durability),轉(zhuǎn)投BASE(Basically Available,Soft state,Eventually consistent)。
例如 Saga、TCC、可靠消息保證最終一致等模型,對于大規(guī)模高并發(fā) OLTP 場景,我個人更建議使用柔性事務(wù)而非強(qiáng)一致的分布式事務(wù)。
關(guān)于柔性事務(wù),筆者之前也寫過一個技術(shù)組件,最近幾年也涌現(xiàn)出了一些新的模型與框架(例如阿里剛開源的 Fescar),限于篇幅不再贅述,有空再單獨寫篇文章。
解決分布式事務(wù)是否只能用兩階段提交協(xié)議?OceanBase1.0 中通過 updateserver 避免分布式事務(wù)的思路很有啟發(fā)性 ,不過 2.0 版后也變成了 2PC。
業(yè)界分布式事務(wù)也并非只有兩階段提交這一解,也有其他方案 its-time-to-move-on-from-two-phase:
https://www.jdon.com/51588
HA 與異地多活
主從模式并不是最優(yōu)的方式,就算是半同步復(fù)制,在極端情況下(半同步轉(zhuǎn)異步)也存在丟數(shù)問題。
目前業(yè)界公認(rèn)更好的方案是基于 Paxos 分布式一致性協(xié)議或者其他類 Paxos 如 Raft 方式,Google Spanner、TiDB、cockcoachDB、OB 都采用了這種方式。
基于 Paxos 協(xié)議的多副本存儲,遵循過半寫原則,支持自動選主,解決了數(shù)據(jù)的高可靠,縮短了 Failover 時間,提高了可用性,特別是減少了運(yùn)維的工作量,這種方案技術(shù)上已經(jīng)很成熟,也是 NewSQL 數(shù)據(jù)庫底層的標(biāo)配。
當(dāng)然這種方式其實也可以用在傳統(tǒng)關(guān)系數(shù)據(jù)庫,阿里、微信團(tuán)隊等也有將 MySQL 存儲改造支持 Paxos 多副本的,MySQL 也推出了官方版 MySQL Group Cluster,預(yù)計不遠(yuǎn)的未來主從模式可能就成為歷史了。
分布式一致性算法本身并不難,但具體在工程實踐時,需要考慮很多異常并做很多優(yōu)化,實現(xiàn)一個生產(chǎn)級可靠成熟的一致性協(xié)議并不容易。
例如實際使用時必須轉(zhuǎn)化實現(xiàn)為 multi-paxos 或 multi-raft,需要通過 batch、異步等方式減少網(wǎng)絡(luò)、磁盤 IO 等開銷。
需要注意的是很多 NewSQL 數(shù)據(jù)庫廠商宣傳基于 Paxos 或 Raft 協(xié)議可以實現(xiàn)【異地多活】,這個實際上是有前提的,那就是異地之間網(wǎng)絡(luò)延遲不能太高。
以銀行“兩地三中心”為例,異地之間多相隔數(shù)千里,延時達(dá)到數(shù)十毫秒,如果要多活,那便需異地副本也參與數(shù)據(jù)庫日志過半確認(rèn),這樣高的延時幾乎沒有 OLTP 系統(tǒng)可以接受的。
數(shù)據(jù)庫層面做異地多活是個美好的愿景,但距離導(dǎo)致的延時目前并沒有好的方案。
之前跟螞蟻團(tuán)隊交流,螞蟻異地多活的方案是在應(yīng)用層通過 MQ 同步雙寫交易信息,異地 DC 將交易信息保存在分布式緩存中。
一旦發(fā)生異地切換,數(shù)據(jù)庫同步中間件會告之?dāng)?shù)據(jù)延遲時間,應(yīng)用從緩存中讀取交易信息,將這段時間內(nèi)涉及到的業(yè)務(wù)對象例如用戶、賬戶進(jìn)行黑名單管理,等數(shù)據(jù)同步追上之后再將這些業(yè)務(wù)對象從黑名單中剔除。
由于雙寫的不是所有數(shù)據(jù)庫操作日志而只是交易信息,數(shù)據(jù)延遲只影響一段時間內(nèi)數(shù)據(jù),這是目前我覺得比較靠譜的異地度多活方案。
另外有些系統(tǒng)進(jìn)行了單元化改造,這在 Paxos 選主時也要結(jié)合考慮進(jìn)去,這也是目前很多 NewSQL 數(shù)據(jù)庫欠缺的功能。
Scale 橫向擴(kuò)展與分片機(jī)制
Paxos 算法解決了高可用、高可靠問題,并沒有解決 Scale 橫向擴(kuò)展的問題,所以分片是必須支持的。
NewSQL 數(shù)據(jù)庫都是天生內(nèi)置分片機(jī)制的,而且會根據(jù)每個分片的數(shù)據(jù)負(fù)載(磁盤使用率、寫入速度等)自動識別熱點,然后進(jìn)行分片的分裂、數(shù)據(jù)遷移、合并,這些過程應(yīng)用是無感知的,這省去了 DBA 的很多運(yùn)維工作量。
以 TiDB 為例,它將數(shù)據(jù)切成 Region,如果 Region 到 64M 時,數(shù)據(jù)自動進(jìn)行遷移。
分庫分表模式下需要應(yīng)用設(shè)計之初就要明確各表的拆分鍵、拆分方式(Range、取模、一致性哈?;蛘咦远x路由表)、路由規(guī)則、拆分庫表數(shù)量、擴(kuò)容方式等。
相比 NewSQL 數(shù)據(jù)庫,這種模式給應(yīng)用帶來了很大侵入和復(fù)雜度,這對大多數(shù)系統(tǒng)來說也是一大挑戰(zhàn)。
分庫分表模式也能做到在線擴(kuò)容,基本思路是通過異步復(fù)制先追加數(shù)據(jù),然后設(shè)置只讀完成路由切換,最后放開寫操作,當(dāng)然這些需要中間件與數(shù)據(jù)庫端配合一起才能完成。
這里有個問題是 NewSQL 數(shù)據(jù)庫統(tǒng)一的內(nèi)置分片策略(例如 TiDB 基于 Range)可能并不是最高效的,因為與領(lǐng)域模型中的劃分要素并不一致,這導(dǎo)致的后果是很多交易會產(chǎn)生分布式事務(wù)。
舉個例子,銀行核心業(yè)務(wù)系統(tǒng)是以客戶為維度,也就是說客戶表、該客戶的賬戶表、流水表在絕大部分場景下是一起寫的。
但如果按照各表主鍵 Range 進(jìn)行分片,這個交易并不能在一個分片上完成,這在高頻 OLTP 系統(tǒng)中會帶來性能問題。
分布式 SQL 支持
常見的單分片 SQL,這兩者都能很好支持。NewSQL 數(shù)據(jù)庫由于定位與目標(biāo)是一個通用的數(shù)據(jù)庫,所以支持的 SQL 會更完整,包括跨分片的 Join、聚合等復(fù)雜 SQL。
中間件模式多面向應(yīng)用需求設(shè)計,不過大部分也支持帶拆分鍵 SQL、庫表遍歷、單庫 Join、聚合、排序、分頁等。但對跨庫的join以及聚合支持就不夠了。
NewSQL 數(shù)據(jù)庫一般并不支持存儲過程、視圖、外鍵等功能,而中間件模式底層就是傳統(tǒng)關(guān)系數(shù)據(jù)庫,這些功能如果只是涉及單庫是比較容易支持的。
NewSQL 數(shù)據(jù)庫往往選擇兼容 MySQL 或者 PostgreSQL 協(xié)議,所以 SQL 支持僅局限于這兩種,中間件例如驅(qū)動模式往往只需做簡單的 SQL 解析、計算路由、SQL 重寫,所以可以支持更多種類的數(shù)據(jù)庫 SQL。
SQL 支持的差異主要在于分布式 SQL 執(zhí)行計劃生成器,由于 NewSQL 數(shù)據(jù)庫具有底層數(shù)據(jù)的分布、統(tǒng)計信息,因此可以做 CBO,生成的執(zhí)行計劃效率更高。
而中間件模式下沒有這些信息,往往只能基于規(guī)則 RBO(Rule-Based-Opimization)。
這也是為什么中間件模式一般并不支持跨庫 Join,因為實現(xiàn)了效率也往往并不高,還不如交給應(yīng)用去做。
這里也可以看出中間件+分庫分表模式的架構(gòu)風(fēng)格體現(xiàn)出的是一種妥協(xié)、平衡,它是一個面向應(yīng)用型的設(shè)計;而 NewSQL 數(shù)據(jù)庫則要求更高、“大包大攬”,它是一個通用底層技術(shù)軟件,因此后者的復(fù)雜度、技術(shù)門檻也高很多。
存儲引擎
傳統(tǒng)關(guān)系數(shù)據(jù)庫的存儲引擎設(shè)計都是面向磁盤的,大多都基于 B+ 樹。B+ 樹通過降低樹的高度減少隨機(jī)讀、進(jìn)而減少磁盤尋道次數(shù),提高讀的性能,但大量的隨機(jī)寫會導(dǎo)致樹的分裂,從而帶來隨機(jī)寫,導(dǎo)致寫性能下降。
NewSQL 的底層存儲引擎則多采用 LSM,相比 B+ 樹 LSM 將對磁盤的隨機(jī)寫變成順序?qū)?,大大提高了寫的性能?/p>
不過 LSM 的的讀由于需要合并數(shù)據(jù)性能比 B+ 樹差,一般來說 LSM 更適合應(yīng)在寫大于讀的場景。
當(dāng)然這只是單純數(shù)據(jù)結(jié)構(gòu)角度的對比,在數(shù)據(jù)庫實際實現(xiàn)時還會通過 SSD、緩沖、Bloom Filter 等方式優(yōu)化讀寫性能,所以讀性能基本不會下降太多。
NewSQL 數(shù)據(jù)由于多副本、分布式事務(wù)等開銷,相比單機(jī)關(guān)系數(shù)據(jù)庫 SQL 的響應(yīng)時間并不占優(yōu),但由于集群的彈性擴(kuò)展,整體 QPS 提升還是很明顯的。
這也是 NewSQL 數(shù)據(jù)庫廠商說分布式數(shù)據(jù)庫更看重的是吞吐,而不是單筆 SQL 響應(yīng)時間的原因。
成熟度與生態(tài)
分布式數(shù)據(jù)庫是個新型通用底層軟件,準(zhǔn)確的衡量與評價需要一個多維度的測試模型。
需包括發(fā)展現(xiàn)狀、使用情況、社區(qū)生態(tài)、監(jiān)控運(yùn)維、周邊配套工具、功能滿足度、DBA 人才、SQL 兼容性、性能測試、高可用測試、在線擴(kuò)容、分布式事務(wù)、隔離級別、在線 DDL 等等。
雖然 NewSQL 數(shù)據(jù)庫發(fā)展經(jīng)過了一定時間檢驗,但多集中在互聯(lián)網(wǎng)以及傳統(tǒng)企業(yè)非核心交易系統(tǒng)中,目前還處于快速迭代、規(guī)模使用不斷優(yōu)化完善的階段。
相比而言,傳統(tǒng)關(guān)系數(shù)據(jù)庫則經(jīng)過了多年的發(fā)展,通過完整的評測,在成熟度、功能、性能、周邊生態(tài)、風(fēng)險把控、相關(guān)人才積累等多方面都具有明顯優(yōu)勢,同時對已建系統(tǒng)的兼容性也更好。
對于互聯(lián)網(wǎng)公司,數(shù)據(jù)量的增長壓力以及追求新技術(shù)的基因會更傾向于嘗試 NewSQL 數(shù)據(jù)庫,不用再考慮庫表拆分、應(yīng)用改造、擴(kuò)容、事務(wù)一致性等問題怎么看都是非常吸引人的方案。
對于傳統(tǒng)企業(yè)例如銀行這種風(fēng)險意識較高的行業(yè)來說,NewSQL 數(shù)據(jù)庫則可能在未來一段時間內(nèi)仍處于探索、審慎試點的階段。
基于中間件+分庫分表模式架構(gòu)簡單,技術(shù)門檻更低,雖然沒有 NewSQL 數(shù)據(jù)庫功能全面,但大部分場景最核心的訴求也就是拆分后 SQL 的正確路由,而此功能中間件模式應(yīng)對還是綽綽有余的,可以說在大多數(shù) OLTP 場景是夠用的。
限于篇幅,其他特性例如在線 DDL、數(shù)據(jù)遷移、運(yùn)維工具等特性就不在本文展開對比。
總結(jié)
如果看完以上內(nèi)容,您還不知道選哪種模式,那么結(jié)合以下幾個問題,先思考下 NewSQL 數(shù)據(jù)庫解決的點對于自身是不是真正的痛點:
強(qiáng)一致事務(wù)是否必須在數(shù)據(jù)庫層解決?
數(shù)據(jù)的增長速度是否不可預(yù)估的?
擴(kuò)容的頻率是否已超出了自身運(yùn)維能力?
相比響應(yīng)時間更看重吞吐?
是否必須做到對應(yīng)用完全透明?
是否有熟悉 NewSQL 數(shù)據(jù)庫的 DBA 團(tuán)隊?
如果以上有 2 到 3 個是肯定的,那么你可以考慮用 NewSQL 數(shù)據(jù)庫了,雖然前期可能需要一定的學(xué)習(xí)成本,但它是數(shù)據(jù)庫的發(fā)展方向,未來收益也會更高,尤其是互聯(lián)網(wǎng)行業(yè),隨著數(shù)據(jù)量的突飛猛進(jìn),分庫分表帶來的痛苦會與日俱增。
當(dāng)然選擇 NewSQL 數(shù)據(jù)庫你也要做好承擔(dān)一定風(fēng)險的準(zhǔn)備。
如果你還未做出抉擇,不妨再想想下面幾個問題:
最終一致性是否可以滿足實際場景?
數(shù)據(jù)未來幾年的總量是否可以預(yù)估?
擴(kuò)容、DDL 等操作是否有系統(tǒng)維護(hù)窗口?
對響應(yīng)時間是否比吞吐更敏感?
是否需要兼容已有的關(guān)系數(shù)據(jù)庫系統(tǒng)?
是否已有傳統(tǒng)數(shù)據(jù)庫 DBA 人才的積累?
是否可容忍分庫分表對應(yīng)用的侵入?
如果這些問題有多數(shù)是肯定的,那還是分庫分表吧。在軟件領(lǐng)域很少有完美的解決方案,NewSQL 數(shù)據(jù)庫也不是數(shù)據(jù)分布式架構(gòu)的銀彈。
相比而言分庫分表是一個代價更低、風(fēng)險更小的方案,它最大程度復(fù)用傳統(tǒng)關(guān)系數(shù)據(jù)庫生態(tài),通過中間件也可以滿足分庫分表后的絕大多數(shù)功能,定制化能力更強(qiáng)。
在當(dāng)前 NewSQL 數(shù)據(jù)庫還未完全成熟的階段,分庫分表可以說是一個上限低但下限高的方案,尤其傳統(tǒng)行業(yè)的核心系統(tǒng)。
到此,相信大家對“分庫分表與NewSQL怎么選擇”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。