深度 | 帶領國產數據庫走向世界,POLARDB底層邏輯是什么?
POLARDB 是阿里云自主研發的下一代云原生分布式數據庫,100%兼容
MySQL、PostgreSQL等開源數據庫,高度兼容Oracle語法,使用RDS服務的客戶不需要修改應用代碼,可以一鍵遷移到POLARDB,體驗更大的容量,更高的性能,更低的成本,和更靈活的彈性。
目前,POLARDB是阿里云增速最快的數據庫產品,廣泛應用于互聯網金融、政府便民工程、新零售、教育、游戲、社交直播等行業。
作為基于計算與存儲分離架構的新一代云原生數據庫,POLARDB的計算節點里主要實現了 SQL 解析和優化、以及查詢并行執行與無鎖高性能事務處理,計算節點之間通過高吞吐的物理復制協議同步內存狀態。
而存儲層基于分布式文件系統PolarFS,通過Parallel Raft共識算法實現多數據副本間的強一致性,在存儲層進行存儲引擎的多版本頁管理來支持全集群跨計算節點的Snapshot Isolation隔離級別。
01基于計算與存儲分離的先進架構
計算節點與存儲節點之間通過理解數據庫語義的智能互聯協議將filter和projection等算子從計算層下推到存儲層執行。為了保證事務和查詢語句的低延遲,同時降低計算節點之間狀態同步的延遲,計算節點和存儲節點之間使用25Gb高速RDMA網絡互聯,采用Bypass kernel的用戶態網絡協議層進行通訊。
基于計算與存儲分離的先進架構,POLARDB可以從1個計算節點(2個CPU核)彈性伸縮到16個計算節點(最高達到1000核)的事務擴展能力,單實例存儲容量從10GB按使用量彈性擴展到100TB。
計算節點與存儲節點分離的架構設計給POLARDB帶來了實時的水平擴展能力。由于單個數據庫實例的計算能力有限,傳統的做法是通過搭建多個數據庫副本來分擔壓力,從而提供數據庫Scale out 的擴展能力。
然而,這種做法需要存儲多份全量數據,并且頻繁同步日志數據造成了過高的網絡開銷。此外,在傳統數據庫集群上,增加副本需要同步所有增量數據,這帶來了同步延遲上漲的問題。
POLARDB將數據庫文件以及Redo log 等日志文件存放在共享存儲設備上,確保主實例和所有副本共享同一份全量數據和增量日志數據。節點間只需要同步內存里的元數據信息,通過MVCC機制的保證,就能支持跨節點讀取數據的一致性,非常巧妙地解決了主實例和副本之間的數據同步問題,大大節約了跨節點的網絡開銷,降低副本間的同步延遲。
02提升事務性能 POLARDB內核層面優化揭秘
為了提高事務性能,POLARDB 在內核層面進行了大量優化。把一系列性能瓶頸用無鎖(lockless)算法以及各種并行優化算法進行改造,減少甚至消除各種鎖之間的相互沖突,大大增加了系統的scalability 能力。
同時,我們依托處理雙十一這種大規模高并發場景下的經驗, 在 POLARDB 上實現了對庫存等熱點數據進行優化的功能。對于簡單重復的查詢,POLARDB支持直接從存儲引擎獲取結果,從而減少了優化器及執行器的開銷。
此外,進一步優化已經高效的物理復制。比如,我們在重做日志加了一些元數據,以減少日志解析CPU開銷. 這個簡單優化減少了60%日志解析時間。我們也重用 一些數據結構,以減少內存分配器的開銷。
POLARDB運用了一系列算法來優化日志應用,比如只有在buffer pool中的數據頁面 才需要日志應用。同時我們也優化了page cleaner and double write buffer,大大減少這些工作的成本. 這一系列優化使得在性能上 POLARDB 遠超 MySQL ,在sysbencholtp_insert等大量并發寫入的基準評測中達到最高6倍于MySQL 的性能。
03支持并行查詢(Parallel Query)
為了提高子查詢和join等復雜查詢(例如TPC-H基準評測)的能力,POLARDB的查詢處理器支持并行查詢(parallel query),可以將一個查詢同時在多個或所有可用CPU核上進行執行。并行查詢能夠將一個查詢任務(當前只支持SELECT語句)劃分為多個子任務,多個子任務可以并行進行處理,整體采用Leader-Worker的并發模型。
Leader線程負責生成并行查詢計劃,協調并行執行過程的其他組件,并行執行計劃會包括并行掃描、多表并行連接、并行排序、并行分組、并行聚集等子動作。
Message queue是leader線程和worker線程的通訊層,worker線程通過message queue向leader線程發送數據,而leader線程也會通過message queue向worker線程發送控制信息。
Worker線程負責真正的執行任務。Leader線程解析查詢語句生成并行計劃,然后同時啟動多個worker線程進行并行任務處理,為了高效的執行查詢,Worker上的執行不需要進行再次優化,而是直接從Leader上來拷貝生成好的計劃分片。這需要實現執行計劃樹上所有節點的拷貝。
worker線程在進行掃描,聚集,排序等操作后將中間結果集返回給leader,leader負責收集來自worker的所有數據集,然后進行適當的二次處理(比如merge sort,二次group by 等操作),最后將最終結果返回給客戶端。
Parallel Scan層會結合存儲引擎的數據結構特征來實現工作負載的均衡。如何將掃描數據劃分成多個分區,使得所有的工作線程盡可能的均勻的工作是數據分區劃分的目標。在以B+樹作為存儲結構的存儲引擎里,劃分分區的時候,是先從根上來劃分,如果根上不能劃分出足夠多的分區(>= 并行度),將會繼續從下一層進行劃分。
而如果我們需要6個分區的話,根節點最多分出4個分區,所以就需要繼續搜索下一層來進行分區,以此類推。在實際實現并行查詢的過程中,為了能讓多個工作線程更加均勻的分配掃描段,會在B+樹里盡可能的多劃分分區,這樣如果某個工作線程由于過濾性比較高會優先完成當前分區,那么它會自動attach下一個分區繼續執行,通過自動attach的方式來實現所有線程的
負載均衡。
04新一代基于代價的優化器
云上客戶的業務是多樣化的,如果執行計劃選錯會導致慢查詢。為了系統性地解決這些問題,POLARDB推出了新一代的基于代價的優化器。POLARDB里實現新的直方圖Compressed Histogram對高頻率數據進行自動探測并構建精確描述,在選擇率計算時考慮數據頻率和取值空間,解決實際應用中普遍存在的數據傾斜場景。
POLARDB大量基于改良的直方圖進行代價估算,比如估算表和表join的結果大小,是join代價和join order優化的決定性因素,MySQL只能根據經驗公式粗略的估算,無論是有索引時的rows_per_key,還是無索引時的默認參數值,估算的誤差都較大,這些誤差會在多表連接的過程中不斷放大,導致生成效率低下的執行計劃。
在POLARDB中使用直方圖對重合部分進行合并計算,并根據不同的直方圖類型適配不同的estimation算法,大大提高了估算精度,幫助優化器做出更優的join order選擇。在隨機生成的正態分布數據測試中,多表聯合查詢優化后可提速2.4-12倍,TPC-H測試中多個查詢的join order發生變化,性能提升77%-332%。
POLARDB也使用直方圖優化了record_in_range的邏輯,MySQL對于有索引的過濾條件采用index dive來估算區間的記錄數,這個操作在OLTP短查詢中CPU占比較高。在使用基于直方圖估算替換index dive后,在淘寶電商核心業務中,絕大多數的查詢查詢響應時間減少一半。
05、自研分布式文件系統PolarFS:高可靠、高可用、與數據庫協同設計
POLARDB的存儲層采用的是阿里云自主研制的分布式文件系統PolarFS。PolarFS是國內首款面向DB應用設計的采用了全用戶空間I/O棧的低延遲高性能分布式存儲系統(參見VLDB 2018 上的文章 PolarFS: An Ultra-low Latency and Failure Resilient Distributed FileSystem for Shared Storage Cloud Database),其具備與本地SSD硬盤架構相當的低延遲高性能I/O能力,同時也以分布式集群的方式提供了優異的存儲容量與存儲性能的擴展能力。
而PolarFS作為一款與POLARDB深度協同的存儲基礎設施,其最核心的競爭力不僅體現在性能和擴展性方面,更深層次的則是在面臨有許多挑戰性的POLARDB客戶業務需求和規模化的公有云研發運維過程中而長期積累形成的一系列高可靠、高可用、與數據庫協同設計的存儲技術。
為了支持POLARDB在多個計算節點之間分發查詢且保持全局的Snapshot Isolation語義,PolarFS支持存儲POLARDB存儲引擎B+樹動態生成的多版本(Multi-version page)。
為了減少讀寫沖突,現代數據庫一般都通過以MVCC并發控制為框架來提供RC、SI、SSI等不同的事務隔離級別,在MVCC機制下,B+樹的每個頁面會動態維護一系列的版本,并發執行中的多個事務允許各自訪問一個頁面的不同版本。
在POLARDB集群里,由于跨節點復制同步延遲的存在,每個計算節點B+樹的頁面可能是不同版本的,這時多版本存儲可以為各節點提供其所對應版本。在POLARDB中,計算節點向PolarFS寫入一個頁面的同時要提供該數據頁的版本信息(LSN),PolarFS不僅存儲數據頁的同時還要存儲數據版本元信息;計算節點讀取數據頁時,也會提供版本信息從存儲獲取相應的數據頁(歷史)版本。
POLARDB數據庫層定期會將集群所有計算節點版本號的低水位線發送給PolarFS,PolarFS會基于此版本號清理不再使用的歷史版本。
保證數據可靠性是POLARDB所有設計的底線。在實際的分布式系統中,硬盤、網絡與內存等硬件、固件或軟件的bug等問題可能會造成數據錯誤,從而給數據可靠性保障帶來各種挑戰。存儲端的可靠性問題來自靜默錯誤(lost write、misdirected write,block corruption等),網絡和內存主要來自于比特反轉和軟件bug。
為了確保各種異常情況(包括:硬件故障,軟件故障,人工操作故障)發生時的數據可靠性,POLARDB和PolarFS提供了端到端全鏈路數據校驗保障。
在數據寫入時,POLARDB 從計算節點的存儲引擎開始,一直到PolarFS存儲節點的數據落盤,經過的中間鏈路,都會對數據的正確性做校驗,防止異常數據寫入。
在數據讀取時,PolarFS和POLARDB存儲引擎都會對讀取到的數據做checksum校驗,準確地識別磁盤靜默錯誤的發生,防止靜默錯誤擴散。
在業務流量低峰時,還會在后臺持續性的做數據一致性掃描,用于檢查單副本數據的checksum是否正確以及各個副本間的數據是否一致。數據遷移過程中的正確校驗性也非常重要:POLARDB在執行任何形式的數據遷移動作時,除了副本自身數據的 checksum 校驗,還會對多個副本數據的一致性做校驗;當這兩個校驗都通過,才會將數據遷移到目標端;最大限度的防止由于遷移動作,導致單副本上的數據錯誤擴散,避免數據損壞問題。
PolarFS還支持對POLARDB做快速的物理快照備份與還原。快照是一種流行的基于存儲系統的備份方案。其本質是采用Redirect-On-Write 的機制,通過記錄塊設備的元數據變化,對于發生寫操作的存儲卷進行寫時復制,將寫操作內容改動到新復制出的存儲卷上,來實現恢復到快照時間點的數據的目的。
快照是一個典型的基于時間以及寫負載模型的后置處理機制。也就是說創建快照時,并沒有備份數據,而是把備份數據的負載均分到創建 快照之后的實際數據寫發生的時間窗口,以此實現備份、恢復的快速響應。
POLARDB通過底層存儲系統的快照機制以及Redo log增量備份,在按時間點恢復用戶數據的功能上,比傳統的全量數據結合邏輯日志增量數據的恢復方式更加高效。
06高度兼容Oracle語法 成本是商業數據庫的1/10
除了100%兼容MySQL和PostgreSQL這兩個最流行的開源數據庫生態, POLARDB還高度兼容Oracle語法,為傳統企業上云提供成本是商業數據庫1/10的方案。
通過用DMS替換Oracle的GUI管理工具OEM,以及用POLARDBPlus替換命令行工具SQL Plus,沿襲了OracleDBA的使用習慣;客戶端SDK可以從OCI和O-JDBC Driver替換成libpq和JDBC Driver,只需要做so和jar包的替換,程序主體代碼不需要修改;
對Oracle的SQL普通DML語法都能支持,對幾乎所有高級語法如connect by、pivot、listagg等也都全面支持;對PL/SQL存儲過程、以及存儲過程用到的內置函數庫也能做到全面覆蓋支持;
對一些高級功能(如安全管理、AWR等)提供完全相同的格式布局和操作語法,所以綜合看來,POLARDB對Oracle的操作方法、使用習慣、生態工具、SQL語法、格式布局等都做到了全面的兼容和替換,結合遷移評估工具ADAM,應用可以做到少量改動甚至無改動。
07提前看:更多新技術和企業級特性即將上線
除了上面介紹的技術,POLARDB還有大量新技術和企業級特性在2019下半年陸續發布,這些技術會全面提升POLARDB的可用性、性能,降低POLARDB的使用成本:
1)從彈性存儲到彈性內存,熱緩沖池(warm buffer pool)技術
POLARDB即將支持和計算節點進程解構的“熱”緩沖池,這將大大減少用戶業務在計算節點重啟時受到的影響。在進行機型替換規格升降級的時候(serverless),對業務的影響更小。同時,一個獨立的內存也使得其動態按需擴展或收縮成為可能。
2) 性能數倍增長,更好的DDL支持(FAST DDL)
POLARDB即將支持并行DDL,這將大大縮短表級別的DDL延遲。這個功能把并行化做到極致,可以把建索引等DDL的時間減少近10倍。同時,POLARDB還進行了大量的DDL復制層面的優化,這使得DDL可以進行跨區域的大批量復制,速度更加迅速,資源的消耗更少。
3) 支持跨地域的全球數據庫(Global Database)
POLARDB 支持跨地域、長距離的物理復制,幫助用戶建立其全球數據庫的部署。通過物理復制,數據可以實時復制到全球各個機房,使得全球用戶的查詢在當地機房就得到響應,反應更迅速。
4)分區表的支持
POLARDB支持100T的存儲容量。但是隨著表的大小的增長,單表索引的層次也增加,導致數據的查找定位也變得更慢,一些單表上的物理鎖也導致并行DML碰到天花板。
所以進行合理的分區變得更加緊迫。之前不少用戶依賴數據庫外部中間件的分庫分表的來減少單表的壓力。
但是,隨著POLARDB在各方面比如并行查詢的發展,我們可以把這些分庫分表的功能通過分區表的形式在數據庫內更有效的實現。
有效的分區不但使我們能夠支持更大的表,而且它減少了一些數據庫索引的全局物理鎖的沖突,從而提高整體DML的性能。
同時,這種形態之后可以更好的支持冷熱數據分離,把不同“溫度“的數據存放在不同的存儲介質中,在保證數據access的性能的同時,減少數據存放的成本。
POLARDB在增強分區表的一系列功能,包括全局索引(Global Index),分區表的外鍵(Foreign Key Constraint),自增分區表(Interval Partition)等,使得POLARDB更好的應對特大表
5) 行級壓縮
POLARDB即將推出行級壓縮功能。業界通常的做法是在數據頁級別通過通用壓縮算法(比如LZ77、Snappy)進行壓縮,但頁級壓縮會帶來CPU開銷過大的問題,因為改動一行數據,也要把整個數據頁解壓,改動,再壓縮。
此外,有些場景下數據頁壓縮后反而變大(bloat),還會導致多重索引頁分裂 (multiple splits)。POLARDB采用細粒度(fine-grain)行級壓縮技術,對不同的數據類型采用特定的壓縮方式。
數據以壓縮的方式同時存在于外存及內存中,只有在要查詢的時候才進行行級數據的解壓,而不用解壓整個數據頁。由于數據除查詢外都是以壓縮方式存儲,所以日志也記錄了壓縮的數據,這個進一步減少了日志的大小,以及在網絡傳輸的數據/日志的壓力。同時其相對應的索引也只存儲壓縮的數據。
整體數據量的減少足以抵消解壓所引起的額外開銷,使得這種壓縮在大大減少數據存儲的同時并不會引起性能衰退。
6)In-Memory的列存(HTAP)
在傳統的數據庫領域,分析數據庫和在線事務處理是分隔開來的。因此通常需要在一天的經營結束后將在線事務處理的數據與往期分析處理的數據一起導入至數據倉庫后運行分析,以生成相應的報表。
在HTAP數據庫中,則省去了大規模數據搬移的時間與運營成本,一站式解決大部分企業級應用的需求,并在交易結束當天同步出具T+0的分析報告。
在這種需求下,POLARDB在實現in-memory的列存數據表。通過物理邏輯日志直接和POLARDB行存數據同步。這樣通過特定適合分析的算子可以對這些列存數據進行實時的大數據分析。使得用戶可以一站式的得到分析結果。
7)冷熱分離存儲引擎X-Engine
存儲數據的規模越來越龐大,但不是所有的數據訪問頻率都相同,實際上數據訪問總是呈現比較明顯的冷熱分布特征,基于這一特征,X-Engine設計了冷熱分層的存儲架構,根據數據訪問頻度(冷熱)的不同將數據劃分為多個層次,針對每個層次數據的訪問特點,設計對應的存儲結構,寫入合適的存儲設備。
不同于傳統的B+樹技術,X-Engine使用了LSM-Tree作為分層存儲的架構基礎,使用多事務處理隊列和流水線處理技術,減少線程上下文切換代價,并計算每個階段任務量配比,使整個流水線充分流轉,極大提升事務處理性能。數據復用技術減少數據合并代價,并且因為數據復用減少緩存淘汰帶來的性能抖動。進一步利用FPGA硬件加速compaction過程,使得系統上限進一步提升。
相對于其他類似架構的存儲引擎比如RocksDB,X-Engine的事務處理性能有10倍以上提升。
X-Engine的詳細技術參考SIGMOD 2019的論文X-Engine: An Optimized StorageEngine for Large-scale E-Commerce Transaction Processing。
目前,POLARDB不僅支撐阿里巴巴集團淘寶、天貓、菜鳥等業務場景,還廣泛應用于政務、零售、金融、電信、制造等領域,目前已經有40萬個數據庫遷上阿里云。
基于POLARDB分布式數據庫,北京的公交系統快捷、流暢地安排著全市2萬多輛公交車,方便每天800萬人次出行;
眾安保險使用該數據庫處理保單數據,效率提升25%。