淘寶海量資料庫OceanBase系統架構

hongwei2021 發表於 2022-11-24
資料庫


無論是資料量還是訪問量, OceanBase 都不能再是單機系統,即使單機可以服務高達數 TB 的資料,提供數萬 QPS 的服務能力,因此,分散式系統是必然的。但是要實現內部表反彙編 ( 資料庫反彙編 ) 的事務,是一個很大的挑戰,也是一個很艱難的選擇。

一種選擇是目前資料庫常見的橫向拆解,淘寶在這方面做了很多實踐。通常的做法是對主鍵進行雜湊或模運算 ( 實際上是一種特殊的雜湊 ) ,將資料分佈到不同的 DB 伺服器上,客戶端透過路由或規則訪問特定的資料庫,將整個系統的資料和訪問負載分佈到多個伺服器上,從而減輕單機的負載壓力。然而,這種方法有一些缺點:

一是資料和負載增加後的加機操作複雜;

二是很多跨行 / 跨表修改通常涉及多臺機器,難以支援事務;

三是有些範圍查詢需要訪問幾乎所有的機器;

四是單一的 RDBMS 資料量小 ( 比如 MySQL 在很多情況下支援 200GB 左右的資料時效能更好 ) ,可能會消耗大量的機器資源;

至關重要的是,這種方法在很多年前就被幾乎所有的 relationships 海量資料庫廠商採用並積累了豐富的經驗,而 OceanBase 專案組沒有理由做得更好。

還有分散式 B+ ( 類似 BigTable HBase) ,根據主鍵的範圍動態拆分資料庫,即把整個表看成一棵主鍵的 B+ 樹,每個葉節點 ( 200 MB) 對應一個連續的主鍵範圍。由於修改、刪除等,葉節點可能變得太大或太小。以及拆分或合併。容錯、故障恢復和負載均衡都是基於葉節點的 ( 關於 Bigtable 的更多資訊,請參考另一篇部落格:雲端計算的分散式表系統或 BigTable 論文:《 BigTable :結構化資料的分散式儲存系統》 )

這種架構的優點是系統易於擴充套件:只需新增機器,少數突發的機器故障甚至對使用者透明。負載均衡優於以前的方案,範圍查詢容易實現且高效。

但是這種架構最大的難點是事務的實現,因為 BigTable 只有單行事務,而 OceanBase 需要跨行跨表的事務。專案組花了很長時間來解決這個問題 ( 參見 系統架構 (2)”) 。理論分析和程式碼實現表明,該方法簡單高效。

後來有機會看了 Google 關於分散式事務的文章 ( 《使用分散式事務和通知的大規模增量處理》 ) ,感受到了它優秀的設計和複雜性。同時我也發現,雖然使用 15000 CPU 核達到了創紀錄的 11200 tps (TPC-E 基準 ) ,但其平均事務響應時間為 2s-5s ,不符合淘寶平均響應時間幾毫秒到幾十毫秒的需求。此外,開發類似的系統及其底層 BigTable GFS 系統所需的時間、人力、物力和技術挑戰是巨大的。

如上所述,只有分散式架構才能支援目前和未來不斷增長的資料量和訪問量。同時, OceanBase 還必須支援跨行、跨表交易。看來 OceanBase 需要實現分散式事務。

然而,分散式事務不僅實現起來複雜,更重要的是還沒有在業界得到廣泛應用,其效率和效能還需要更多的生產實踐來檢驗。

仔細分析了很多業務,發現海量資料庫 system 的資料量非常巨大,比如幾十億、幾百億甚至更多,但是某一段時間 ( 比如一天 ) 的修改量並不大,通常不超過幾千萬到上億。所以 OceanBase 決定使用單個伺服器 ( 稱為 UpdateServer) 來記錄這段時間 ( 比如一天 ) 內的修改增量,主要是記憶體 memtable 。超出增量並在此期間保持不變的資料稱為基線資料。基線資料以類似於分散式檔案系統的方式儲存在多個伺服器 ( 稱為 ChunkServer) 上, MergerServer 為每個查詢融合 ChunkServer 上的基線資料和 UpdateServer 上的增量資料,並將其返回給呼叫者。這樣,寫事務集中在 UpdateServer ,讀事務分散在多個伺服器上,既實現了跨行、跨表事務,又避免了複雜的分散式寫事務,具有良好的可擴充套件性。

首先, UpdateServer 總是以記憶體表的形式記錄更改。如果記憶體表達到一定的閾值, UpdateServer 將凍結當前記憶體表,同時開啟一個新的記憶體表,後續的更改將被寫入新的記憶體表。凍結的記憶體表不再接受寫入,轉換成緊湊格式儲存到 SSD 磁碟。轉換完成後,凍結記憶體表的記憶體可以回收。

OceanBase 使用主鍵 ( 類似於經典關聯式資料庫的聚集索引 ) 對錶中的資料進行排序和儲存。主鍵由幾列組成,並且是唯一的。在 OceanBase 內,基線資料按主鍵排序,分成資料量大致相等的塊,稱為 tablet 。平板電腦的預設大小為 256MB( 可配置 ) ,儲存在 ChunkServer 上。為了避免 ChunkServer 故障造成的資料丟失,平板通常會保留 2~3 份副本 ( 可配置 )

每隔一段時間 ( 比如一天 ) OceanBase 會將這段時間內的修改增量合併到原來的基線資料中並生成新的基線資料 ( 稱為每日合併 ) ,然後清除 UpdateServer 中過期的修改增量和 ChunkServer 上過期的基線資料。在合併開始時, UpdateServer 將凍結當前的記憶體表,並開啟一個新的記憶體表。之後,新的修改將被寫入新的記憶體表。 ChunkServer 會將當前的基線資料與凍結的記憶體表融合,並生成新的基線資料。當所有新的平板電腦基線資料生成後, UpdateServer 凍結的記憶體表將被釋放,其記憶體將被恢復。為了減少每日合併對使用者訪問 OceanBase 的影響,每日合併被設定為低優先順序任務。當機器負載 ( CPU 負載和 iowait 等。 ) 高於某個閾值,合併速度會變慢甚至暫停。在實際應用中,海量資料庫 DBA 通常將每日合併時間設定在業務的低峰期 ( 比如午夜之後 ) ,這樣每日合併對使用者的影響很小。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70005384/viewspace-2925051/,如需轉載,請註明出處,否則將追究法律責任。

相關文章