我們都知道阿里雙11偎漫,除了創(chuàng)造了世界史上的交易奇跡之外账月,也創(chuàng)造了世界技術(shù)史上的奇跡。支付寶的峰值達(dá)到了每秒12萬筆挪挤,這在技術(shù)界簡直是一個(gè)奇跡耘婚。為什么說他是一個(gè)奇跡呢罢浇?簡單的來解釋一下:其實(shí)在日常開發(fā)中,打交道最多的就是數(shù)據(jù)庫沐祷,好多開發(fā)都戲稱只會(huì)增嚷闭、刪、改赖临。但是千萬不要小看增胞锰、刪、改兢榨,因?yàn)榧僭O(shè)你只有一個(gè)用戶訪問的你的數(shù)據(jù)庫胜蛉,你怎么寫都可以,但是如果有幾十萬色乾,上百萬誊册,上千萬,乃至上億用戶呢暖璧?如果操作不當(dāng)案怯,那么你的數(shù)據(jù)庫一定會(huì)down掉。所以看上去簡單的東西其實(shí)一點(diǎn)都不簡單澎办,就好像風(fēng)清揚(yáng)一樣嘲碱,簡單的劍招卻蘊(yùn)含著上千變化金砍。
這里,我主要想揭秘下oceanbase麦锯,因?yàn)檎麄€(gè)支付寶的交易的庫都是依賴于它恕稠。oceanbase究竟是什么?用官方的話是這樣的:OceanBase是一個(gè)支持海量數(shù)據(jù)的高性能分布式數(shù)據(jù)庫系統(tǒng)扶欣,實(shí)現(xiàn)了數(shù)千億條記錄鹅巍、數(shù)百TB數(shù)據(jù)上的跨行跨表事務(wù),由淘寶核心系統(tǒng)研發(fā)部料祠、運(yùn)維骆捧、DBA、廣告髓绽、應(yīng)用研發(fā)等部門共同完成敛苇。那么以前在沒有使用ob之前,支付寶都用的什么呢顺呕?mysql或者oracle枫攀。這兩個(gè)一個(gè)是開源的數(shù)據(jù)庫,一個(gè)是甲骨文公司的商業(yè)付費(fèi)數(shù)據(jù)庫株茶。簡單的來說都是人家老外搞得脓豪!其實(shí)這兩個(gè)數(shù)據(jù)庫已經(jīng)很強(qiáng)大了,支付寶以前的框架都是基于這兩種數(shù)據(jù)庫的忌卤。但是隨著業(yè)務(wù)的發(fā)展扫夜,這兩種數(shù)據(jù)庫也帶來了弊端。
-------------------------------------------------------------華麗的分割線-------------------------------------------------------------
假設(shè)我們要撐起上千萬的并發(fā)量驰徊,上百PB笤闯,乃至TB的數(shù)據(jù)量。如何設(shè)計(jì)棍厂?
方案一颗味、單庫(熱備)
這個(gè)方案完全不行,原因不多說了牺弹。
方案二浦马、數(shù)據(jù)拆分(分庫分表)
按照業(yè)務(wù)特點(diǎn)將數(shù)據(jù)拆分:
垂直拆分以及水平拆分------比如說利用用戶的user_id通過hash取模,然后路由到不同的分區(qū)张漂。
這么做帶來的問題有兩個(gè):1晶默、當(dāng)數(shù)據(jù)/負(fù)載增加時(shí),需要人工介入航攒,代價(jià)非常大磺陡。
2、select查詢有時(shí)候需要便利所有的分區(qū),速度非常慢币他。
3坞靶、每一臺(tái)機(jī)器都要主從同步,管理起來太麻煩蝴悉。
方案三彰阴、參考google的bigtable
主要是將一個(gè)bigtable拆分成幾百萬個(gè)子表(主鍵有序)。
好處:1拍冠、數(shù)據(jù)不會(huì)丟失(hdfs)尿这,故障遷移,可擴(kuò)展倦微。2、子表有序正压,查詢快欣福。
這樣的話,方案就生成了焦履,參考bigtable拓劝,在hbase的開源基礎(chǔ)上自己開發(fā)一套。后來經(jīng)過驗(yàn)證發(fā)現(xiàn)不行嘉裤,因?yàn)橹A伲紫萮base的開源不徹底,每臺(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ù)陕靠,難道沒有方案了么?-------------------------------------------------------------華麗的分割線-------------------------------------------------------------
既要有非關(guān)系數(shù)據(jù)庫的海量數(shù)據(jù)存儲(chǔ)脱茉,還要有關(guān)系型數(shù)據(jù)庫的事務(wù)剪芥,到底如何該解決呢?
經(jīng)過數(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ù))撬统。寫事務(wù)只在單臺(tái)服務(wù)器寫,避免了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é)果給客戶端蛛蒙。
接下來我們來深入探討一下:
首先ob部署在多個(gè)機(jī)房糙箍,每個(gè)機(jī)房一個(gè)ob集群。
客戶端的請(qǐng)求過程:
1牵祟、請(qǐng)求rootserver獲取ob集群中的mergeserver列表
2深夯、按照一定策略選擇mergeserver
3、請(qǐng)求失敗后诺苹,重新選擇一臺(tái)mergeserver咕晋,如果某一臺(tái)被請(qǐng)求失敗超過一定次數(shù),拉黑收奔。
oceanbase集群會(huì)根據(jù)路由規(guī)則控制流量比掌呜,所以不用擔(dān)心負(fù)載的問題。
ob中的基線數(shù)據(jù)按照主鍵排序(查詢非称汉澹快)并劃分為子表(每一個(gè)256M)质蕉,并且都有副本。而在rootserver中記錄了每個(gè)子表在chunkserver的位置损姜。
mergeserver會(huì)緩存子表的分部信息饰剥,根據(jù)請(qǐng)求轉(zhuǎn)發(fā)給該子表所在的chunkserver殊霞,如果寫操作還會(huì)轉(zhuǎn)發(fā)給updateserver摧阅。
在chunkserver中,一般存儲(chǔ)子表绷蹲,而一個(gè)子表由多個(gè)sstable過程棒卷,每個(gè)sstable的容量4k~64(主鍵有序)。
合并操作:
oceanbase定期觸發(fā)合并/數(shù)據(jù)分發(fā)操作祝钢,chunkserver會(huì)從updateserver中獲取一段時(shí)間更新的操作比规。(業(yè)務(wù)低谷時(shí)操作)
updateserver:
更新操作寫入內(nèi)存,當(dāng)內(nèi)存數(shù)據(jù)量超過一定值時(shí)拦英,生成快照存儲(chǔ)在SSD中蜒什。
定期合并/數(shù)據(jù)分發(fā):把updateserver增量更新分發(fā)到chunkserver中。
1疤估、updateserver凍結(jié)當(dāng)前的活躍的內(nèi)存表(Active Memory)灾常,生成凍結(jié)內(nèi)存表,開啟新的活躍內(nèi)存表后铃拇,緩存更新操作寫入新的活躍內(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é)户敬,其中也看出一些問題落剪,首先updateserver需要非常大的內(nèi)存,第二為了避免單點(diǎn)尿庐,應(yīng)該是主備切換忠怖,這里面用了zookeeper中的paxos算法,選舉主機(jī)抄瑟。整個(gè)ob還是非常復(fù)雜的凡泣,如果想深入探究還需要花費(fèi)很大的功夫啊皮假!