OceanBase架構剖析(讀寫事務、單點效能、SSD支援、資料正確性、分層結構)
讀寫事務
在OceanBase系統中,使用者的讀寫請求,即讀寫事務,都發給MergeServer。MergeServer解析這些讀寫事務的內容,例如詞法和語法分析、schcma檢查等。對於只讀事務,由MergeScrver 發給相應的ChunkServer分別執行後再合併每個ChunkServer的執行結果;對於讀寫事務,由MergeServer進行預處理後,傳送給UpdateServer執行。
只讀事務執行流程如下:
1)MergeServer解析SQL語句,詞法分析、語法分析、預處理(schema合法性檢查、許可權檢查、資料型別檢查等),最後生成邏輯執行計劃和物理執行計劃。
2)如果SOL請求只涉及單張表格,MergeServer將請求拆分後同時發給多臺
ChunkServer併發執行,每臺ChunkServer將讀取的部分結果返回MergeServer,由MergeServer來執行結果合併。
3)如果SQL請求涉及多張表格,MergeServer還需要執行聯表、巢狀查詢等操作。
4)MergeServer將最終結果返回給客戶端。
讀寫事務執行流程如下:
1)與只讀事務相同,MergeServer首先解析SQL請求,得到物理執行計劃。
2)MergeServer請求ChunkServer獲取需要讀取的基線資料,並將物理執行計劃和基線資料一起傳給Updateserver。
3)Updatesever根據物理執行計劃執行讀寫事務,執行過程中需要使用MergeServer傳入的基線資料。
4)UpdateServer返回MergeServer操作成功或者失敗,MergeServer接著會把操作結果返回客戶端。
例如,假設某SQL語句為update t1 set c1 = c1 + 1 where rowkey=1
,即將表格t1中主鍵為1的c1列加1,這一行資料儲存在Chunkserver中.c1列的值原來為2012。那麼,MergeServer執行SQL時首先從ChunkServer讀取主鍵為1的資料行的c1列,接著將讀取結果(c1=2012)以及SOL語句的物理執行計劃一起傳送給UpdateServer。UpdateServer根據物理執行計劃將c1加1,即將c1變為2013並記錄到記憶體表(McmTable)中。當然,更新記憶體表之前需要記錄操作日誌。
單點效能
OceanBase架構的優勢在於既支援跨行跨表事務,又支援儲存伺服器線性擴充套件。當然,這個架構也有一個明顯的缺陷:UpdateServer單點,這個問題限制了OceanBase叢集的整體讀寫效能。
下面從記憶體容量、網路、磁碟等幾個方面分析UpdateServer的讀寫效能。其實大部分資料庫每天的修改次數相當有限,只有少數修改比較頻繁的資料庫才有每天幾億次的修改次數。另外,資料庫平均每次修改涉及的資料量很少,很多時候只有幾十個位元組到幾百個位元組。假設資料庫每天更新1億次,平均每次需要消耗100位元組,每天插入1000萬次,平均每次需要消耗1000位元組,那麼,一天的修改量為:1億×100+1000
萬×1000=20GB,如果記憶體資料結構膨脹2倍,佔用記憶體只有40GB。而當前主流的伺服器都可以配置96GB記憶體,一些高檔的伺服器甚至可以配置192GB、384GB乃至更多記憶體。
從上面的分析可以看出,UpdateServer的記憶體容量一般不會成為瓶頸。然而,伺服器的記憶體畢竟有限,實際應用中仍然可能出現修改量超出記憶體的情況。例如,淘寶雙11網購節資料庫修改量暴漲,某些特殊應用每天的修改次數特別多或者每次修改的資料量特別大,DBA資料訂正時一次性寫入大量資料。為此,Updateserver設計實現了幾種方式解決記憶體容量問題,Updancesever的記憶體表達到一定大小時,可自動或者手工凍結並轉儲到SSD中,另外,OceanBase支援通過定期合併或者資料分發的方式將Updateserver的資料分散到叢集中所有的ChunkServer機器中,這樣不僅避免了Updateserver單機資料容量問題,還能夠使得讀取操作往往只需要訪問UpdateServer記憶體中的資料,避免訪問SSD磁碟,提高了讀取效能。
從網路角度看,假設每秒的讀取次數為20萬次,每次需要從UpdateServer中獲取100位元組,那麼,讀取操作佔用的UpdateServer出口頻寬為:20萬×100=20MB,遠遠沒有達到千兆網路卡頻寬上限。另外,UpdateServer還可以配置多塊千兆網路卡或者萬兆網路卡,例如,OceanBase線上叢集一般給UpdateServer配置4塊千兆網路卡。當然,如果軟體層面沒有做好,硬體特性將得不到充分發揮。針對UpdateServer全記憶體、收發的網路包一般比較小的特點,開發團隊對UpdateServer的網路框架做了專門的優化,大大提高了每秒收發網路包的個數,使得網路不會成為瓶頸。
從磁碟的角度看,資料庫事務需要首先將操作日誌寫人磁碟。如果每次寫人都需要將資料刷入磁碟,而一塊SAS磁碟每秒支援的IOPS很難超過300,磁碟將很快成為瓶頸。為了解決這個問題,UpdateServer在硬體上會配置一塊帶有快取模組的RAID卡,UpdateServer寫操作日誌只需要寫入到RAID卡的快取模組即可,延時可以控制在1毫秒之內。RAID卡帶電池,如果UpdateServer發生故障,比如機器突然停電,RAID卡能夠確保將快取中的資料刷入磁碟,不會出現丟資料的情況。另外,UpdateServer 還實現了寫事務的成組提交機制,將多個使用者寫操作湊成一批一次性提交,進一步減少磁碟IO次數。
SSD支援
磁碟隨機10是儲存系統效能的決定因素,傳統的SAS盤能夠提供的IOPS不超過300。關聯式資料庫一般採用快取記憶體(Bufcr Cache)9的方式緩解這個問題,讀取操作將磁碟中的頁面快取到快取記憶體中,並通過LRU或者類似的方式淘汰不經常訪問的頁面:同樣,寫人操作也是將資料寫入到快取記憶體中,由快取記憶體按照一定的策略將記憶體中頁面的內容刷人磁碟。這種方式面臨一些問題,例如,Cache冷啟動問題,即資料庫剛啟動時效能很差,需要將讀取流量逐步切人。另外,這種方式不適合寫入特別多的場景。
最近幾年,SSD磁碟取得了很大的進展,它不僅提供了非常好的隨機讀取效能,功耗也非常低,大有取代傳統機械磁碟之勢。一塊普通的SSD磁碟可以提供35000 IOPS甚至更高,並提供300MB/s或以上的讀出頻寬。然而,SSD盤的隨機寫效能並不理想。這是因為,儘管SSD的讀和寫以頁(page,例如4KB,8KB等)為單位,但SSD寫入前需要首先擦除已有內容,而擦除以塊(block)為單位,一個塊由若干個連續的頁組成,大小通常在512KB~2MB。假如寫人的頁有內容,即使只寫人一個位元組,SSD也需要擦除整個512KB~2MB大小的塊,然後再寫入整個頁的內容,這就是SSD的寫入放大效應。雖然SSD硬體廠商都針對這個問題做了一些優化,但整體上看,隨機寫入不能發揮SSD的優勢。
OceanBase設計之初就認為SSD為大勢所趨,整個系統設計時完全摒棄了隨機寫,除了操作日誌總是順序追加寫入到普通SAS盤上,剩下的寫請求都是對響應時間要求不是很高的批量順序寫,SSD盤可以輕鬆應對,而大量查詢請求的隨機讀,則發揮了SSD良好的隨機讀的特性。摒棄隨機寫,採用批量的順序寫,也使得固態盤的使用壽命
不再成為問題,主流SSD盤使用MLCSSD晶片,而MLC號稱可以擦寫1萬次(SLC可以擦寫10萬次,但因成本高而較少使用),即使按最保守的2500次擦寫次數計算,而且每天全部擦寫一遍,其使用壽命為2500/365=6.8年。
資料正確性
資料丟失或者資料錯誤對於儲存系統來說是一種災難。OceanBase設計為強一致性系統,設計方案上保證不丟資料。然而,TCP協議傳輸、磁碟讀寫都可能出現資料錯誤,程式Bug則更為常見。為了防止各種因素導致的資料損毀,OceanBase採取了以下資料校驗措施:
- 資料儲存校驗。每個儲存記錄(通常是幾KB到幾十KB)同時儲存64位CRC校驗碼,資料被訪問時,重新計算和比對校驗碼。
- 資料傳輸校驗。每個傳輸記錄同時傳輸64位CRC校驗碼,資料被接收後,重新計算和比對校驗碼。
- 資料映象校驗。UpdateServer在機群內有主UpdateServer和備UpdateServer,叢集間有主叢集和備叢集,這些UpdateServer的記憶體表(MemTable)必須保持一致。為此,UpdateServer為MemTable生成一個校驗碼,MemTable每次更新時,校驗碼同步更新並記錄在對應的操作日誌中。備UpdateServer收到操作日誌並重放到MemTable時,也同步更新MemTable校驗碼並與接收到的校驗碼對照。UpdateServer 重新啟動後重放日誌恢復MemTable時也同步更新MemTable校驗碼並與儲存在每條操作日誌中的校驗碼對照。
- 資料副本校驗。定期合併時,新的子表由各個ChunkServer獨立地融合舊的子表中的SSTable與凍結的MemTable而生成,如果發生任何異常或者錯誤(比如程式bug),同一子表的多個副本可能不一致,則這種不一致可能隨著定期合併而逐步累積或擴散且很難被發現,即使被察覺,也可能因為需要追溯較長時間而難以定位到源頭。為了防止這種情況出現,ChunkServer在定期合併生成新的子表時,也同時為每個子表生成一個校驗碼,並隨新子表彙報給RootServer,以便RootServer核對同一子表不同副本的校驗碼。
分層結構
OceanBase對外提供的是與關聯式資料庫一樣的SQL操作介面,而內部卻實現成一個線性可擴充套件的分散式系統。系統從邏輯實現上可以分為兩個層次:分散式儲存引擎層以及資料庫功能層。
OceanBase一期只實現了分散式儲存引擎,這個儲存引擎支援如下特性:
- 支援分散式資料結構,基線資料邏輯上構成一顆分散式B+樹,增量資料為記憶體中的B+樹:
- 支援目前OceanBase的所有分散式特性,包括資料分佈、負載均衡、主備同步、容錯、自動增加/減少伺服器等;
- 支援根據主健更新、插入、刪除、隨機讀取一條記錄,另外,支援根據主鍵範圍順序查詢一段範圍的記錄。
二期的OceanBase版本在分散式儲存引之上增加了SQL支援:
- 支援SQL語言以及MySQL協議,MySQL客戶端可以直接訪問;
- 支援讀寫事務;
- 支援多版本併發控制;
- 支援讀事務併發執行。
從另外一個角度看,OceanBase融合了分散式儲存系統和關聯式資料庫這兩種技術。通過分散式儲存技術將基線資料分佈到多臺ChunkServer,實現資料複製、負載均衡、伺服器故障檢測與自動容錯,等等;UpdateServer相當於一個高效能的記憶體資料庫,底層採用關聯式資料庫技術實現。我們後來發現,有一個號稱“世界上最快的記憶體資料庫”MemSQL採用了和OceanBase UpdateServer類似的設計,在擁有64個CPU核心的伺服器上實現了每秒150萬次單行寫事務。OceanBase相當於GFS+MemSQL,ChunkServer的實現類似GFS,UpdateServer的實現類似MemSQL,目標是成為可擴充套件的、支援每秒百萬級單行事務操作的分散式資料庫。
相關文章
- 微服務架構 - 正確的開始微服務架構
- 看京東架構師如何解決,資料庫讀寫分離與事務糾纏的坑架構資料庫
- 資料倉儲架構分層設計架構
- Redis List 底層三種資料結構原理剖析Redis資料結構
- 三層架構及分層架構
- Mysql之讀寫分離架構-AtlasMySql架構
- ASp.net 剖析三層架構ASP.NET架構
- 正確使用資料架構的五條規則 - infoworld架構
- 分享一個純 Go 編寫的高效能內嵌型 KV 資料庫 NutsDB,支援事務以及多種資料結構Go資料庫資料結構
- 分層架構和SOA架構
- 分層架構在資料倉儲的應用架構
- SpringBoot資料響應、分層解耦、三層架構Spring Boot解耦架構
- 單體架構&微服務架構&中臺服務架構架構微服務
- 資料結構簡單要點總結資料結構
- 【資料結構】線性表-單連結串列資料結構
- 【小白寫論文】技術性論文結構剖析
- 架構分層的小糾結-層級該如何劃分與定位?架構
- 資料結構:用例項分析ArrayList與LinkedList的讀寫效能資料結構
- 一起玩轉微服務(5)——分層架構微服務架構
- Redis - 底層資料結構Redis資料結構
- 分享一個純 Go 編寫的內嵌型 KV 資料庫 NutsDB,支援事務以及多種資料結構Go資料庫資料結構
- 架構離不開資料結構架構資料結構
- Redis原始碼分析-底層資料結構盤點Redis原始碼資料結構
- 常用的幾種大資料架構剖析大資料架構
- redis支援的資料結構Redis資料結構
- 前端架構思想:聚類分層前端架構聚類
- 4+2 分層架構 - Ricardo架構
- 軟體架構分層方法論架構
- “阿里架構師”kafka 資料可靠性深度解讀阿里架構Kafka
- 淘寶海量資料庫OceanBase系統架構資料庫架構
- 連載 4 - 如何看待微服務架構下的分層微服務架構
- .Net微服務實戰之技術架構分層篇微服務架構
- 前端資料結構--線性結構-連結串列前端資料結構
- 【架構與設計】常見微服務分層架構的區別和落地實踐架構微服務
- 大資料架構和模式(三)——理解大資料解決方案的架構層大資料架構模式
- HBase 系統架構及資料結構架構資料結構
- 組織架構新型資料結構思考架構資料結構
- Hbase 系統架構與資料結構架構資料結構