OceanBase簡介及其與MySQL的比較
阿里雲官方映象站:OceanBase、MySQL映象源
https://developer.aliyun.com/mirror/?utm_content=g_1000303593
概述
OceanBase是阿里巴巴和螞蟻金服完全自主研發的通用的分散式關係型資料庫,定位為商用企業級資料庫。OceanBase能提供金融級別的可靠性,目前主要應用用於金融行業,同時也適用於非金融行業場景。它融合傳統關聯式資料庫和分散式系統的優勢,利用普通的PC伺服器組成資料庫叢集,擁有出色的線性擴充套件性。
透過在底層分散式引擎實現的Paxos多數派協議和多副本特性,OceanBase擁有了令人稱道的高可用和容災能力,不負“永不停機”的資料庫系統的盛名,可以完美支援多地多活、異地容災等高可用部署。
OceanBase是一個準記憶體資料庫系統,獨有的讀寫分離架構和麵向SSD固態盤的高效儲存引擎,為使用者帶來了超高效能的體驗。
OceanBase定位為雲資料庫,透過在資料庫內部實現多租戶隔離,實現一個叢集可以服 務多個租戶,且租戶之間完全隔離,不會相互影響。
OceanBase目前完全相容MySQL,使用者可以零成本從 MySQL 遷移到OceanBase。同時OceanBase在資料庫內部實現了分割槽表和二級分割槽功能,可以完全取代MySQL常用的分庫分表方案。
OceanBase的儲存引擎
OceanBase本質上 是一個基線加增量的儲存引擎,跟關聯式資料庫差別很大。 儲存機制是LSM樹,這也是大多數NoSQL使用的儲存機制。OceanBase採用了一種讀寫分離的架構,把資料分為基線資料和增量資料,其中增量資料放在記憶體裡(MemTable),基線資料放在SSD盤(SSTable)。雖然不是刻意設計的,但OceanBase確實比傳統資料庫更適合像雙十一、秒殺以及優惠券銷售等短時間突發大流量的場景:
- 短時間內大量使用者湧入,短時間內業務流量非常大,資料庫系統壓力非常大
- 一段時間(幾秒鐘、幾分鐘、或半個小時等)後業務流量迅速或明顯回落
OceanBase是“基線資料(硬碟)”+“修改增量(記憶體)”的架構,如下圖所示。
整個資料庫以硬碟(通常是SSD)為載體,對資料的修改都是增量資料,只寫記憶體,新近的增、刪、改資料(修改增量)在記憶體,所以DML是完全的記憶體操作,效能非常高。而基線資料在儲存在硬碟上,因此OceanBase可以看成一個準記憶體資料庫。這樣做的好處有:
- 寫事務在記憶體(除事務日誌必須落盤外),效能大大提升。
- 沒有隨機寫硬碟,硬碟隨機讀不受干擾,高峰期系統效能提升明顯;對於傳統資料庫,業務高峰期通常也是大量隨機寫盤(刷髒頁)的高峰期,大量隨機寫盤消耗了大量的IO,特別是考慮到SSD的寫入放大,對於讀寫效能都有較大的影響。
- 基線資料只讀,快取(cache)簡單且效果提升。
讀資料的時候,資料可能會在記憶體裡有更新過的版本,在持久化儲存裡有基線版本,需要把兩個版本進行合併,獲得一個最新版本。同時在記憶體實現了Block Cache和Row cache,來避免對基線資料的隨機讀。當記憶體的增量資料達到一定規模的時候,會觸發增量資料和基線資料的合併,把增量資料落盤(稱為轉儲,又叫minor freeze)。同時每天晚上的空閒時刻,系統也會自動每日合併(簡稱合併,major freeze)。
OB為何採用這種特殊架構,簡要來說,就是基於這樣一條理論基礎—— 儘管資料庫本身的資料量越來越大,記錄數越來越多,但每天的增刪改資料量並不大,僅僅只佔資料庫總量一個很小的比例。 這個情況不只是對支付寶的支付資料,對其它大部分資料庫實際應用情況也適用,是OB建立上述儲存引擎的重要理論基礎。
每日合併,必然涉及到大量的硬碟讀寫(IO),因此可能對業務的吞吐量和事務響應時間(RT)產生影響。如何避免每日合併對業務的影響呢?OceanBase透過“輪轉合併”解決了這個問題。
眾所周知,出於高可用的考慮,OceanBase是三機群部署。
根據配置和部署的不同,業務高峰時可以一個機群、兩個機群或者三個機群提供讀寫服務。OceanBase的輪轉合併就是對每個機群輪轉地進行每日合併,在對一個機群進行每日合併之前,先把該機群上的業務讀寫流量切換到另外的一個或兩個機群,然後對該機群進行全速的每日合併。
因此在每日合併期間,合併進行中的機群沒有業務流量,僅僅接收事務日誌並且參與Paxos投票,業務訪問OceanBase的事務響應時間完全不受每日合併的影響,僅僅是OceanBase的總吞吐量有所下降:如果先前是三個機群都提供服務則總吞吐量下降1/3,如果先前只有一個或兩個機群提供服務則總吞吐量沒有變化。
輪轉合併使得OceanBase對SSD十分友好,避免了大量隨機寫盤對SSD壽命的影響,因此OceanBase可以使用相對廉價的“讀密集型”SSD來代替傳統資料庫使用的相對昂貴的“讀寫型”SSD,而不影響效能。此外由於輪轉合併對伺服器的CPU使用、硬碟IO使用以及耗時長短都不敏感(高峰期的傳統資料庫在刷髒頁的同時還要優先保證業務訪問的吞吐量和事務響應時間,刷髒頁的CPU及IO資源都非常受限),因此OceanBase在每日合併時可以採用更加高效的壓縮或者編碼演算法(比如壓縮或編碼速度略慢,但壓縮率較高、解壓縮很快的演算法),從而進一步降低儲存成本並提升效能。
每日合併提供了很多好處,但也需要承受一定的代價;整體上來說,每日合併會是一個比較費時的操作,對系統的 IO 和 CPU 會有比較多的消耗。為了使每日合併使用系統資源對系統帶來的影響儘可能的降低,比較常見的做法是將每日合併的操作放在業務的低峰期間(如夜間時刻)進行。
OceanBase如何保證寫的原子性
分散式資料庫技術具體難在哪裡呢?簡單說,要想賬頭一分錢都不錯,資料庫要支援事務,事務擁有ACID原則,這四個字母分別代表:A原子性、C一致性、I隔離性、D永續性。
- 原子性:表示事務中的多個操作要麼全部完成,要麼全部失敗,不會出現中間狀態,例如A轉給B100塊錢,A賬戶扣除100塊的同時,B賬戶必須增加100塊錢。這兩件事必須像一個原子一樣緊緊抱在一起,決不允許“A已經扣錢,B還沒加錢”的事情發生。
- 一致性:A轉給B100塊錢,轉賬完成的一瞬間,A瞬間再查詢自己的最新餘額,必須顯示已經扣除100之後的金額,B必須瞬間查到已經加上100塊之後的餘額。所有的賬目在任何一個時間切面必須完完全全對得上。
- 隔離性:表示多個併發事務之間不互相影響,A轉給B100塊錢,不能對C有任何影響。
- 永續性:表示事務一旦成功就不會丟失,A轉給B100塊錢,這筆轉賬一旦完成,就永遠生效。
其中 一致性是目的,原子性隔離性和持久化是手段,只要做好ACID中的AID,C自然就能滿足。
由於資料散落在多臺資料庫伺服器上,庫作了拆分。分散式寫最大的難度其實就在於保證ACID中的那個A——原子性。
舉個例子,假設A給B轉100塊錢,由於是“分散式資料庫”,A使用者的賬戶資料存在A機器上,B使用者的賬戶資料存在B機器上。
如果交易發生時,負責給A賬戶扣100塊錢的A機器當機,沒有扣成功,而負責給賬戶B加100塊錢的B機器工作正常,加上了100——這就會造成支付寶損失100塊。
反之,如果負責給A賬戶扣100塊錢的A機器正常,已經扣掉100,而負責給賬戶B加100塊錢的B機器當機,100塊沒加上,那麼使用者就會損失100——最後支付寶還要賠償使用者100塊。
為了保證以上這兩種尷尬的局面不發生,OceanBase 1.0 採用了整整一組技術,但最主要的是兩個。
投票機制
資料庫採用“三副本”,也就是任何一個賬戶,都有一個主咖兩個備胎共三份相同的資料。
舉例來說:賬戶A的資料一定同時存在三臺機器上。轉賬時,至少兩臺機器執行完畢才算轉賬完成,這意味著,三臺機器裡有一臺壞掉,並不影響轉賬的執行。同時,三臺機器之間相互實時傳送“心跳訊號”,如果有一臺機器掛了,其他兩臺馬上就能感覺到,處理完手頭這個交易後,馬上向系統傳送警報,系統自動為他倆匹配一個新搭檔,三臺機器繼續工作。而換下來那個壞機器,交給技術人員維修,修好後重新上架成為備用機器,等待進入戰鬥序列。
也就是說,除非兩臺機器在同年同月同日同分同秒同毫秒壞掉,否則資料庫的工作不受影響。
即使是這還不夠,在關鍵的節點,OceanBase 會採用五個節點投票。也就是除非三臺機器在同年同月同日同分同秒同毫秒壞掉,否則資料庫的工作不受影響。這個機率已經低到塵土裡了。
oceanBase在儲存層,透過分割槽級Paxos日誌同步實現高可用和自動擴充套件,支援靈活的儲存架構,包括本地儲存,以及儲存計算分離。 經典集中式資料庫往往採用主備同步方案,有兩種同步模式:第一種是強同步,每個事務操作都需要強同步到備機才可以應答使用者,這種方式能夠做到伺服器故障不丟資料,但必須停服務,無法保證可用性;另外一種是非同步,每個事務操作只需要在主機成功就可以應答使用者,這種方式能夠做到高可用,但主庫和備庫之間資料不一致,備庫切換為主庫之後會丟資料。
強一致和高可用作為資料庫最重要的兩個特性,在主備同步模式下,魚和熊掌不可兼得。Paxos是一種基於多數派的分散式投票協議,每個事務需要成功寫入超過一半伺服器才可以應答使用者。俗話說得好,“三個臭皮匠頂過一個諸葛亮”,假設總共有3臺伺服器,每個事務操作要求至少在2臺伺服器上成功,無論任何一臺伺服器發生故障,系統中還有1臺包含了全部資料的伺服器能夠正常工作,從而做到完全不丟資料,並在30秒之內選出新的主庫恢復服務,RPO等於0,RTO小於 30秒。所有保證RPO=0的協議都是Paxos協議或者Paxos協議的變種,Raft協議就是其中之一。
監督機制
監督機制其實是 對兩階段提交協議(2PC)的實踐,仔細想想,除了機器壞掉,還有一些情況會破壞交易的原子性。
例如:A賬戶要扣掉100塊,但是它的餘額只有90塊,或者已經達到了今天的轉賬限額,這種情況下,如果貿然給B賬戶加了100塊,A賬戶卻不夠扣,就會陷入麻煩了。
反之如果B賬戶狀態有異常,不能加100塊,同樣會有麻煩。解決這個問題的方法,就是引入一位“裁判員”。裁判員站在A賬戶和B賬戶旁邊,它的工作流程是這樣的:
- 裁判員問A賬戶:你的三臺機器都沒問題吧?A賬戶說:沒問題。
- 裁判員問A賬戶:你的賬戶允許扣100嗎?A賬戶說:允許。
- 裁判員問B賬戶:你的三臺機器都沒問題吧?B賬戶說:沒問題。
- 裁判員問B賬戶:你的賬戶狀態能接受加100嗎?B說:允許。
- 這時,裁判員吹哨,A、B賬戶同時凍結。
- A扣100,B加100,雙方向裁判彙報“成功”。
- 裁判員再吹哨,A、B賬戶同時解凍。
以上7步,都是按時間順序完成的,卡在任何一步,賬目都不會亂,一分錢都不會丟。完全符合“原子化”的要求。
裁判員充當2PC中的協調器角色。
OceanBase如何保證事務的隔離性
資料庫系統不能只服務一個使用者,需要允許多個使用者同時運算元據,即併發。所以需要保證多個併發事務的隔離,這裡涉及到併發控制技術,常見的併發控制方法有基於鎖的併發控制(Lock based Concurrency Controll)和多版本併發控制(Multiple version Concurrency Controll)
基於鎖的併發控制
資料庫系統對使用者在事務過程中操作的每一行資料都加鎖,讀操作加讀鎖,寫操作加寫鎖。讀寫阻塞,寫寫阻塞。如果兩個不同的事務試圖修改同一行資料,事務1先加上寫鎖正常執行,事務2就只能阻塞等待,當事務1執行結束釋放寫鎖後,事務2再繼續執行。
以轉賬操作為例,A賬戶有100元,B賬戶有200元,如果事務1執行從A賬戶轉10元到B賬戶,那麼在事務1執行過程中,A B兩行賬戶資料都會被加上寫鎖。如果事務2執行另一次轉賬操作,從A賬戶轉50元到B賬戶,那麼給A加寫鎖時失敗,事務2會一直等待直到加寫鎖成功為止。
如果在事務1與事務2的執行過程中,又來一個事務3想要查詢A B兩個賬戶的餘額總和,那麼需要讀取A B兩行,讀之前要先加讀鎖,但是在事務1和事務2操作時,讀鎖加不成功,那麼事務3就需要等待事務1和事務2都結束了才能執行。
多版本的併發控制
在上面例子中,一個讀取A B兩賬戶餘額總和的操作,無論事務1和事務2是否執行完成,其結果都是確定的(300元)。但基於鎖的併發控制,讀寫是阻塞的,極大的降低了資料庫的併發效能,所以出現了MVCC的方法來做併發控制。對於資料庫的資料,每次修改都保留歷史版本,這樣讀操作可以直接在歷史版本上執行,不會被寫操作阻塞。
在 MVCC 方法下,每一個事務都會有一個提交版本,繼續上面事務三的例子。假設資料的初始版本是98,假定事務1是的版本號100,事務2是101。那麼修改都完成後,資料庫中的資料狀態如下:
每次資料修改的記錄都會被串聯起來。另有一個全域性變數 Global Committed Version(GCV) 標示全域性最後提交的版本號。在事務1執行之前GCV是98,事務1提交之後GCV變成100,事務二提交之後GCV變成101。所以,當事務3開始執行時,先獲取GCV,然後根據這個版本號去讀相應的資料。
MVCC的修改操作依然會依賴上面提到的鎖機制,所以寫操作之間的衝突依然需要等待。但是MVCC最大的優勢就是讀操作與寫操作完全隔離開,互相不影響。對於資料庫的效能和併發能力提升非常有益。
OceanBase使用的方案
使用MVCC方案時GCV的修改需要依次遞增,如果GCV被修改成了101,表示101及之前的所有事務都提交了。OceanBase使用了分散式事務後,這個保證變得困難,例如,版本號為100的事務可能是分散式事務,101可能是單機事務,分散式事務的提交過程要顯著長於單機事務。結果,版本號101的事務先完成,GCV就被修改成了101。但是此時版本號為100事務還在提交過程中,並不能被讀取。
所以,OceanBase採用了MVCC和Lock-based結合的方式,讀取操作先獲取GCV,然後按照這個版本號讀取每一行資料。如果這行資料上沒有修改,或者有修改但是修改的版本號會大於GCV,那麼這行資料可以直接按照版本號讀取。如果這行資料上有一個正在提交中事務,並且版本號有可能小於讀取使用的版本號,那麼讀取操作就需要等待這個事務結束,就好像Lock-based方案中讀鎖等待寫鎖一樣。但是,這個發生的機率極低,所以整體的效能還是像 MVCC一樣好。
OceanBase的高可用
高可用是資料庫的基本需求之一, 傳統資料庫允許透過日誌同步實現主備映象;然而,由於主備映象中主庫與備庫無法完全同步,因此傳統資料庫的高可用其實是建立在傳統的高可靠伺服器和高可靠共享儲存之上的。
OceanBase同樣使用價效比較高、可靠性略低的伺服器,但**同一資料儲存在多臺(>=3)伺服器中的半數以上伺服器上(例如3臺中的2臺,5臺中的3臺等),每一筆寫事務也必須到達半數以上伺服器才生效,因此當少數伺服器故障時不會有任何資料丟失。**不僅如此,傳統資料庫主備映象在主庫發生故障時,通常需要外部工具或人工把備庫升級成主庫,而OceanBase底層實現了Paxos高可用協議,在主庫故障後,剩餘的伺服器會很快自動選舉出新的主庫,並繼續提供服務,OceanBase資料庫能做到自動切換且完全不丟資料。
OceanBase與MySQL的比較
1、 OB的redo log是使用分散式一致性演算法paxos實現的。所以在CAP理論中,雖然OB使用的是強一致模型,但是OB能在一定網路分割槽的情況下做到高可用(通俗點講就是多餘半數機器還活著的時候就能幹活),官方的MySQL目前做不到這一點。
2、OB的儲存結構使用的是兩級的LSM tree。其中記憶體中的C0 Btree葉節點不需要和磁碟上的btree一樣大小,所以能做得比較小,對CPU的Cache比較友好,並且不會有寫入放大的問題。使得OB的寫效能有極大的提升。同時磁碟上的C1 tree不是一個傳統意義上的Btree(Btree未經壓縮可能浪費一半空間)。空間利用率大大提高。簡單來說就是速度快,省成本。
3、 資料庫自動分片功能(支援hash/range,一級二級等等分片方式),提供獨立的proxy路由寫入查詢等操作到對應的分片。這意味著資料量再大也不需要手動分庫分表了。並且分片能線上的在各個server之間遷移,解決熱點問題(資源分配不均的問題,做到彈性加機器和減機器)。每個分片(確切的說是被選為主的分片)都支援讀寫,做到多點寫入(高吞吐量,效能可線性擴充套件)。
4、資料庫內部實現的無阻塞的兩階段提交(跨機事務)。
5、資料庫原生的多租戶支援,能直接隔離租戶之間的cpu、mem、io等資源。
6、高可用,對OceanBase而言,同一資料儲存在多臺(>=3)臺伺服器中的半數以上伺服器上(例如3臺中的2臺),每一筆寫事務也必須到達半數以上伺服器才生效,因此當少數伺服器故障時不會有任何資料丟失,能夠做到RPO等於零。不僅如此,OceanBase底層實現的Paxos高可用協議,在主庫故障後,剩餘的伺服器會很快自動選舉出新的主庫,實現自動切換,並繼續提供服務,在實際的生產系統中做到RTO在20秒之內。
7、擴充套件能力。MySQL在資料庫中介軟體的幫助下,可以透過分庫分表來實現水平擴充套件。這種方案解決了傳統資料庫需要垂直擴充套件的通病,但還是存在相當的侷限性,比如擴容和縮容困難、無法支援全域性索引,資料一致性難以保證等。OceanBase則從資料庫層面提供了真正意義上的水平擴充套件能力。OceanBase基於分散式系統實現,可以很方便地進行擴容和縮容,且能做到使用者無感知。同時,OceanBase所具備的叢集內動態負載均衡、多機分散式查詢、全域性索引的能力更進一步加強了其可擴充套件性。對於使用者的分庫分表方案,OceanBase提供了分割槽表和二級分割槽的功能,可以完全取而代之。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70003733/viewspace-2842887/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL與MySQL比較MySql
- PostgreSQL與MySQL的比較 - hackrMySql
- Mysql中的Btree與Hash索引比較MySql索引
- PostgreSQL初體驗及其與MySQL的對比MySql
- ETL介紹與ETL工具比較
- mysql中count(1)與count(*)比較MySql
- Play框架與NodeJS的簡單比較框架NodeJS
- 簡單介紹Go 字串比較的實現示例Go字串
- NoSQL資料庫概覽及其與SQL語法的比較SQL資料庫
- ROWID與ROWNUM的簡介與對比
- MySQL簡介與啟動MySqlMySql
- 【Halcon】Halcon與OpenCV介紹、比較OpenCV
- oceanbase資料庫簡介資料庫
- 從docker介紹及其簡介Docker
- 比較MySQL 5.6與前版的同步協議薦MySql協議
- MySQL中MyISAM引擎與InnoDB引擎效能比較MySql
- 使用perl比較mysql的版本MySql
- MongoDB和MySQL比較MongoDBMySql
- MySQL檢視簡介與操作MySql
- Xposed原理簡介及其精簡化
- MySQL中的NULL和空串比較MySqlNull
- mongodb和hbase的簡單比較MongoDB
- MySQL:MySQL層比較函式呼叫MySql函式
- 字串-簡單字串比較字串
- 對mysql explain講的比較清楚的MySqlAI
- MVVM與MVC模式的比較MVVMMVC模式
- XTask與RxJava的使用比較RxJava
- JavaScript 與 Java、PHP 的比較JavaScriptPHP
- Hadoop與Spark的比較HadoopSpark
- CMM/CMMI 與敏捷的比較敏捷
- Hibernate與 MyBatis的比較MyBatis
- CoffeeScript與Ruby的比較
- Vue與React比較VueReact
- 【Redis與Memcached比較】Redis
- RecyclerView與ListView比較View
- js與jq比較JS
- Vuex與Redux比較VueRedux
- MySQL備份與恢復簡介MySql