支付寶雙11的功臣-分布式關(guān)系型數(shù)據(jù)庫(kù)(oceanbase)

我們都知道阿里雙11,除了創(chuàng)造了世界史上的交易奇跡之外,也創(chuàng)造了世界技術(shù)史上的奇跡。支付寶的峰值達(dá)到了每秒12萬(wàn)筆,這在技術(shù)界簡(jiǎn)直是一個(gè)奇跡。為什么說(shuō)他是一個(gè)奇跡呢?簡(jiǎn)單的來(lái)解釋一下:其實(shí)在日常開(kāi)發(fā)中,打交道最多的就是數(shù)據(jù)庫(kù),好多開(kāi)發(fā)都戲稱只會(huì)增、刪、改。但是千萬(wàn)不要小看增、刪、改,因?yàn)榧僭O(shè)你只有一個(gè)用戶訪問(wèn)的你的數(shù)據(jù)庫(kù),你怎么寫(xiě)都可以,但是如果有幾十萬(wàn),上百萬(wàn),上千萬(wàn),乃至上億用戶呢?如果操作不當(dāng),那么你的數(shù)據(jù)庫(kù)一定會(huì)down掉。所以看上去簡(jiǎn)單的東西其實(shí)一點(diǎn)都不簡(jiǎn)單,就好像風(fēng)清揚(yáng)一樣,簡(jiǎn)單的劍招卻蘊(yùn)含著上千變化。

這里,我主要想揭秘下oceanbase,因?yàn)檎麄€(gè)支付寶的交易的庫(kù)都是依賴于它。oceanbase究竟是什么?用官方的話是這樣的:OceanBase是一個(gè)支持海量數(shù)據(jù)的高性能分布式數(shù)據(jù)庫(kù)系統(tǒng),實(shí)現(xiàn)了數(shù)千億條記錄、數(shù)百TB數(shù)據(jù)上的跨行跨表事務(wù),由淘寶核心系統(tǒng)研發(fā)部、運(yùn)維、DBA、廣告、應(yīng)用研發(fā)等部門(mén)共同完成。那么以前在沒(méi)有使用ob之前,支付寶都用的什么呢?mysql或者oracle。這兩個(gè)一個(gè)是開(kāi)源的數(shù)據(jù)庫(kù),一個(gè)是甲骨文公司的商業(yè)付費(fèi)數(shù)據(jù)庫(kù)。簡(jiǎn)單的來(lái)說(shuō)都是人家老外搞得!其實(shí)這兩個(gè)數(shù)據(jù)庫(kù)已經(jīng)很強(qiáng)大了,支付寶以前的框架都是基于這兩種數(shù)據(jù)庫(kù)的。但是隨著業(yè)務(wù)的發(fā)展,這兩種數(shù)據(jù)庫(kù)也帶來(lái)了弊端。

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

假設(shè)我們要撐起上千萬(wàn)的并發(fā)量,上百PB,乃至TB的數(shù)據(jù)量。如何設(shè)計(jì)?

方案一、單庫(kù)(熱備)

這個(gè)方案完全不行,原因不多說(shuō)了。

方案二、數(shù)據(jù)拆分(分庫(kù)分表)

按照業(yè)務(wù)特點(diǎn)將數(shù)據(jù)拆分:

垂直拆分以及水平拆分------比如說(shuō)利用用戶的user_id通過(guò)hash取模,然后路由到不同的分區(qū)。

這么做帶來(lái)的問(wèn)題有兩個(gè):1、當(dāng)數(shù)據(jù)/負(fù)載增加時(shí),需要人工介入,代價(jià)非常大。

2、select查詢有時(shí)候需要便利所有的分區(qū),速度非常慢。

3、每一臺(tái)機(jī)器都要主從同步,管理起來(lái)太麻煩。

方案三、參考google的bigtable

主要是將一個(gè)bigtable拆分成幾百萬(wàn)個(gè)子表(主鍵有序)。

好處:1、數(shù)據(jù)不會(huì)丟失(hdfs),故障遷移,可擴(kuò)展。2、子表有序,查詢快。

這樣的話,方案就生成了,參考bigtable,在hbase的開(kāi)源基礎(chǔ)上自己開(kāi)發(fā)一套。后來(lái)經(jīng)過(guò)驗(yàn)證發(fā)現(xiàn)不行,因?yàn)椋紫萮base的開(kāi)源不徹底,每臺(tái)單機(jī)支持的數(shù)據(jù)有限,然后是必須引入分布式事務(wù)2PC,一般時(shí)間在2~5s左右,因?yàn)閷?duì)于hbase這種nosql只保證單行事務(wù),如果要跨行跨表操作是支持不了的。并且分布式事務(wù)太耗時(shí),所以這個(gè)方案只能拋棄!

在設(shè)計(jì)oceanbase的時(shí)候,目標(biāo)是支持10w+tps,100w+qps,100TB+數(shù)據(jù),難道沒(méi)有方案了么?-------------------------------------------------------------華麗的分割線-------------------------------------------------------------

既要有非關(guān)系數(shù)據(jù)庫(kù)的海量數(shù)據(jù)存儲(chǔ),還要有關(guān)系型數(shù)據(jù)庫(kù)的事務(wù),到底如何該解決呢?

經(jīng)過(guò)數(shù)據(jù)分析,發(fā)現(xiàn)了隱藏在數(shù)據(jù)中的一個(gè)秘密:雖然業(yè)務(wù)線的數(shù)據(jù)量龐大,但是修改量實(shí)際很少。這個(gè)怎么理解。

