新硬體環境下日誌模組的設計與演進
本文根據朱閱岸老師於第九屆中國資料庫技術大會(DTCC 2018)的現場演講《新硬體環境下日誌模組的設計與演進》內容整理而成。
講師介紹:
朱閱岸,中國人民大學博士,現供職於YY Research LAB。研究方向主要為資料庫系統理論與實現、新硬體平臺下的資料庫系統以及TP+AP型混合系統。
分享提綱:
1、現代處理器及新型儲存的發展
2、傳統的資料庫系統日誌模組設計
3、面向新型硬體的日誌子系統設計
4、總結
演講內容:
大家好,我今天帶來的主題是“新硬體環境下日誌模組的設計與演進”。該topic對近些年來工業界與學術界在日誌子系統的最佳化進行總結,尤其是新硬體環境下的工作。分享由四部分組成,首先介紹一下新硬體和資訊儲存的一些發展,題目中的新硬體主要是指現代處理器和新型儲存這兩種。我會簡要回顧一下資料庫系統經典日誌模組設計的原理和不足,然後是面向新硬體的一些日誌子系統設計的方法,最後是總結。
一、現代處理器及新型儲存的發展
我們首先簡要回顧一下處理器的發展趨勢。由於能耗與製造工藝的原因使得處理器製造商不再追求高頻率,而是轉向片上多處理器技術,也就是多核技術。現在伺服器配備幾十個CPU處理已經很常見了,一些廠商甚至推出了成百上千個處理核心的處理器,“眾核”的概念開始流行起來。
另一方面大家可能沒有注意到,非易失性記憶體開始從實驗室走向工業界,例如Intel傲騰,這類儲存具有磁碟的持久儲存特性與接近記憶體的訪問速度,可以實現位元組定址,也就是使用CPU的load與store指令直接定址。總體來說,它的主要特性是非易失、低延遲、高密度和讀寫不對稱。可以看到,非易失性記憶體的儲存容量比較大,可以達到記憶體的2到4倍左右,但是也有讀寫不對稱的一些問題。
目前實現非易失性記憶體的主流技術有四種:這裡簡要介紹一下非易失性記憶體的實現原理,可以分為四類。第一類是採用相變儲存。相變儲存器主要由相變材料、加熱體、存取裝置組成。透過加熱體對相變材料進行加熱材料會出現結晶與非結晶兩種狀態,呈現低電阻與高電阻,這對應與1和0;第二類是使用自旋磁力矩。自旋磁力矩的一個單元由固定層,自由層以及隔離層組成。對磁性材料施加電流會改變自由層的磁性方向從而使得儲存單元具有低電阻與高電阻的二元狀態;第三類是使用鐵電材料:鐵電晶體在電場的作用下會使得中心原子出現高極化電荷與低極化電荷。這種鐵電材料的二元穩定狀態使得它可以作為儲存介質;最後是採用憶阻器技術。簡單說,憶阻器是一種有記憶功能的非線性電阻。它可以記憶流經它的電荷數量,控制電流的變化可改變其阻值。如果把高阻值定義為“1”,低阻值定義為“0”,則這種電阻就可以實現儲存資料的功能。非易失性記憶體是憶阻器的最簡單應用。它的最大用途還是構造類大腦的硬體,為AI實現質的突破。
我們來看一下非易失性記憶體、快閃記憶體以及記憶體之間的對比引數。由於PCM(Phase Change Memory)最具市場前景,我們將基於相變儲存的非易失性記憶體與flash與DRAM進行比較。
相比flash,PCM可以實現位元組定址,在讀寫速度上快2-3個數量級左右,同時讀寫壽命與能耗也有大幅改進。相比DRAM,PCM的讀寫延遲與頻寬稍微遜色,但是在閒時能耗以及密度令人眼前一亮。在閒時能耗方面,PCM是DRAM的1/100。這主要是DRAM需要不斷重新整理電容來保持儲存單元的內容,而PCM並不需要這樣子的操作。能耗是資料中心最關心的一個問題,非易失性記憶體在大型資料中心的具有非常大的優勢。
回到軟體設計,其實在我們的觀念裡在非易失性記憶體出現之前,記憶體與外設存在著巨大的效能差距。為了彌補這個差距,軟體系統都會加上一層buffer,減少與外設打交道的頻率。資料庫系統有資料buffer和日誌buffer,一般使用的steal與no force策略。也就是說,事務提交時刻無需刷髒頁,直接將日誌寫出即可。這個模式是針對磁碟時代而設計的,在某些工作負載下,日誌模組容易成為系統瓶頸。
09年的時候,CMU的研究人員對幾款流行的開源資料庫系統進行了詳盡的研究,驗證了上述的觀點,這幾款開源的資料庫系統都不能很好地利用底層硬體設施。隨著併發執行緒的增加,上述系統效能都遭受了不同程度的下降。尤其是,事務真正花費在實際工作上的時間只佔12%左右。緩衝區管理/鎖管理器/日誌模組耗費了大部分的事務執行用時。其主要原因是關聯式資料庫系統的研發。時至今日,MYSQL的日誌管理/鎖管理以及Pg的緩衝區管理與日誌管理都是一個大問題。他們的研究論文具有里程碑的意義,拉開了開源系統在多核處理器時代最佳化的序幕。
總體來看,現在硬體發展就是CPU向多核、眾核發展,非易失性記憶體開始從實驗室走向工業界。非易失性記憶體的出現彌補了DRAM和永續性儲存裝置效能差距的鴻溝。有了非易失性記憶體以後,系統開發人員可以認為記憶體與外設之間的一個效能差距問題不復存在。在新硬體環境下,上層軟體必須去適配底層硬體的發展,才能獲得硬體上的紅利。
二、傳統的資料庫系統日誌模組設計
接下來我們簡要回顧一下日誌模組的設計和不足。其實現在來看,InnoDB的效能瓶頸目前主要集中在鎖管理器與日誌模組,PostgreSQL的效能瓶頸體現在緩衝區管理模組與日誌模組。日誌模組有一個通病,資料庫通常採用集中的WAL方法實現,經常會引發熱點問題。
傳統的日誌提交主要有三個步驟,首先要獲取寫日誌緩衝區上的排他鎖,然後遞增LSN, 代理執行緒將事務日誌記錄複製到日誌緩衝區相應位置,最後釋放緩衝區上的鎖。當然在兩三年前(至少開源資料庫系統)資料庫系統都是這麼幹的,現在大家都已經發現這個問題了。
我們先看看MySQL 8.0版本之前,InnoDB是怎麼提交日誌的。當提交一個mini transaction時,需要將記錄資料的更改日誌提交到公共buffer中,並將對應的髒頁加到flush list上。入口函式為mtr_t::commit,執行過程如下:
1. mtr_t::Command::prepare_write 獲取log_sys->mutex
2. mtr_t::Command::finish_write 將日誌從mtr中複製到公共log buffer。這裡需要考慮block空間不足的情況(持有log_sys->mutex)
3. 若本次事務產生髒頁,申請flush list mutex隨後釋放log_sys->mutex。
這三個步驟完全遵循上述的日誌提交方法。
PostgreSQL也有相同的問題,9.4版本之前日誌提交的臨界區設計的相當粗糙,事務執行的關鍵路徑的程式碼長度大概有300行左右。
基於這一點我們可以猜測很多資料庫系統,特別是開源系統,在臨界區上的設計上是比較隨意的,面臨一些擴充套件性的問題。從當前的研究實踐看來,MySQL、PostgreSQL等效能瓶頸主要還是聚焦在日誌模組。因此在當前硬體環境下,重構日誌模組是具有很重要的意義的。
三、面向新型硬體的日誌子系統設計
這部分我們來看一下面向新型硬體的日誌子系統設計。主要分成三個部分,一部分是針對大併發場景最佳化日誌子系統,通常做法是縮短臨界區。第二種面向NVM最佳化日誌子系統,但還是在現有的框架下去最佳化這個系統。第三部分是比較激進的,或許也是趨勢,從頭開始構建一個日誌子系統,顛覆以前的認知。
1、大併發場景最佳化之一:預留空間
第一種最佳化方法叫做預留空間。下面是事務日誌提交步驟:(1)事務只需在臨界區內簡單計算日誌記錄所佔長度,然後即可釋放鎖。事務之間可以並行複製日誌。(2)追蹤日誌記錄填充情況。事務提交時刻需要確保之前的事務已經完成日誌複製。
針對多核處理器,大併發場景下的最佳化方法主要是縮短臨界區。如圖a所示,之前通常的做法是在臨界區內複製日誌。這將日誌記錄大小的引入事務執行的關鍵路徑,其實只需要簡單地預留空間以後即可釋放鎖。預留空間就是計算事務日誌應該在緩衝區中的佔據的位置。事務之間的日誌複製可以同時進行,如圖(b)所示。
但是這個做法有個有個挑戰,就是怎麼樣去追蹤日誌空洞,因為事務複製日誌是併發執行的,有些事務執行的比較快,有些事務執行的比較慢。如果先執行的事務還沒有複製完日誌,而後來執行的事務卻先於之前的事務完成日誌複製,那麼會導致在日誌緩衝區上存在日誌空洞,系統怎樣去追蹤空洞,這是一個很重要的研究課題。
其中這一類做法(預留空間)的典型代表是ELEDA演算法(ELEDA,Express Logging Ensuring Durable Atomicity),它把系統分成三類執行緒:工作執行緒、日誌狀態追蹤執行緒以及日誌刷盤執行緒。這樣子分工主要是為了達到無鎖化設計的目的(回想一下InnoDB的log_sys->mutex以及log_sys->write_mutex的作用)。工作執行緒在提交時刻利用原子操作申請LSN,預留空間,然後將日誌記錄複製到緩衝區。複製完成以後即可繼續執行其它操作。如果是提交事務那麼需要提供回撥函式。追蹤執行緒記錄最大連續的日誌緩衝區偏移SBL(Sequentially Buffered Log)。刷盤執行緒將小於等於SBL的日誌寫入持久儲存,更新SDL(Storage Durable Log)為SBL。這時候就可以通知commit LSN小於SDL的事務提交成功。
怎樣維護這些資訊還是很有挑戰的,特別是追蹤日誌空洞。在ELEDA中,每個工作執行緒維護一個共享LSN連結串列如圖所示,日誌追蹤執行緒根據這些連結串列建立最小堆,堆的頂部就是SBL。同時,工作執行緒在日誌複製完成以後會在跳錶(Hopping Index)相應的區間進行累加。當複製的位元組數等於設定的區間值,那麼表明該區間的日誌已經全部複製完成,可以執行刷盤動作(這種方式對比利用最小堆推進SBL可以起到加速作用)。
論文作者修改了MongoDB的儲存引擎wiredTiger,在36核,488G記憶體上的伺服器上測試。在YCSB的測試標準上,修改後的wiredTiger擴充套件性可以達到32核,對比沒有修改的版本效能提升71X,可以充分利用底層硬體的處理能力。在TPCC的測試基準上,也有類似的表現。
2、大併發場景最佳化之二:PostgreSQL的做法
我們來看一下PostgreSQL的另一種做法。在9.4版本,PostgreSQL的開發者意識到了日誌提交的問題,重構了日誌提交演算法。在之前的版本中,日誌提交臨界區程式碼段有300行左右,最佳化之後,該臨界區程式碼段縮短為只有5行。PostgreSQL的設計者們利用8把鎖追蹤日誌空洞,規定事務將日誌寫入共享日誌緩衝區時刻需要申請這種型別的鎖,在日誌複製完成後即可將鎖釋放。事務提交時刻只需檢查這8把鎖的狀態即可。
這個設計有一個技巧性,就是需要優先考慮事務提交請求,也即對於鎖的排隊需要考慮優先順序。透過類TPC-B測試顯示,這個實現在大併發場景下效能能夠提升30%以上。
3、NVM上的日誌管理器
另外一個就是針對非易失性記憶體而設計的日誌子系統。這種方法更為激進,大概的思路是現在不再是維護一個集中式日誌管理器了,而是把負載分散到N個不同的日誌管理器上,去提高寫日誌的併發性,但是還是要去解決日誌空洞問題與確定日誌回放順序問題。在提交技術上,多數採用passive group commit技術。
如上圖,這個方法就是完全去掉了集中式的log buffer,每個事務自己維護一個私有的日誌緩衝區,這樣的話就把log buffer上的一些鎖、臨界區等資源競爭完全給去除掉了。系統可以選擇在事務提交時刻將日誌記錄批次移動到非易失性記憶體或者在填充完日誌記錄以後馬上移動到非易失性記憶體。這兩種日誌持久化策略分別對應:flush-on-commit以及flush-on-insert。在當前的CPU體系架構下,需要使用cflush以及mfence等指令將快取記憶體的資料一併寫入。Flush-on-commit可以將日誌持久化的代價均攤。
這是惠普實驗室的研究人員針對非易失性記憶體而設計的日誌管理器。如上圖,Redo空間按照頁面進行劃分, undo空間按照事務進行劃分;事務日誌可以按照頁面為劃分並行寫入,這對於以頁面為單位進行重放日誌的系統模型十分友好,加速系統恢復速度。在TPC-C測試基準下,效能提升1.2-1.6倍。
最後介紹卡耐基梅隆的資料庫研究小組提出的新理論實踐,Write-Behind Logging(WBL)。目前幾乎所有的資料庫都是使用Write-Ahead Logging方法。這種方法帶來的一大弊端是軟體執行時開銷以及系統恢復時間較長。WBL執行時只需追蹤髒頁,無需構造redo日誌。事務提交時刻先寫髒頁,然後寫日誌。事務的日誌協議不用再去構造After-image,直接就寫上事務提交的時間區間(Cp,Cd)就行了。小於CP這個時間點的事務都已經提交了,而落在這個時間區間(Cp,Cd)裡面的事務,就是還沒有提交的,也即是活躍事務區間。在事務恢復的時候,系統知道這個時間區間的事務沒有提交,對其它事務不可見,無需undo操作。系統也沒有必要去進行Redo操作,因為提交資料都已經持久化。系統崩潰恢復時,需要一趟掃描日誌,建立崩潰時候的時間區間(檢點可以減少需要掃描的日誌量)。從實驗上看,WBL可以達到即時恢復的效果,同時效能提升約30%。
最後一種做法是統一資料塊與日誌塊,採用log is database的理念。資料塊可以在多種狀態下轉換,減少系統IO,提升效能。由於時間關係不仔細展開,可以參考相應的參考文獻。
總的來說,我們傳統的ARIES演算法是面向磁碟而設計的,在大併發情況下日誌模組容易成為系統瓶頸。因此可見軟體的設計需要適配底層硬體的發展,才能更好地獲取底層硬體的能力。目前最佳化集中式日誌管理器主要有三種方式:一種是縮短臨界區,另一種是並行化寫日誌操作,另外,就是針對新硬體場景開闢新的理論實踐。
四、總結
綜上,計算機硬體的發展為我們資料庫理論的創新開啟了新的一扇大門。以前我們認為資料庫理論發展進入了封閉期,基本上沒有什麼可以突破的了,但是現在,特別是非易失性記憶體出來以後,還有AI的飛速發展(從某種意義上說,AI的飛速發展其實也是得益於新硬體),我們發現資料庫系統理論又有了新的方向,新的進展,這對於我們資料庫核心開發人員來說,是一個很激動人心的現象。
在多核與記憶體計算時代下,系統設計人員應當將更多的精力放在系統擴充套件性以及資料訪問的區域性性上。而非易失性記憶體的出現使得系統設計人員可以將注意力完全地從I/O上移除,專注系統擴充套件性設計。
引用狄更斯的名言,“這是最壞的時代,也是最好的時代” 。各種不同應用領域的出現,對資料庫的要求更高了,同時機遇與挑戰並存,這對我們而言也是最好的時代。
關於DTCC
第九屆中國資料庫大會以“數領先機?智贏未來”為主題,設定2大主會場及22個技術專場,邀請來自國內外網際網路、金融、教育等行業百餘位技術專家,共同探討Oracle、MySQL、NoSQL、大資料、機器學習、區塊鏈、資料視覺化等領域的前瞻性熱點話題與技術。
(更多精彩報導,請戳:http://www.it168.com/redian/dtcc2018/)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31473948/viewspace-2157761/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 日誌篇:模組日誌總體介紹
- 日誌模組
- Milvus 編譯環境演進編譯
- nodejs 日誌模組 winston 的使用NodeJS
- SpringBoot多環境日誌配置Spring Boot
- Javascript模組化的演進歷程JavaScript
- 日誌記錄模組logging
- 轉轉容器日誌採集的演進之路
- Python強大的日誌模組loggingPython
- 雲原生環境下的日誌採集、儲存、分析實踐
- 日誌架構演進:從集中式到分散式的Kubernetes日誌策略架構分散式
- iLogtail和Loggie:K8S環境下日誌收集利器AIK8S
- Java 開發中常用的日誌模組Java
- 『無為則無心』Python日誌 — 65、日誌模組logging的使用Python
- 在 Windows 環境下,有幾種開源的日誌監控軟體可供選擇,包括:Windows
- 硬體開發筆記(三):硬體開發基本流程,一個USBRS232的模組(二):設計原理相簿筆記
- springboot下新增日誌模組和設定日誌檔案輸出Spring Boot
- 1. 硬體和環境說明
- 輕鬆定位硬體故障方法-日誌分析
- Golang語言之Prometheus的日誌模組使用案例GolangPrometheus
- mybaits原始碼分析--日誌模組(四)AI原始碼
- python之logging日誌模組詳解Python
- Python:使用logging模組記錄日誌Python
- python-包及日誌模組使用Python
- 我們NetCore下日誌儲存設計NetCore
- 【webpack進階】前端執行時的模組化設計與實現Web前端
- 第二篇:低功耗模組Air724UG硬體設計手冊AI
- 第三篇:低功耗模組Air724UG硬體設計手冊AI
- 軟體成分安全分析(SCA)能力的建設與演進
- 乾貨 | 攜程日誌系統治理演進之路
- 環境與生態統計||統計假設
- Eclipse Collections的API設計演進EclipseAPI
- PyCon 2018: 利用logging模組輕鬆地進行Python日誌記錄Python
- 使用面向 Aspect 的程式設計改進模組性程式設計
- Java開發中操作日誌的作用和模組Java
- java crm 進銷存 模組設計方案Java
- 日誌分析如何演變
- k3568硬體開發筆記(第二篇 ) 外圍模組設計筆記