阿里云官方鏡像站:OceanBase、MySQL鏡像源
https://developer.aliyun.com/mirror/?utm_content=g_1000303593
概述
OceanBase是阿里巴巴和螞蟻金服完全自主研發(fā)的通用的分布式關(guān)系型數(shù)據(jù)庫,定位為商用企業(yè)級數(shù)據(jù)庫。OceanBase能提供金融級別的可靠性,目前主要應用用于金融行業(yè),同時也適用于非金融行業(yè)場景。它融合傳統(tǒng)關(guān)系數(shù)據(jù)庫和分布式系統(tǒng)的優(yōu)勢,利用普通的PC服務器組成數(shù)據(jù)庫集群,擁有出色的線性擴展性。
通過在底層分布式引擎實現(xiàn)的Paxos多數(shù)派協(xié)議和多副本特性,OceanBase擁有了令人稱道的高可用和容災能力,不負“永不停機”的數(shù)據(jù)庫系統(tǒng)的盛名,可以完美支持多地多活、異地容災等高可用部署。
OceanBase是一個準內(nèi)存數(shù)據(jù)庫系統(tǒng),獨有的讀寫分離架構(gòu)和面向SSD固態(tài)盤的高效存儲引擎,為用戶帶來了超高性能的體驗。
OceanBase定位為云數(shù)據(jù)庫,通過在數(shù)據(jù)庫內(nèi)部實現(xiàn)多租戶隔離,實現(xiàn)一個集群可以服 務多個租戶,且租戶之間完全隔離,不會相互影響。
OceanBase目前完全兼容MySQL,用戶可以零成本從 MySQL 遷移到OceanBase。同時OceanBase在數(shù)據(jù)庫內(nèi)部實現(xiàn)了分區(qū)表和二級分區(qū)功能,可以完全取代MySQL常用的分庫分表方案。
OceanBase的存儲引擎
OceanBase本質(zhì)上是一個基線加增量的存儲引擎,跟關(guān)系數(shù)據(jù)庫差別很大。 存儲機制是LSM樹,這也是大多數(shù)NoSQL使用的存儲機制。OceanBase采用了一種讀寫分離的架構(gòu),把數(shù)據(jù)分為基線數(shù)據(jù)和增量數(shù)據(jù),其中增量數(shù)據(jù)放在內(nèi)存里(MemTable),基線數(shù)據(jù)放在SSD盤(SSTable)。雖然不是刻意設計的,但OceanBase確實比傳統(tǒng)數(shù)據(jù)庫更適合像雙十一、秒殺以及優(yōu)惠券銷售等短時間突發(fā)大流量的場景:
短時間內(nèi)大量用戶涌入,短時間內(nèi)業(yè)務流量非常大,數(shù)據(jù)庫系統(tǒng)壓力非常大
一段時間(幾秒鐘、幾分鐘、或半個小時等)后業(yè)務流量迅速或明顯回落
OceanBase是“基線數(shù)據(jù)(硬盤)”+“修改增量(內(nèi)存)”的架構(gòu),如下圖所示。
整個數(shù)據(jù)庫以硬盤(通常是SSD)為載體,對數(shù)據(jù)的修改都是增量數(shù)據(jù),只寫內(nèi)存,新近的增、刪、改數(shù)據(jù)(修改增量)在內(nèi)存,所以DML是完全的內(nèi)存操作,性能非常高。而基線數(shù)據(jù)在保存在硬盤上,因此OceanBase可以看成一個準內(nèi)存數(shù)據(jù)庫。這樣做的好處有:
寫事務在內(nèi)存(除事務日志必須落盤外),性能大大提升。
沒有隨機寫硬盤,硬盤隨機讀不受干擾,高峰期系統(tǒng)性能提升明顯;對于傳統(tǒng)數(shù)據(jù)庫,業(yè)務高峰期通常也是大量隨機寫盤(刷臟頁)的高峰期,大量隨機寫盤消耗了大量的IO,特別是考慮到SSD的寫入放大,對于讀寫性能都有較大的影響。
基線數(shù)據(jù)只讀,緩存(cache)簡單且效果提升。
讀數(shù)據(jù)的時候,數(shù)據(jù)可能會在內(nèi)存里有更新過的版本,在持久化存儲里有基線版本,需要把兩個版本進行合并,獲得一個最新版本。同時在內(nèi)存實現(xiàn)了Block Cache和Row cache,來避免對基線數(shù)據(jù)的隨機讀。當內(nèi)存的增量數(shù)據(jù)達到一定規(guī)模的時候,會觸發(fā)增量數(shù)據(jù)和基線數(shù)據(jù)的合并,把增量數(shù)據(jù)落盤(稱為轉(zhuǎn)儲,又叫minor freeze)。同時每天晚上的空閑時刻,系統(tǒng)也會自動每日合并(簡稱合并,major freeze)。
OB為何采用這種特殊架構(gòu),簡要來說,就是基于這樣一條理論基礎——盡管數(shù)據(jù)庫本身的數(shù)據(jù)量越來越大,記錄數(shù)越來越多,但每天的增刪改數(shù)據(jù)量并不大,僅僅只占數(shù)據(jù)庫總量一個很小的比例。 這個情況不只是對支付寶的支付數(shù)據(jù),對其它大部分數(shù)據(jù)庫實際應用情況也適用,是OB建立上述存儲引擎的重要理論基礎。
每日合并,必然涉及到大量的硬盤讀寫(IO),因此可能對業(yè)務的吞吐量和事務響應時間(RT)產(chǎn)生影響。如何避免每日合并對業(yè)務的影響呢?OceanBase通過“輪轉(zhuǎn)合并”解決了這個問題。
眾所周知,出于高可用的考慮,OceanBase是三機群部署。
根據(jù)配置和部署的不同,業(yè)務高峰時可以一個機群、兩個機群或者三個機群提供讀寫服務。OceanBase的輪轉(zhuǎn)合并就是對每個機群輪轉(zhuǎn)地進行每日合并,在對一個機群進行每日合并之前,先把該機群上的業(yè)務讀寫流量切換到另外的一個或兩個機群,然后對該機群進行全速的每日合并。
因此在每日合并期間,合并進行中的機群沒有業(yè)務流量,僅僅接收事務日志并且參與Paxos投票,業(yè)務訪問OceanBase的事務響應時間完全不受每日合并的影響,僅僅是OceanBase的總吞吐量有所下降:如果先前是三個機群都提供服務則總吞吐量下降1/3,如果先前只有一個或兩個機群提供服務則總吞吐量沒有變化。
輪轉(zhuǎn)合并使得OceanBase對SSD十分友好,避免了大量隨機寫盤對SSD壽命的影響,因此OceanBase可以使用相對廉價的“讀密集型”SSD來代替?zhèn)鹘y(tǒng)數(shù)據(jù)庫使用的相對昂貴的“讀寫型”SSD,而不影響性能。此外由于輪轉(zhuǎn)合并對服務器的CPU使用、硬盤IO使用以及耗時長短都不敏感(高峰期的傳統(tǒng)數(shù)據(jù)庫在刷臟頁的同時還要優(yōu)先保證業(yè)務訪問的吞吐量和事務響應時間,刷臟頁的CPU及IO資源都非常受限),因此OceanBase在每日合并時可以采用更加高效的壓縮或者編碼算法(比如壓縮或編碼速度略慢,但壓縮率較高、解壓縮很快的算法),從而進一步降低存儲成本并提升性能。
每日合并提供了很多好處,但也需要承受一定的代價;整體上來說,每日合并會是一個比較費時的操作,對系統(tǒng)的 IO 和 CPU 會有比較多的消耗。為了使每日合并使用系統(tǒng)資源對系統(tǒng)帶來的影響盡可能的降低,比較常見的做法是將每日合并的操作放在業(yè)務的低峰期間(如夜間時刻)進行。
OceanBase如何保證寫的原子性
分布式數(shù)據(jù)庫技術(shù)具體難在哪里呢?簡單說,要想賬頭一分錢都不錯,數(shù)據(jù)庫要支持事務,事務擁有ACID原則,這四個字母分別代表:A原子性、C一致性、I隔離性、D持久性。
原子性:表示事務中的多個操作要么全部完成,要么全部失敗,不會出現(xiàn)中間狀態(tài),例如A轉(zhuǎn)給B100塊錢,A賬戶扣除100塊的同時,B賬戶必須增加100塊錢。這兩件事必須像一個原子一樣緊緊抱在一起,決不允許“A已經(jīng)扣錢,B還沒加錢”的事情發(fā)生。
一致性:A轉(zhuǎn)給B100塊錢,轉(zhuǎn)賬完成的一瞬間,A瞬間再查詢自己的最新余額,必須顯示已經(jīng)扣除100之后的金額,B必須瞬間查到已經(jīng)加上100塊之后的余額。所有的賬目在任何一個時間切面必須完完全全對得上。
隔離性:表示多個并發(fā)事務之間不互相影響,A轉(zhuǎn)給B100塊錢,不能對C有任何影響。
持久性:表示事務一旦成功就不會丟失,A轉(zhuǎn)給B100塊錢,這筆轉(zhuǎn)賬一旦完成,就永遠生效。
其中一致性是目的,原子性隔離性和持久化是手段,只要做好ACID中的AID,C自然就能滿足。
由于數(shù)據(jù)散落在多臺數(shù)據(jù)庫服務器上,庫作了拆分。分布式寫最大的難度其實就在于保證ACID中的那個A——原子性。
舉個例子,假設A給B轉(zhuǎn)100塊錢,由于是“分布式數(shù)據(jù)庫”,A用戶的賬戶數(shù)據(jù)存在A機器上,B用戶的賬戶數(shù)據(jù)存在B機器上。
如果交易發(fā)生時,負責給A賬戶扣100塊錢的A機器死機,沒有扣成功,而負責給賬戶B加100塊錢的B機器工作正常,加上了100——這就會造成支付寶損失100塊。
?
反之,如果負責給A賬戶扣100塊錢的A機器正常,已經(jīng)扣掉100,而負責給賬戶B加100塊錢的B機器死機,100塊沒加上,那么用戶就會損失100——最后支付寶還要賠償用戶100塊。
?
為了保證以上這兩種尷尬的局面不發(fā)生,OceanBase 1.0 采用了整整一組技術(shù),但最主要的是兩個。
投票機制
數(shù)據(jù)庫采用“三副本”,也就是任何一個賬戶,都有一個主咖兩個備胎共三份相同的數(shù)據(jù)。
舉例來說:賬戶A的數(shù)據(jù)一定同時存在三臺機器上。轉(zhuǎn)賬時,至少兩臺機器執(zhí)行完畢才算轉(zhuǎn)賬完成,這意味著,三臺機器里有一臺壞掉,并不影響轉(zhuǎn)賬的執(zhí)行。同時,三臺機器之間相互實時發(fā)送“心跳信號”,如果有一臺機器掛了,其他兩臺馬上就能感覺到,處理完手頭這個交易后,馬上向系統(tǒng)發(fā)送警報,系統(tǒng)自動為他倆匹配一個新搭檔,三臺機器繼續(xù)工作。而換下來那個壞機器,交給技術(shù)人員維修,修好后重新上架成為備用機器,等待進入戰(zhàn)斗序列。
也就是說,除非兩臺機器在同年同月同日同分同秒同毫秒壞掉,否則數(shù)據(jù)庫的工作不受影響。
?
即使是這還不夠,在關(guān)鍵的節(jié)點,OceanBase 會采用五個節(jié)點投票。也就是除非三臺機器在同年同月同日同分同秒同毫秒壞掉,否則數(shù)據(jù)庫的工作不受影響。這個概率已經(jīng)低到塵土里了。
?
oceanBase在存儲層,通過分區(qū)級Paxos日志同步實現(xiàn)高可用和自動擴展,支持靈活的存儲架構(gòu),包括本地存儲,以及存儲計算分離。經(jīng)典集中式數(shù)據(jù)庫往往采用主備同步方案,有兩種同步模式:第一種是強同步,每個事務操作都需要強同步到備機才可以應答用戶,這種方式能夠做到服務器故障不丟數(shù)據(jù),但必須停服務,無法保證可用性;另外一種是異步,每個事務操作只需要在主機成功就可以應答用戶,這種方式能夠做到高可用,但主庫和備庫之間數(shù)據(jù)不一致,備庫切換為主庫之后會丟數(shù)據(jù)。
強一致和高可用作為數(shù)據(jù)庫最重要的兩個特性,在主備同步模式下,魚和熊掌不可兼得。Paxos是一種基于多數(shù)派的分布式投票協(xié)議,每個事務需要成功寫入超過一半服務器才可以應答用戶。俗話說得好,“三個臭皮匠頂過一個諸葛亮”,假設總共有3臺服務器,每個事務操作要求至少在2臺服務器上成功,無論任何一臺服務器發(fā)生故障,系統(tǒng)中還有1臺包含了全部數(shù)據(jù)的服務器能夠正常工作,從而做到完全不丟數(shù)據(jù),并在30秒之內(nèi)選出新的主庫恢復服務,RPO等于0,RTO小于 30秒。所有保證RPO=0的協(xié)議都是Paxos協(xié)議或者Paxos協(xié)議的變種,Raft協(xié)議就是其中之一。
監(jiān)督機制
監(jiān)督機制其實是對兩階段提交協(xié)議(2PC)的實踐,仔細想想,除了機器壞掉,還有一些情況會破壞交易的原子性。
例如:A賬戶要扣掉100塊,但是它的余額只有90塊,或者已經(jīng)達到了今天的轉(zhuǎn)賬限額,這種情況下,如果貿(mào)然給B賬戶加了100塊,A賬戶卻不夠扣,就會陷入麻煩了。
反之如果B賬戶狀態(tài)有異常,不能加100塊,同樣會有麻煩。解決這個問題的方法,就是引入一位“裁判員”。裁判員站在A賬戶和B賬戶旁邊,它的工作流程是這樣的:
裁判員問A賬戶:你的三臺機器都沒問題吧?A賬戶說:沒問題。
裁判員問A賬戶:你的賬戶允許扣100嗎?A賬戶說:允許。
裁判員問B賬戶:你的三臺機器都沒問題吧?B賬戶說:沒問題。
裁判員問B賬戶:你的賬戶狀態(tài)能接受加100嗎?B說:允許。
這時,裁判員吹哨,A、B賬戶同時凍結(jié)。
A扣100,B加100,雙方向裁判匯報“成功”。
裁判員再吹哨,A、B賬戶同時解凍。
以上7步,都是按時間順序完成的,卡在任何一步,賬目都不會亂,一分錢都不會丟。完全符合“原子化”的要求。
?
裁判員充當2PC中的協(xié)調(diào)器角色。
OceanBase如何保證事務的隔離性
數(shù)據(jù)庫系統(tǒng)不能只服務一個用戶,需要允許多個用戶同時操作數(shù)據(jù),即并發(fā)。所以需要保證多個并發(fā)事務的隔離,這里涉及到并發(fā)控制技術(shù),常見的并發(fā)控制方法有基于鎖的并發(fā)控制(Lock based Concurrency Controll)和多版本并發(fā)控制(Multiple version Concurrency Controll)
基于鎖的并發(fā)控制
數(shù)據(jù)庫系統(tǒng)對用戶在事務過程中操作的每一行數(shù)據(jù)都加鎖,讀操作加讀鎖,寫操作加寫鎖。讀寫阻塞,寫寫阻塞。如果兩個不同的事務試圖修改同一行數(shù)據(jù),事務1先加上寫鎖正常執(zhí)行,事務2就只能阻塞等待,當事務1執(zhí)行結(jié)束釋放寫鎖后,事務2再繼續(xù)執(zhí)行。
以轉(zhuǎn)賬操作為例,A賬戶有100元,B賬戶有200元,如果事務1執(zhí)行從A賬戶轉(zhuǎn)10元到B賬戶,那么在事務1執(zhí)行過程中,A B兩行賬戶數(shù)據(jù)都會被加上寫鎖。如果事務2執(zhí)行另一次轉(zhuǎn)賬操作,從A賬戶轉(zhuǎn)50元到B賬戶,那么給A加寫鎖時失敗,事務2會一直等待直到加寫鎖成功為止。
如果在事務1與事務2的執(zhí)行過程中,又來一個事務3想要查詢A B兩個賬戶的余額總和,那么需要讀取A B兩行,讀之前要先加讀鎖,但是在事務1和事務2操作時,讀鎖加不成功,那么事務3就需要等待事務1和事務2都結(jié)束了才能執(zhí)行。
多版本的并發(fā)控制
在上面例子中,一個讀取A B兩賬戶余額總和的操作,無論事務1和事務2是否執(zhí)行完成,其結(jié)果都是確定的(300元)。但基于鎖的并發(fā)控制,讀寫是阻塞的,極大的降低了數(shù)據(jù)庫的并發(fā)性能,所以出現(xiàn)了MVCC的方法來做并發(fā)控制。對于數(shù)據(jù)庫的數(shù)據(jù),每次修改都保留歷史版本,這樣讀操作可以直接在歷史版本上執(zhí)行,不會被寫操作阻塞。
在 MVCC 方法下,每一個事務都會有一個提交版本,繼續(xù)上面事務三的例子。假設數(shù)據(jù)的初始版本是98,假定事務1是的版本號100,事務2是101。那么修改都完成后,數(shù)據(jù)庫中的數(shù)據(jù)狀態(tài)如下:
每次數(shù)據(jù)修改的記錄都會被串聯(lián)起來。另有一個全局變量 Global Committed Version(GCV) 標示全局最后提交的版本號。在事務1執(zhí)行之前GCV是98,事務1提交之后GCV變成100,事務二提交之后GCV變成101。所以,當事務3開始執(zhí)行時,先獲取GCV,然后根據(jù)這個版本號去讀相應的數(shù)據(jù)。
MVCC的修改操作依然會依賴上面提到的鎖機制,所以寫操作之間的沖突依然需要等待。但是MVCC最大的優(yōu)勢就是讀操作與寫操作完全隔離開,互相不影響。對于數(shù)據(jù)庫的性能和并發(fā)能力提升非常有益。
OceanBase使用的方案
使用MVCC方案時GCV的修改需要依次遞增,如果GCV被修改成了101,表示101及之前的所有事務都提交了。OceanBase使用了分布式事務后,這個保證變得困難,例如,版本號為100的事務可能是分布式事務,101可能是單機事務,分布式事務的提交過程要顯著長于單機事務。結(jié)果,版本號101的事務先完成,GCV就被修改成了101。但是此時版本號為100事務還在提交過程中,并不能被讀取。
所以,OceanBase采用了MVCC和Lock-based結(jié)合的方式,讀取操作先獲取GCV,然后按照這個版本號讀取每一行數(shù)據(jù)。如果這行數(shù)據(jù)上沒有修改,或者有修改但是修改的版本號會大于GCV,那么這行數(shù)據(jù)可以直接按照版本號讀取。如果這行數(shù)據(jù)上有一個正在提交中事務,并且版本號有可能小于讀取使用的版本號,那么讀取操作就需要等待這個事務結(jié)束,就好像Lock-based方案中讀鎖等待寫鎖一樣。但是,這個發(fā)生的概率極低,所以整體的性能還是像 MVCC一樣好。
OceanBase的高可用
高可用是數(shù)據(jù)庫的基本需求之一,傳統(tǒng)數(shù)據(jù)庫允許通過日志同步實現(xiàn)主備鏡像;然而,由于主備鏡像中主庫與備庫無法完全同步,因此傳統(tǒng)數(shù)據(jù)庫的高可用其實是建立在傳統(tǒng)的高可靠服務器和高可靠共享存儲之上的。
OceanBase同樣使用性價比較高、可靠性略低的服務器,但**同一數(shù)據(jù)保存在多臺(>=3)服務器中的半數(shù)以上服務器上(例如3臺中的2臺,5臺中的3臺等),每一筆寫事務也必須到達半數(shù)以上服務器才生效,因此當少數(shù)服務器故障時不會有任何數(shù)據(jù)丟失。**不僅如此,傳統(tǒng)數(shù)據(jù)庫主備鏡像在主庫發(fā)生故障時,通常需要外部工具或人工把備庫升級成主庫,而OceanBase底層實現(xiàn)了Paxos高可用協(xié)議,在主庫故障后,剩余的服務器會很快自動選舉出新的主庫,并繼續(xù)提供服務,OceanBase數(shù)據(jù)庫能做到自動切換且完全不丟數(shù)據(jù)。
OceanBase與MySQL的比較
1、 OB的redo log是使用分布式一致性算法paxos實現(xiàn)的。所以在CAP理論中,雖然OB使用的是強一致模型,但是OB能在一定網(wǎng)絡分區(qū)的情況下做到高可用(通俗點講就是多余半數(shù)機器還活著的時候就能干活),官方的MySQL目前做不到這一點。
2、OB的存儲結(jié)構(gòu)使用的是兩級的LSM tree。其中內(nèi)存中的C0 Btree葉節(jié)點不需要和磁盤上的btree一樣大小,所以能做得比較小,對CPU的Cache比較友好,并且不會有寫入放大的問題。使得OB的寫性能有極大的提升。同時磁盤上的C1 tree不是一個傳統(tǒng)意義上的Btree(Btree未經(jīng)壓縮可能浪費一半空間)??臻g利用率大大提高。簡單來說就是速度快,省成本。
3、 數(shù)據(jù)庫自動分片功能(支持hash/range,一級二級等等分片方式),提供獨立的proxy路由寫入查詢等操作到對應的分片。這意味著數(shù)據(jù)量再大也不需要手動分庫分表了。并且分片能在線的在各個server之間遷移,解決熱點問題(資源分配不均的問題,做到彈性加機器和減機器)。每個分片(確切的說是被選為主的分片)都支持讀寫,做到多點寫入(高吞吐量,性能可線性擴展)。
4、數(shù)據(jù)庫內(nèi)部實現(xiàn)的無阻塞的兩階段提交(跨機事務)。
5、數(shù)據(jù)庫原生的多租戶支持,能直接隔離租戶之間的cpu、mem、io等資源。
6、高可用,對OceanBase而言,同一數(shù)據(jù)保存在多臺(>=3)臺服務器中的半數(shù)以上服務器上(例如3臺中的2臺),每一筆寫事務也必須到達半數(shù)以上服務器才生效,因此當少數(shù)服務器故障時不會有任何數(shù)據(jù)丟失,能夠做到RPO等于零。不僅如此,OceanBase底層實現(xiàn)的Paxos高可用協(xié)議,在主庫故障后,剩余的服務器會很快自動選舉出新的主庫,實現(xiàn)自動切換,并繼續(xù)提供服務,在實際的生產(chǎn)系統(tǒng)中做到RTO在20秒之內(nèi)。
7、擴展能力。MySQL在數(shù)據(jù)庫中間件的幫助下,可以通過分庫分表來實現(xiàn)水平擴展。這種方案解決了傳統(tǒng)數(shù)據(jù)庫需要垂直擴展的通病,但還是存在相當?shù)木窒扌裕热鐢U容和縮容困難、無法支持全局索引,數(shù)據(jù)一致性難以保證等。OceanBase則從數(shù)據(jù)庫層面提供了真正意義上的水平擴展能力。OceanBase基于分布式系統(tǒng)實現(xiàn),可以很方便地進行擴容和縮容,且能做到用戶無感知。同時,OceanBase所具備的集群內(nèi)動態(tài)負載均衡、多機分布式查詢、全局索引的能力更進一步加強了其可擴展性。對于用戶的分庫分表方案,OceanBase提供了分區(qū)表和二級分區(qū)的功能,可以完全取而代之。
?
原文鏈接:blog.csdn.net/fuzhongmin0…
編輯:fqj
評論
查看更多