一文详解PolarDB披荆斩棘的“秘密武器”
一、背景
傳統的關系型數據庫有著悠久的歷史,從上世紀60年代開始就已經在航空領域發揮作用。因為其嚴謹的強一致保證以及通用的關系型數據模型接口,獲得了越來越多的應用,大有一統天下的氣勢。
2000年以后,隨著互聯網應用的出現,很多場景下,并不需要傳統關系型數據庫提供的強一致性以及關系型數據模型。相反,由于快速膨脹和變化的業務場景,對可擴展性(Scalability)以及可靠性(Reliable)更加需要,而這個又正是傳統關系型數據庫的弱點。
自然地,新的適合這種業務特點的數據庫出現,就是我們常說的NoSQL。但是由于缺乏強一致性及事務支持,很多業務場景被NoSQL拒之門外。同時,缺乏統一的高級的數據模型,訪問接口,又讓業務代碼承擔了更多的負擔。數據庫的歷史就這樣經歷了否定之否定,又螺旋上升的過程。而這一次,魚和熊掌我們都要。
PolarDB就是在這種背景下出現的,由阿里巴巴自主研發的下一代關系型分布式云原生數據庫。在兼容傳統數據庫生態的同時,突破了傳統單機硬件的限制,為用戶提供大容量,高性能,極致彈性的數據庫服務。
二、核心技術之共享存儲
PolarDB采用了Share Storage的整體架構。采用RDMA高速網絡互連的眾多Chunk Server一起向上層計算節點提供塊設備服務。一個集群可以支持一個Primary和多個Secondary節點,分別以讀寫和只讀的掛載模式通過RDMA掛載在Chunk Server上。PolarDB的計算節點通過libpfs掛載在PolarStores上,數據按照Chunk為單位拆分,再通過本機的PolarSwritch分發到對應的ChunkServer。每個ChunkServer維護一組Chunk副本,并通過ParallelRaft保證副本間的一致性。PolarCtl則負責維護和更新整個集群的元信息。
- Bypass Kernel
PolarDB誕生于2015年,由于RDMA高速網絡的出現,使得網絡帶寬接近于總線帶寬。PoalrDB作出大膽的假設,那就是未來數據庫的瓶頸將由網絡轉向軟件棧自己。因此PolarStore中采用了大量的Bypass Kernel的設計。首先是新硬件的使用,NVME和RDMA的使用,擺脫了IO訪問過程中的用戶態內核態交互。
軟件設計中,在綁定CPU,非阻塞IO的模式下, 通過狀態機代替操作系統的線程調度,達到Bypass Kernel的目的。
- ParallelRaft
PolarStore中采用三副本的方式來保證數據的高可用,需要保證副本間的一致性。工業界有成熟的Raft協議及實現,但Raft由于對可理解的追求,要求順序確認以及順序提交。而副本的確認提交速度會直接影響整個PolarStore的性能。為了獲得更好的訪問速度,PolarStore提出了ParallelRaft協議,在Raft協議的框架下,利用塊設備訪問模式中方便判定訪問沖突的特點,允許一定程度的亂序確認和亂序提交,如下圖所示:在所有已經確認提案中,那些對前序訪問有訪問Range沖突的提案會被暫時Block,而沒有沖突的提案會進入Ready狀態并commit,commit以后的提案會繼續反饋給當前的Scheduler,之前被Block的提案有可能會進入Ready狀態,進而繼續被提交。
三、核心技術之物理復制
采用了共享存儲的模式之后,Secondary上依然需要從Primary來的復制邏輯來刷新內存結構,如果Buffer Pool以及各種Cache。但是,由于讀寫節點和只讀節點訪問的是同一份數據,傳統的基于binlog的邏輯復制方式不再可用,這時由于邏輯復制由于最終執行順序的變化,導致主從之間不同的物理數據結構。因此DB層基于Redo Log的物理復制的支持是必不可少的:
不同于邏輯復制自上而下的復制方式,物理復制的復制方式是自下而上的,從共享存儲中讀取并重放REDO,重放過程會直接修改Buffer Pool中的Page,同步B+Tree及事務信息,更新Secondary上的各種內存Cache。除了支持共享存儲外,物理復制還可以減少一份日志寫。同時,由于整個復制過程不需要等到事務提交才能開始,顯著地減少了復制延遲:
四、交易場景優化
針對雙十一峰值交易場景,PolarDB也做了大量優化。
- Blink Tree
在峰值交易場景中,會有大量涉及熱點page的更新及訪問,會導致大量關于這些熱點Page的SMO操作,
之前PolarDB在SMO場景下由于B+Tree實現有如下的加鎖限制:
- 同一時刻整個B+Tree 有且只能有一個SMO在進行;
- 正在做SMO的B+Tree分支上的讀取操作會被阻塞直到整個smo完成。
針對這個問題PolarDB做了如下優化:
- 通過優化加鎖,支持同一時刻有多個SMO同時進行,這樣原本等待在其他分支做SMO的插入操作就無需等待,從而提高寫入性能;
- 引入Blink Tree來替換B+Tree并通過縮小SMO的加鎖粒度,將原本需要將所有涉及SMO的各層Page加鎖直到整個SMO完成后才釋放的邏輯,優化成Ladder Latch,即逐層加鎖,修改完一層即可放鎖然后去加上一層Page鎖繼續修改。這樣原本被SMO阻塞的讀操作會有機會在SMO中間進來:通過對每個節點增加一個后繼鏈接的方式,使得在Page Split的中間狀態也可以完成對Page安全的訪問,如下圖所示,傳統的B+ Tree必須通過一把鎖來Block整個Page Split過程中對所影響的Page的訪問。而Blink Tree則不需要,即使Split還在進行中,父節點到子節點的鏈接還沒有完成建立,依然可以通過前一個節點的后繼鏈接找到正確的子節點。并且通過特殊處理確保訪問到正確的Page,從而提高讀取性能。
通過這些對B+ Tree的優化,可以實現交易場景PolarDB讀寫性能提升20%。
- Simulated AIO
InnoDB中有simulated AIO的邏輯,用于支持運行在不包含AIO的系統下,PolarDB下的共享存儲文件系統就是沒有AIO的,所以采用的是simulated AIO的邏輯。
但是原版中的simulated AIO是基于本地存儲設計的,與分布式存儲的特性并不適配。為了進行IO合并,原版的simulated IO設計,將所有異步IO請求按照目標地址進行組織,存放在同一個IO數組中,方便將目標地址連續的小IO合并成大IO來操作,以提升IO的吞吐。
但是這個設計與分布式存儲是不相適配的,連續的大IO操作,會使得同一時刻,只有一個或少量存儲節點處在服務狀態,浪費了其他存儲節點的作用;另外,分布式存儲的網絡延遲較大,高負載下,網絡中的Inflight IO會較多,IO組中的IO請求數量也會很多,而這種組織方式下,IO數組中的槽位狀態都無序的,往數組中添加IO請求和移除IO請求的開銷都很大。
所以,PolarDB在高負載下的性能比較差且不穩定,為此PolarDB專門對simulated AIO進行了重新的設計,主要包括:
a.合理地選擇IO合并和拆解,充分利分布式存儲的多節點優勢;
b.建立狀態有序的IO服務隊列,減少高負載下的IO服務開銷。
重新設計下,性能提升了很多
穩定性也有了很大的提升
- Partitioned Lock System
PolarDB采用的是2PL + MVCC的并發控制方式。也就是用多版本數據構建Snapshot來服務讀請求,從而避免讀寫之間的訪問沖突。而讀寫之間的沖突需要通過兩階段鎖來保證,包括表鎖,記錄鎖,謂詞鎖等。每當需要加鎖的時候,之前的做法都需要去log_sys中先獲得一把全局的mutex保護。在峰值的交易場景中,大量的寫入會導致這個地方的mutex成為瓶頸。因此PolarDB采取了Partition Lock System的方式,將log_sys改造成由多個LockSysShard組成,每個Shard中都有自己局部的mutex,從而將這個瓶頸打散。尤其是在這種大壓力的寫入場景下明顯的提升寫入性能。
- Lockless Transaction System
PolarDB中支持Snapshot Isolation的隔離級別,通過保留使用的Undo版本信息來支持對不同版本的記錄的訪問,即MVCC。而實現MVCC需要事務系統有能力跟蹤當前Active及已經Commit的事務信息。在之前的實現中每當有寫事務開始時,需要分配一個事務ID,并將這個ID添加到Transaction System中的一個活躍事務列表中。當有讀請求需要訪問數據時,會首先分配一個ReadView,其中包括當前已分配最大的事務ID,以及當前這個活躍事務列表的一個備份。每當讀請求訪問數據時,會通過從Index開始的Roll ptr訪問到這個記錄所有的歷史版本,通過對比某個歷史版本的事務ID和自己ReadView中的活躍事務列表,可以判斷是不是需要的版本。
然而,這就導致每當有讀事務開始時,都需要在整個拷貝過程對這個活躍事務列表加鎖,從而阻塞了新的寫事務將自己的ID加入。同樣寫事務和寫事務之間也有訪問活躍事務列表的沖突。從而活躍事務列表在這里變成一個明顯的性能瓶頸,在雙十一這種大壓力的讀寫場景下尤為明顯。
對此,我們將Tansaction System中的這個活躍事務列表改造成無鎖Hash實現,寫事務添加ID以及讀事務拷貝到ReadView都可以并發進行。大大提升了性能。
原文鏈接:https://developer.aliyun.com/article/790024?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的一文详解PolarDB披荆斩棘的“秘密武器”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何攻破容器持久化存储挑战?
- 下一篇: 阿里云数据库快速搭建疫情分析系统最佳实践