我打個(gè)比喻:

1、人口基數(shù)實(shí)際上非常大,但是考慮到出生/死亡/失蹤,這部分人口實(shí)際上在總?cè)丝谥姓急群苄 ?/p>

2、金融賬務(wù)系統(tǒng)每天要記錄很多的流水,但是考慮到一半在線上保存一年的流水,那么每天新增的幾乎占比很小。

3、金融交易系統(tǒng)每天雖然要記錄很多交易,但是考慮到一半都保存一年以上的交易記錄,那么新增的占比很小的。

這就是隱藏在數(shù)據(jù)中的秘密!

其實(shí)大部分的數(shù)據(jù),都是基數(shù)大,新增,刪除,修改量占比不大。

那么可以這么解決。采用單臺(tái)服務(wù)器記錄最近一段時(shí)間的修改增量(內(nèi)存中記錄),而以前的數(shù)據(jù)不變(基線數(shù)據(jù))。寫(xiě)事務(wù)只在單臺(tái)服務(wù)器寫(xiě),避免了2PC,高效的實(shí)現(xiàn)了跨行跨表事務(wù)。然后定期合并修改增量到基線數(shù)據(jù)服務(wù)器。

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

基于上面描述,OB整個(gè)系統(tǒng)架構(gòu):

整個(gè)ob集群包括:rootserver,updateserver,chunkserver,mergeserver這幾個(gè)類服務(wù)器。

client:與mysql兼容,協(xié)議相同。

rootserver:管理集群,子表,數(shù)據(jù)分布,副本。分為主,副(主備數(shù)據(jù)同步)

updateserver:存儲(chǔ)ob中的增量數(shù)據(jù)(內(nèi)存)主備

chunkserver:存儲(chǔ)基線數(shù)據(jù)

mergeserver:接受sql,解析,優(yōu)化,轉(zhuǎn)發(fā)給chunkserver或者updateserver,合并結(jié)果給客戶端。

接下來(lái)我們來(lái)深入探討一下:

首先ob部署在多個(gè)機(jī)房,每個(gè)機(jī)房一個(gè)ob集群。

客戶端的請(qǐng)求過(guò)程:

1、請(qǐng)求rootserver獲取ob集群中的mergeserver列表

2、按照一定策略選擇mergeserver

3、請(qǐng)求失敗后,重新選擇一臺(tái)mergeserver,如果某一臺(tái)被請(qǐng)求失敗超過(guò)一定次數(shù),拉黑。

oceanbase集群會(huì)根據(jù)路由規(guī)則控制流量比,所以不用擔(dān)心負(fù)載的問(wèn)題。

ob中的基線數(shù)據(jù)按照主鍵排序(查詢非常快)并劃分為子表(每一個(gè)256M),并且都有副本。而在rootserver中記錄了每個(gè)子表在chunkserver的位置。

mergeserver會(huì)緩存子表的分部信息,根據(jù)請(qǐng)求轉(zhuǎn)發(fā)給該子表所在的chunkserver,如果寫(xiě)操作還會(huì)轉(zhuǎn)發(fā)給updateserver。

在chunkserver中,一般存儲(chǔ)子表,而一個(gè)子表由多個(gè)sstable過(guò)程,每個(gè)sstable的容量4k~64(主鍵有序)。

合并操作:

oceanbase定期觸發(fā)合并/數(shù)據(jù)分發(fā)操作,chunkserver會(huì)從updateserver中獲取一段時(shí)間更新的操作。(業(yè)務(wù)低谷時(shí)操作)

updateserver:

更新操作寫(xiě)入內(nèi)存,當(dāng)內(nèi)存數(shù)據(jù)量超過(guò)一定值時(shí),生成快照存儲(chǔ)在SSD中。

定期合并/數(shù)據(jù)分發(fā):把updateserver增量更新分發(fā)到chunkserver中。

1、updateserver凍結(jié)當(dāng)前的活躍的內(nèi)存表(Active Memory),生成凍結(jié)內(nèi)存表,開(kāi)啟新的活躍內(nèi)存表后,緩存更新操作寫(xiě)入新的活躍內(nèi)存表。

2、updateserver通知rootserver數(shù)據(jù)版本變化,rootserver心跳通知chunkserver。

3、每臺(tái)chunkserver啟動(dòng)定期合并或數(shù)據(jù)分發(fā),從updateserver獲取每個(gè)子表對(duì)應(yīng)的增量更新數(shù)據(jù)。

為什么分為定期合并和數(shù)據(jù)分發(fā)?

定期合并:chunkserver講本地sstable中的基線數(shù)據(jù)與凍結(jié)內(nèi)存表中的增量更新數(shù)據(jù)歸并,生成新的sstable。(因?yàn)楹喜⒉僮鲗?duì)服務(wù)器性能影響非常大,需要在業(yè)務(wù)低估時(shí)進(jìn)行)

數(shù)據(jù)分發(fā):chunkserver將updateserver中的凍結(jié)內(nèi)存表中的增量緩存到本地。(不受業(yè)務(wù)高峰限制)

以上就是我對(duì)ob的原理的總結(jié),其中也看出一些問(wèn)題,首先updateserver需要非常大的內(nèi)存,第二為了避免單點(diǎn),應(yīng)該是主備切換,這里面用了zookeeper中的paxos算法,選舉主機(jī)。整個(gè)ob還是非常復(fù)雜的,如果想深入探究還需要花費(fèi)很大的功夫啊!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容