支付寶雙11的功臣-分佈式關係型數據庫(oceanbase)

咱們都知道阿里雙11,除了創造了世界史上的交易奇蹟以外,也創造了世界技術史上的奇蹟。支付寶的峯值達到了每秒12萬筆,這在技術界簡直是一個奇蹟。爲何說他是一個奇蹟呢?簡單的來解釋一下:其實在平常開發中,打交道最多的就是數據庫,好多開發都戲稱只會增、刪、改。可是千萬不要小看增、刪、改,由於假設你只有一個用戶訪問的你的數據庫,你怎麼寫均可以,可是若是有幾十萬,上百萬,上千萬,乃至上億用戶呢?若是操做不當,那麼你的數據庫必定會down掉。因此看上去簡單的東西其實一點都不簡單,就好像風清揚同樣,簡單的劍招卻蘊含着上千變化。mysql

這裏,我主要想揭祕下oceanbase,由於整個支付寶的交易的庫都是依賴於它。oceanbase到底是什麼?用官方的話是這樣的:OceanBase是一個支持海量數據的高性能分佈式數據庫系統,實現了數千億條記錄、數百TB數據上的跨行跨表事務,由淘寶核心系統研發部、運維、DBA、廣告、應用研發等部門共同完成。那麼之前在沒有使用ob以前,支付寶都用的什麼呢?mysql或者oracle。這兩個一個是開源的數據庫,一個是甲骨文公司的商業付費數據庫。簡單的來講都是人家老外搞得!其實這兩個數據庫已經很強大了,支付寶之前的框架都是基於這兩種數據庫的。可是隨着業務的發展,這兩種數據庫也帶來了弊端。算法

-------------------------------------------------------------華麗的分割線-------------------------------------------------------------sql

假設咱們要撐起上千萬的併發量,上百PB,乃至TB的數據量。如何設計?數據庫

方案1、單庫(熱備)緩存

這個方案徹底不行,緣由很少說了。服務器

方案2、數據拆分(分庫分表)架構

按照業務特色將數據拆分:併發

垂直拆分以及水平拆分------好比說利用用戶的user_id經過hash取模,而後路由到不一樣的分區。oracle

這麼作帶來的問題有兩個:一、當數據/負載增長時,須要人工介入,代價很是大。框架

二、select查詢有時候須要便利全部的分區,速度很是慢。

三、每一臺機器都要主從同步,管理起來太麻煩。

方案3、參考google的bigtable

主要是將一個bigtable拆分紅幾百萬個子表(主鍵有序)。

好處:一、數據不會丟失(hdfs),故障遷移,可擴展。二、子表有序,查詢快。

這樣的話,方案就生成了,參考bigtable,在hbase的開源基礎上本身開發一套。後來通過驗證發現不行,由於,首先hbase的開源不完全,每臺單機支持的數據有限,而後是必須引入分佈式事務2PC,通常時間在2~5s左右,由於對於hbase這種nosql只保證單行事務,若是要跨行跨表操做是支持不了的。而且分佈式事務太耗時,因此這個方案只能拋棄!

在設計oceanbase的時候,目標是支持10w+tps,100w+qps,100TB+數據,難道沒有方案了麼?-------------------------------------------------------------華麗的分割線-------------------------------------------------------------

既要有非關係數據庫的海量數據存儲,還要有關係型數據庫的事務,到底如何該解決呢?

通過數據分析,發現了隱藏在數據中的一個祕密:雖然業務線的數據量龐大,可是修改量實際不多。這個怎麼理解。

我打個比喻:

一、人口基數實際上很是大,可是考慮到出生/死亡/失蹤,這部分人口實際上在總人口中佔比很小。

二、金融帳務系統天天要記錄不少的流水,可是考慮到一半在線上保存一年的流水,那麼天天新增的幾乎佔比很小。

三、金融交易系統天天雖然要記錄不少交易,可是考慮到一半都保存一年以上的交易記錄,那麼新增的佔比很小的。

這就是隱藏在數據中的祕密!

其實大部分的數據,都是基數大,新增,刪除,修改量佔比不大。

那麼能夠這麼解決。採用單臺服務器記錄最近一段時間的修改增量(內存中記錄),而之前的數據不變(基線數據)。寫事務只在單臺服務器寫,避免了2PC,高效的實現了跨行跨表事務。而後按期合併修改增量到基線數據服務器。

-------------------------------------------------------------華麗的分割線-------------------------------------------------------------

基於上面描述,OB整個系統架構:

 

 

整個ob集羣包括:rootserver,updateserver,chunkserver,mergeserver這幾個類服務器。

client:與mysql兼容,協議相同。

rootserver:管理集羣,子表,數據分佈,副本。分爲主,副(主備數據同步)

updateserver:存儲ob中的增量數據(內存)主備

chunkserver:存儲基線數據

mergeserver:接受sql,解析,優化,轉發給chunkserver或者updateserver,合併結果給客戶端。

接下來咱們來深刻探討一下:

首先ob部署在多個機房,每一個機房一個ob集羣。

客戶端的請求過程:

一、請求rootserver獲取ob集羣中的mergeserver列表

二、按照必定策略選擇mergeserver

三、請求失敗後,從新選擇一臺mergeserver,若是某一臺被請求失敗超過必定次數,拉黑。

oceanbase集羣會根據路由規則控制流量比,因此不用擔憂負載的問題。

ob中的基線數據按照主鍵排序(查詢很是快)並劃分爲子表(每個256M),而且都有副本。而在rootserver中記錄了每一個子表在chunkserver的位置。

 

 

mergeserver會緩存子表的分部信息,根據請求轉發給該子表所在的chunkserver,若是寫操做還會轉發給updateserver。

在chunkserver中,通常存儲子表,而一個子表由多個sstable過程,每一個sstable的容量4k~64(主鍵有序)。

合併操做:

oceanbase按期觸發合併/數據分發操做,chunkserver會從updateserver中獲取一段時間更新的操做。(業務低谷時操做)

updateserver:

更新操做寫入內存,當內存數據量超過必定值時,生成快照存儲在SSD中。

按期合併/數據分發:把updateserver增量更新分發到chunkserver中。

一、updateserver凍結當前的活躍的內存表(Active Memory),生成凍結內存表,開啓新的活躍內存表後,緩存更新操做寫入新的活躍內存表。

二、updateserver通知rootserver數據版本變化,rootserver心跳通知chunkserver。

三、每臺chunkserver啓動按期合併或數據分發,從updateserver獲取每一個子表對應的增量更新數據。

爲何分爲按期合併和數據分發?

按期合併:chunkserver講本地sstable中的基線數據與凍結內存表中的增量更新數據歸併,生成新的sstable。(由於合併操做對服務器性能影響很是大,須要在業務低估時進行)

數據分發:chunkserver將updateserver中的凍結內存表中的增量緩存到本地。(不受業務高峯限制)

以上就是我對ob的原理的總結,其中也看出一些問題,首先updateserver須要很是大的內存,第二爲了不單點,應該是主備切換,這裏面用了zookeeper中的paxos算法,選舉主機。整個ob仍是很是複雜的,若是想深刻探究還須要花費很大的功夫啊!

相關文章
相關標籤/搜索