黃 貴, 莊明強
(阿里巴巴集團公司,杭州 310000)
?
OceanBase分布式存儲引擎
黃 貴, 莊明強
(阿里巴巴集團公司,杭州 310000)
OceanBase是一個分布式關(guān)系型數(shù)據(jù)庫,其目的是存儲海量的高速增長的結(jié)構(gòu)化數(shù)據(jù),以廉價的服務(wù)器集群實現(xiàn)高可用、高可擴展、高性價比的服務(wù).OceanBase采用內(nèi)外存混合存儲的模式,使用內(nèi)存存儲增量(新寫入)數(shù)據(jù),而使用外存存儲基線(只讀)數(shù)據(jù),并將基線數(shù)據(jù)劃分成大致等量的數(shù)據(jù)分片并采用分布式B+tree的形式將分片存放在很多的數(shù)據(jù)服務(wù)器上,利用定時合并機制不斷將增量數(shù)據(jù)與基線數(shù)據(jù)融合.本文介紹OceanBase基線數(shù)據(jù)存儲的基本結(jié)構(gòu)和分布方式、定時合并機制,以及基線數(shù)據(jù)在OceanBase中的具體存儲格式的設(shè)計和實現(xiàn).
存儲引擎; 分布式系統(tǒng); 每日合并; 分塊存儲; 基線數(shù)據(jù); 增量數(shù)據(jù)
隨著大數(shù)據(jù)時代的到臨,越來越多的應(yīng)用需要處理數(shù)百TB乃至PB級的數(shù)據(jù).當(dāng)前,學(xué)術(shù)界與工業(yè)界已經(jīng)出現(xiàn)了多種數(shù)據(jù)管理技術(shù),但是這些技術(shù)在帶來一定優(yōu)勢的同時,也具有一定的局限性.首先,分布式文件系統(tǒng)GFS[1]、分布式表格系統(tǒng)BigTable[2]和全球分布式數(shù)據(jù)庫Spanner[3]使用分布式系統(tǒng)解決了PB級數(shù)據(jù)的實時存儲和查詢,但BigTable不支持完整的關(guān)系數(shù)據(jù)模型,使用有一定的限制;傳統(tǒng)關(guān)系數(shù)據(jù)庫(例如Oracle[4]、DB2[5]和MySql[6])功能完善,但可擴展性欠佳;內(nèi)存數(shù)據(jù)庫(VoltDB[7]、MemSQL[8])已具備高性能,但其受內(nèi)存大小和成本限制.因此,亟需設(shè)計與開發(fā)新型數(shù)據(jù)管理技術(shù),以實現(xiàn)高性、低成本、可擴展和高可用性等目標(biāo).
為了滿足阿里巴巴迅速增長的數(shù)據(jù)處理需求,我們設(shè)計、實現(xiàn)并部署了分布式關(guān)系數(shù)據(jù)庫OceanBase,以可靠地處理數(shù)百TB級別的數(shù)據(jù).OceanBase能部署在數(shù)百臺機器上,具有關(guān)系型數(shù)據(jù)庫的功能,并已經(jīng)實現(xiàn)了上述四個目標(biāo).OceanBase將分布式和關(guān)系數(shù)據(jù)庫巧妙結(jié)合,充分發(fā)揮分布式系統(tǒng)可擴展強和高可用性優(yōu)點,在相對廉價的普通硬件上提供可靠的數(shù)據(jù)服務(wù).OceanBase使用了很多關(guān)系型數(shù)據(jù)庫的設(shè)計策略,支持完整的關(guān)系數(shù)據(jù)模型.分布式存儲引擎是OceanBase的核心模塊之一,主要分為兩大部分:內(nèi)存事務(wù)存儲引擎和分布式基線數(shù)據(jù)存儲引擎.本文主要介紹分布式基線數(shù)據(jù)存儲引擎的設(shè)計和實現(xiàn).
本文第1節(jié)描述OceanBase基線數(shù)據(jù)、增量數(shù)據(jù)的數(shù)據(jù)模型;第2節(jié)描述每日合并如何將基線數(shù)據(jù)與增量數(shù)據(jù)進(jìn)行融合;第3節(jié)描述數(shù)據(jù)分片的容錯與負(fù)載均衡;第4節(jié)描述基線數(shù)據(jù)分裂與合并;第5節(jié)描述基線數(shù)據(jù)分塊存儲格式;第6節(jié)總結(jié)全文.
1.1 讀寫分離結(jié)構(gòu)
大量數(shù)據(jù)庫應(yīng)用每天增量修改的數(shù)據(jù)量相對較小,而保持不變的數(shù)據(jù)量很大,這兩部分?jǐn)?shù)據(jù)需要根據(jù)不同特點采用不同的存儲管理方式.因此OceanBase使用讀寫分離的結(jié)構(gòu),將數(shù)據(jù)分為基線數(shù)據(jù)和修改增量,增量刪改數(shù)據(jù)保存在單臺服務(wù)器內(nèi)存中(redo log保存在磁盤),稱為MemTable,對應(yīng)的基線數(shù)據(jù)(即數(shù)據(jù)庫在MemTable開始時刻的快照),按照行主鍵排序后,動態(tài)分成多個數(shù)據(jù)分區(qū),稱為Tablet,每個Tablet的多個副本均勻分布到多臺數(shù)據(jù)節(jié)點(我們稱之為ChunkServer)的多塊磁盤(通常是SSD)上,Tablet是數(shù)據(jù)分布和負(fù)載均衡的最小單位.圖1描述了讀寫分離結(jié)構(gòu).
圖1 OceanBase的讀寫分離結(jié)構(gòu)
單臺服務(wù)器內(nèi)存有限,無法存儲持續(xù)所有修改增量,因此OceanBase通常每天在某個時刻(例如后半夜業(yè)務(wù)低谷期)凍結(jié)當(dāng)前MemTable并開啟新的MemTable,此后新的增刪改寫入新的MemTable,然后系統(tǒng)在后臺將凍結(jié)的MemTable與當(dāng)前基線數(shù)據(jù)融合,生成新的基線數(shù)據(jù),這個過程稱為每日合并.每日合并完成后,凍結(jié)的MemTable以及舊的Tablet即可釋放,其占用的內(nèi)存也被回收.
1.2 分布式B+tree結(jié)構(gòu)
一個OceanBase集群存儲了很多表,每個表包含了一個Tablet集合,每個Tablet包含某個范圍內(nèi)的所有行數(shù)據(jù).OceanBase使用一個三層、類似B+樹的結(jié)構(gòu)存儲Tablet的位置信息,如圖2所示:
圖2 Tablet位置層級圖
圖2最右邊為User Table,每個User Table的基線數(shù)據(jù)包含多個User Tablet,在每日合并中User Tablet按照配置的大小分裂成多個User Tablet,共分為三層.第三層為User Table的Meta Table,稱為User Meta Table.每個User Table對應(yīng)一個User Meta Table,每行存儲一個User Tablet的位置信息,User Meta Table的基線數(shù)據(jù)包含多個User Meta Tablet.第二層為User Meta Table的Meta Table,稱為User Root Table,每行存儲一個User Meta Tablet的位置信息,User Root Table的基線數(shù)據(jù)只包含一個Tablet,不允許分裂.第一層為User Root Table的Meta Table,稱為First Root Table,每行存儲一個User Root Tablet的位置信息,F(xiàn)irst Root Table的基線數(shù)據(jù)只包含一個Tablet,不允許分裂.
OceanBase采用分塊SSTable格式來存儲基線數(shù)據(jù)的文件.分塊SSTable是持久化、按行主鍵有序、不可更改的map結(jié)構(gòu).存儲基線數(shù)據(jù)的數(shù)據(jù)節(jié)點包含一個Tablet集合, OceanBase使用類似B+樹的結(jié)構(gòu)來定位行數(shù)據(jù)在數(shù)據(jù)節(jié)點磁盤上的位置,如圖3所示.
圖3 數(shù)據(jù)存儲邏輯圖
每個Tablet使用一個SSTable存儲,分塊SSTable 包含一系列宏塊(通常每個宏塊的大小是2M,這個大小可以配置),分塊SSTable使用宏塊索引定位宏塊位置,在打開SSTable時,SSTable的宏塊索引被加載到內(nèi)存中.宏塊內(nèi)部包含一系列微塊(通常大小為16K,這個大小可以配置),宏塊使用微塊索引定位微塊位置,在打開宏塊時,宏塊的微塊索引被加載到內(nèi)存中.
在數(shù)據(jù)節(jié)點查詢數(shù)據(jù)時,通過二分查找在Tablet索引中找到Tablet,然后從Tablet對應(yīng)的SSTable的宏塊索引中使用二分查找找到宏塊位置,然后從宏塊的微塊索引中使用二分查找找到微塊位置,然后從硬盤讀取相應(yīng)的微塊,最后從微塊中查詢到需要的數(shù)據(jù).
2.1 每日合并過程
隨著寫操作的執(zhí)行,MemTable的大小不斷增加,當(dāng)MemTable尺寸達(dá)到某個閾值或者系統(tǒng)達(dá)到預(yù)設(shè)凍結(jié)時間的時候,OceanBase凍結(jié)當(dāng)前MemTable并創(chuàng)建新的MemTable,每日合并將凍結(jié)的MemTable與當(dāng)前基線數(shù)據(jù)在后臺進(jìn)行融合,生成新的基線數(shù)據(jù).每日合并完成后,凍結(jié)的MemTable以及舊的Tablet即可釋放,其占用的內(nèi)存也被回收.每日合并可以收縮服務(wù)器使用的內(nèi)存,以及在服務(wù)器災(zāi)難恢復(fù)過程中,減少必須從提交日志里讀取的數(shù)據(jù)量.在每日合并過程中,正在進(jìn)行的讀寫操作仍能繼續(xù).每日合并過程如圖4所示.
圖4 每日合并
MemTable凍結(jié)后,存儲基線數(shù)據(jù)的數(shù)據(jù)節(jié)點啟動多個合并線程,每個合并線程以Tablet為單位,向存儲修改增量的服務(wù)器請求Tablet的修改增量數(shù)據(jù),并與該Tablet的本地基線數(shù)據(jù)進(jìn)行融合.在每日合并過程中,Tablet的不同副本按照相同的規(guī)則進(jìn)行分裂,當(dāng)所有數(shù)據(jù)節(jié)點的Tablet都合并完成后,回收凍結(jié)的MemTable和舊Tablet,釋放內(nèi)存和磁盤空間.
2.2 每日合并版本更新
OceanBase使用版本號管理基線數(shù)據(jù)和增量數(shù)據(jù),增量數(shù)據(jù)一般比基線數(shù)據(jù)高一個版本.每日合并時,將凍結(jié)的高版本增量數(shù)據(jù)與低版本的基線數(shù)據(jù)合并成新的高版本基線數(shù)據(jù).例如基線數(shù)據(jù)版本為1,增量數(shù)據(jù)版本為2,MemTable凍結(jié)時創(chuàng)建一個新的MemTable提供寫服務(wù),凍結(jié)的MemTable版本為2,新創(chuàng)建的Memtable版本為3,然后每日合并將版本為1的基線數(shù)據(jù)與版本為2的凍結(jié)MemTable合并成版本2的基線數(shù)據(jù).
為了減少版本管理的負(fù)擔(dān),存儲基線數(shù)據(jù)的數(shù)據(jù)節(jié)點保存兩個版本的基線數(shù)據(jù),凍結(jié)的高版本增量數(shù)據(jù)在該版本每日合并完成后立即刪除.用戶可以指定保存最后n個版本(一般是兩個,可以修改)的基線數(shù)據(jù).
由于基線數(shù)據(jù)是多個副本分布在多個ChunkServer上,而每個ChunkServer的合并進(jìn)度并不一致,在合并過程中的讀事務(wù)會因為調(diào)度到不同的服務(wù)器上,查詢到的Tablet有可能是不同版本的基線數(shù)據(jù),而這并不會造成數(shù)據(jù)不一致的問題,如上所述的合并過程,假設(shè)Tablet1在ChunkServer1上合并到了版本2,而在ChunkServer2仍然是版本1,兩個并發(fā)的請求分別發(fā)送到兩個ChunkServer上,ChunkServer1向UpdateServer請求MemTable版本3的數(shù)據(jù),與本地版本為2的基線數(shù)據(jù)合并,返回最終結(jié)果,ChunkServer2向UpdateServer請求MemTable版本2的凍結(jié)增量和MemTable版本3的數(shù)據(jù),與本地版本為1的基線數(shù)據(jù)合并,返回最終結(jié)果,這兩種合并的結(jié)果都是完全一致的.
組成OceanBase數(shù)據(jù)庫的集群中所使用的服務(wù)器均為廉價的PC 服務(wù)器,其可靠性遠(yuǎn)不如高端服務(wù)器和存儲.需要指出的是,存儲系統(tǒng)中頻繁使用的存儲介質(zhì)(機械磁盤)屬于損壞概率最高的一類硬件.
OceanBase采用基線數(shù)據(jù)多個副本的機制,以避免由于存儲或是服務(wù)器損壞而導(dǎo)致的數(shù)據(jù)損失或無法提供服務(wù).在通常情況下,OceanBase集群中的基線數(shù)據(jù)會保留三個副本,分別存放在不同服務(wù)器上;不管某一個服務(wù)器因何原因下線,其持有的數(shù)據(jù)都會在其他服務(wù)器上有相同的副本,從而提供完整、不間斷的服務(wù).
3.1 自動重試機制
查詢服務(wù)器在讀事務(wù)中查詢某個數(shù)據(jù)分片的數(shù)據(jù).如果發(fā)現(xiàn)一個數(shù)據(jù)服務(wù)器執(zhí)行查詢失敗,會根據(jù)這個數(shù)據(jù)分片的位置信息,重新選取一臺數(shù)據(jù)服務(wù)器進(jìn)行查詢,這個過程會檢查整個查詢過程的超時時間,如果用戶給定的超時時間未到,則可以一直重試可用的副本所在的數(shù)據(jù)服務(wù)器一直到成功為止.對于用戶來說,該重試機制是透明的.
對于查詢失敗的ChunkServer,MergeServer會在失敗一定次數(shù)之后將其加入黑名單,加入黑名單中的ChunkServer在之后一段時間的查詢計劃當(dāng)中,都會被排除在外;直到指定時間過去之后,才重新從黑名單中洗白,開始重新加入查詢列表,因為ChunkServer可能重新加入集群而提供正常的服務(wù).MergeServer會在必要時更新Tablet的位置信息,以免位置信息因為數(shù)據(jù)復(fù)制和遷移而過時.
當(dāng)服務(wù)器因維護或硬件損壞等因素下線時,無法恢復(fù)其保存的數(shù)據(jù).換言之,這些下線的服務(wù)器中所有存儲的副本都會永久失效.RootServer會偵測到這種情況,并適時發(fā)起數(shù)據(jù)副本的復(fù)制操作,以補足默認(rèn)個數(shù)的副本,保證系統(tǒng)正常運行.
得益于OceanBase的讀寫分離設(shè)計,只讀部分的基線數(shù)據(jù)復(fù)制非常容易,因為數(shù)據(jù)復(fù)制的副本在一個合并周期內(nèi)是不進(jìn)行任何修改的,因此數(shù)據(jù)復(fù)制就是對這個只讀數(shù)據(jù)副本的拷貝.在其他分布式系統(tǒng)中[引用],由于是讀寫并發(fā)的,數(shù)據(jù)副本是可變的,在復(fù)制的時候往往會產(chǎn)生新的數(shù)據(jù),復(fù)制的過程是一個循環(huán)追趕的過程.
OceanBase的副本復(fù)制系統(tǒng),為了提高系統(tǒng)的魯棒性,可以在集群之間,甚至是不同版本的異構(gòu)集群之間進(jìn)行.在進(jìn)行副本復(fù)制時,可以根據(jù)復(fù)制源和目的數(shù)據(jù)格式的版本來確定使用邏輯復(fù)制或是物理復(fù)制.
3.2 負(fù)載均衡
OceanBase良好的擴展性保證集群在運行服務(wù)的過程中可以隨意地增減服務(wù)器,為了在集群伸縮的過程中不影響服務(wù)的質(zhì)量,隨時保證系統(tǒng)的各個服務(wù)器的負(fù)載均衡是非常必要的,OceanBase的控制節(jié)點RootServer負(fù)責(zé)整個集群的負(fù)載均衡控制,每個數(shù)據(jù)節(jié)點ChunkServer會定期匯報負(fù)載信息,比如Tablet個數(shù)、大小、系統(tǒng)容量等;RootServer匯總這些信息以后進(jìn)行計算,得出每個ChunkServer應(yīng)該承載的Tablet個數(shù)或大小,再根據(jù)目標(biāo)值進(jìn)行目標(biāo)間的遷移任務(wù)調(diào)度,直到整個集群的每個服務(wù)器負(fù)載基本相當(dāng).
OceanBase的數(shù)據(jù)分片劃分是按照主鍵(PK)排序以后,根據(jù)數(shù)據(jù)的物理大小進(jìn)行范圍劃分為大致相當(dāng)?shù)腡ablet,一般單個Tablet大小為256MB;隨著數(shù)據(jù)庫的不斷修改,Tablet基線數(shù)據(jù)與增量數(shù)據(jù)每日合并的過程當(dāng)中,某些Tablet會不斷地插入新的數(shù)據(jù),變得越來越大,某些Tablet可能會不斷地刪除數(shù)據(jù),變得越來越??;一段時間以后,系統(tǒng)中的Tablet大小不一,在各個服務(wù)器中分布也不均等,會導(dǎo)致熱點集中,影響查詢性能和負(fù)載均衡.
為了使Tablet在運行的過程中一直保持大小均等,系統(tǒng)會在每日合并的過程中發(fā)起Tablet的分裂和合并過程,如果發(fā)現(xiàn)每日合并的過程中Tablet過大,則自動將Tablet分裂為多個標(biāo)準(zhǔn)大小的Tablet,如果發(fā)現(xiàn)每日合并過程中Tablet過小,則會在每日合并結(jié)束后將相鄰的Tablet合并.
4.1 數(shù)據(jù)分片的分裂方法
在其他類似采用主鍵排序進(jìn)行數(shù)據(jù)分片的分布式系統(tǒng),比如HBase[引用]當(dāng)中,進(jìn)行數(shù)據(jù)分片的自動分裂往往是一個非常復(fù)雜的過程,因為每個數(shù)據(jù)分片在不斷地寫入,而且要同步到其他副本;要在多個副本上保持一致性,也就是找到一個一致的分裂點,從而使分裂以后的各個子范圍保持一致,是一個很困難的過程.HBase采用的是一個使用Master節(jié)點作為仲裁來保證一致的方法,這個分裂的過程是一個很長的分布式事務(wù),一旦涉及到的某個節(jié)點出現(xiàn)問題,難于回滾,很可能需要人工介入,因此在實踐當(dāng)中,數(shù)據(jù)分裂會被人為禁止甚至采用手工的方法進(jìn)行.
OceanBase的基線數(shù)據(jù)是只讀的,而每日合并的過程,如前所述,是將某個版本的只讀數(shù)據(jù)與UpdateServer中的相鄰的凍結(jié)版本的數(shù)據(jù)進(jìn)行合并,生成一份新版本的只讀基線數(shù)據(jù)的過程,因為每日合并的源(只讀的基線數(shù)據(jù))在每個ChunkServer上的副本完全一致,加上合并的增量(凍結(jié)版本的增量數(shù)據(jù))在每個UpdateServer上也完全一致,而每日合并的算法完全一致,所以只需在每日合并過程中采用完全相同的分裂規(guī)則,則可以保證分裂的結(jié)果是完全一致的.
OceanBase不需要仲裁來決定每個需要分裂的Tablet的分裂點,也不需要分布式事務(wù)來保證分裂的過程,而是完全采用每個副本獨立計算分裂點的方法.為了保證分裂的大小均等并且不會分裂出過小的數(shù)據(jù)分片,我們設(shè)定了一個分裂溢出比例,假設(shè)Tablet標(biāo)準(zhǔn)大小為S,分裂溢出比例為p, 那么在每日合并過程當(dāng)中,如果生成的數(shù)據(jù)大小超過了S,我們記錄一個分裂點,并且如果余下生成的數(shù)據(jù)大小超過了(S*p),將前一個分裂點確定為一個實際的分裂點,如果余下生成的數(shù)據(jù)大小沒有超過(S*p),那么不進(jìn)行分裂,將整個數(shù)據(jù)作為一個Tablet,如果生成數(shù)據(jù)需要多次分裂,以此類推,每超過S的數(shù)據(jù)分片,都計算余下的數(shù)據(jù)是否構(gòu)成一次真正的分裂.因此,這個分裂的結(jié)果保證生成的Tablet最大不會超過S*(1+p),而最小不會小于S*p;實際過程,我們一般選用p為0.5.
4.2 數(shù)據(jù)分片的合并方法
如果每日合并的過程中,某些Tablet因為數(shù)據(jù)刪除變得過小,就會觸發(fā)Tablet合并過程,合并過程是由控制節(jié)點RootServer發(fā)起的,在每日合并完成之后,RootServer會掃描數(shù)據(jù)分片的元數(shù)據(jù)集合RootTable,如果發(fā)現(xiàn)范圍上連續(xù)的Tablet都小于標(biāo)準(zhǔn)大小,滿足合并條件,比如大小累加以后接近標(biāo)準(zhǔn)大小,則觸發(fā)合并,在掃描整個RootTable后,RootServer會建立一個合并計劃,首先將要合并的相鄰的Tablets中的每一個小的Tablet的副本都遷移到相同的ChunkServer上,然后對每個ChunkServer推送合并命令,ChunkServer接收到命令之后,在本地將小的Tablet(這個時候它們的實際分片數(shù)據(jù)都應(yīng)該已經(jīng)遷移到了本地)合并為一個大的Tablet,最后將合并后的結(jié)果匯報,RootServer會對比推送的命令,如果結(jié)果一致,則接收匯報結(jié)果并修改元數(shù)據(jù).
5.1 為何引入分塊存儲格式
如前所述,數(shù)據(jù)的每日合并過程是將某個版本只讀基線數(shù)據(jù)與凍結(jié)的增量數(shù)據(jù)進(jìn)行合并的過程,而這個合并的過程需要將兩份數(shù)據(jù)全部讀取到內(nèi)存當(dāng)中,逐行的進(jìn)行比對,進(jìn)行歸并排序,并將主鍵相同的行進(jìn)行數(shù)據(jù)合并的過程,這個過程至少需要讀取舊版本的基線數(shù)據(jù),加上凍結(jié)的增量數(shù)據(jù),并且寫入新的版本基線數(shù)據(jù).這個過程必然對系統(tǒng)的磁盤讀寫IO產(chǎn)生巨大的挑戰(zhàn).
OceanBase面向的應(yīng)用通常都是數(shù)據(jù)總量(只讀基線數(shù)據(jù))非常大,但一段時間(例如一天)內(nèi)增刪改的數(shù)據(jù)總量(增量數(shù)據(jù))通常不大,通過對線上已經(jīng)運行的數(shù)據(jù)庫實例的數(shù)據(jù)分析,我們發(fā)現(xiàn),將Tablet的尺寸劃分為不同的大小,其被修改的幾率也不同,具體分析數(shù)據(jù)結(jié)果如表1所示.
表1 Tablet的尺寸劃分
為了避免每日合并的時候?qū)⑺械幕€數(shù)據(jù)全部讀一遍,并且合并以后重復(fù)寫入磁盤,將Tablet劃分的更小,并通過判斷是否有增量的數(shù)據(jù)來進(jìn)行合并的方式,絕大部分沒有修改的基線數(shù)據(jù)不參與到合并過程當(dāng)中,只是對必要的被修改過的Tablet進(jìn)行實際的合并操作,將原來的每日合并的實際運算量減少到合理水平.
5.2 分塊存儲格式結(jié)構(gòu)
如果直接將Tablet標(biāo)準(zhǔn)大小設(shè)置為2 MB,其個數(shù)會變?yōu)樵瓉淼?28倍.在某些應(yīng)用當(dāng)中,由于Tablet個數(shù)已經(jīng)很多,這種膨脹比率會使得RootServer在管理元數(shù)據(jù)RootTable的時候付出極大的代價,而在一個龐大的RootTable中查詢定位到具體的Tablet也會耗費更多的時間,因此OceanBase的存儲結(jié)構(gòu)并沒有直接將Tablet大小縮減,而是引入了我們稱為分塊存儲結(jié)構(gòu)的全新格式.
保持Tablet的標(biāo)準(zhǔn)大小不變,而Tablet內(nèi)部劃分為固定大小的數(shù)據(jù)塊,我們稱這種數(shù)據(jù)塊為“宏塊”,宏塊的大小一般是2 MB,這也是每日合并的基本單位.而宏塊又劃分為微塊,宏塊中存放微塊的索引用于查詢,由于引入了宏塊這個層次,整個系統(tǒng)的存儲結(jié)構(gòu)是Tablet,宏塊,以及微塊三層組成.引入宏塊層次以后,由于宏塊本身需要元數(shù)據(jù),而這種元數(shù)據(jù)本身是存儲在ChunkServer上,如果以每個磁盤2 TB的數(shù)據(jù)來算,用2 MB作為宏塊大小,一共是1 M個宏塊,按每個宏塊需要約100 byte大小的元數(shù)據(jù),總共需要耗費100 MB大小的內(nèi)存,這在ChunkServer上可以接受的.
ChunkServer上的每個磁盤中,都會初始化一個數(shù)據(jù)文件,數(shù)據(jù)文件會被劃分為固定大小的宏塊,宏塊是存放數(shù)據(jù)的基本單元,不僅Tablet的實際數(shù)據(jù),包括Tablet元數(shù)據(jù),以及宏塊元數(shù)據(jù)本身也會存放在宏塊當(dāng)中(如圖5所示).Tablet元數(shù)據(jù)除了Tablet本身所在的范圍外,最主要的部分就是包含組成其自身的宏塊的索引.
圖5 分塊SSTable格式
5.3 分塊存儲的每日合并過程
ChunkServer在進(jìn)行對每個Tablet進(jìn)行每日合并操作時,會遍歷這個Tablet元數(shù)據(jù)中的宏塊索引,根據(jù)宏塊索引編號引用的宏塊,計算其主鍵范圍,通過查詢UpdateServer判斷宏塊對應(yīng)的范圍是否有增量數(shù)據(jù),如果有增量,則對該宏塊進(jìn)行每日合并,在數(shù)據(jù)文件中分配一個新的宏塊位置,將合并生成的數(shù)據(jù)寫入新分配的宏塊當(dāng)中,并將新宏塊的索引信息加入新版本的Tablet元信息;如果沒有增量數(shù)據(jù),則直接將宏塊的索引信息加入新的Tablet元信息.
如圖6所示,舊版本的Tablet索引了1—6這6個宏塊,合并過程中,宏塊2有增量數(shù)據(jù),其他的宏塊均沒有變化,宏塊2進(jìn)行合并以后,新生成的數(shù)據(jù)寫入了宏塊7, 新版本的Tablet索引了1,3—7這幾個宏塊,完成了這個Tablet的合并過程.
圖6 分塊SStable每日合并
OceanBase作為一種分布式關(guān)系型數(shù)據(jù)庫,區(qū)別于傳統(tǒng)關(guān)系型數(shù)據(jù)庫,在存儲結(jié)構(gòu)上采用分布式B+tree結(jié)構(gòu).為了實現(xiàn)可擴展和高可用的系統(tǒng)架構(gòu),OceanBase還設(shè)計了多副本冗余、自動容錯以及負(fù)載均衡等方法來保證系統(tǒng)在各種情形下仍能持續(xù)提供高水準(zhǔn)的服務(wù).本文描述了OceanBase的主要存儲結(jié)構(gòu),數(shù)據(jù)格式以及實現(xiàn)每日合并的技術(shù)細(xì)節(jié).
[1] GHEMAWAT S, GOBIOFF H, LEUNG S T. The Google file system[C]//Proc of the 19th ACM SOSP, 2003: 29-43.
[2] CHANG F, DEAN J, GHEMAWAT S, et al. Bigtable: A distributed storage system for structured data[C]//OSDI, 2006.
[3] CORBETT J C, DEAN J, EPSTEIN M, et al. Spanner: Google’s globally-distributed database[C]//OSDI, 2012.
[4] Oracle Database[EB/OL]. http://www.oracle.com/index.html, 2014.
[5] DB2 Database[EB/OL]. http://www-01.ibm.com/software/data/db2/, 2014.
[6] MySQL[EB/OL]. http://www.mysql.com, 2014.
[7] VoltDB[EB/OL]. http://voltdb.com/, 2014.
[8] MemSQL[EB/OL]. http://www.memsql.com/, 2014.
[9] Apache Hbase Region Splitting and Merging[EB/OL]. http://zh.hortonworks.com/blog/apache-hbase-region-splitting-and-merging/.
(責(zé)任編輯 林 磊)
Scalable distributed storage of OceanBase
HUANG Gui, ZHUANG Ming-qiang
(AlibabaGroup,Hangzhou310000,China)
OceanBase is a distributed relational database, its purpose is to store vast amounts of structured data in high-growth, low-cost servers to achieve high availability, high scalability and cost-effective services. OceanBase using memory and external store hybrid storage mode, stores the incremental (update) data in memory, and the baseline (read-only) data in external storage (usually disk), baseline data is divided into slices we called tablet roughly the same amount of data and the use of distributed B+tree stored on many data servers, using the daily merge mechanism to keep the combined incremental data into baseline.This article describes the basic structure and distribution methods of OceanBase baseline data storage, as well as the daily merge mechanism, in addition, we will introduce in OceanBase baseline data storage format of the specific design and implementation.
storage engine; distributed system; daily merge; block stable store; base data; increment data
1000-5641(2014)05-0164-09
2014-06
黃貴,男,阿里巴巴集團技術(shù)專家,研究方向為分布式數(shù)據(jù)庫.E-mail:qushan@alipay.com.
TP31
A
10.3969/j.issn.1000-5641.2014.05.014