VLDB'22 HiEngine極致RTO論文解讀

来源:https://www.cnblogs.com/huaweiyun/archive/2022/09/09/16673088.html
-Advertisement-
Play Games

摘要:《Index Checkpoints for Instant Recovery in In-Memory Database Systems》是由華為雲資料庫創新Lab一作發表在資料庫領域頂級會議VLDB'2022的學術論文。 本文分享自華為雲社區《VLDB'22 HiEngine極致RTO論文 ...


摘要:《Index Checkpoints for Instant Recovery in In-Memory Database Systems》是由華為雲資料庫創新Lab一作發表在資料庫領域頂級會議VLDB'2022的學術論文。

本文分享自華為雲社區《VLDB'22 HiEngine極致RTO論文解讀》,作者:雲資料庫創新Lab 。

1. HiEngine簡介

HiEngine是華為雲自研的一款面向雲原生環境的OLTP型資料庫, HiEngine在標準TPC-C事務模型下, 端到端單節點(華為2488H V5機型)性能可以達到663w+的tpmC, 多節點擴展性線性度超過0.8。 其核心架構關鍵詞如下:

  • 計算,記憶體,存儲三層分離式雲原生架構
  • 華為雲原生的分散式記憶體資料庫
  • 同時包含分離式記憶體池和分離式存儲池

具體HiEngine詳細的技術架構和性能表現,可以參考我們團隊發表在SIGMOD2022 [1]的論文工作。

2. HiEngine對日誌恢復的優化

此外, HiEngine還擁有極致的RTO恢復性能,在100GB數據集下,可以達到10s級別的恢復時間。 本文將詳細闡述HiEngine在追求極致RTO過程中提出的若幹技術。

2.1 記憶體資料庫的經典恢復流程

回溯學術界現有的工作, 我們可以把記憶體資料庫的恢復大體劃分為幾大步驟:

  • STEP1: 載入最近一次成功執行的元組檢查點數據;
  • STEP2: 回放檢查點到故障點期間的日誌數據;
  • STEP3: 掃描元組數據,重建記憶體索引結構;

我們團隊充分結合HiEngine架構的特點和學術界State of the art的一些工作, 提出了結合HiEngine Indirection array結構特點的dataless checkpoint和indexed logging恢復技術。 因此需要首先介紹一下什麼是HiEngine的Indirection array。

2.2 Indirection Array

與大多數工業/學術系統一般, HiEngine內部採用多版本的方式維護Tuple元組數據, 並且Tuple並沒有按頁面進行組織,而是按照版本鏈的方式組織。 每個邏輯元組用一個全局唯一的RowID標識, 所有的RowID以一個全局的數組進行組織, 該數組我們姑且稱作Indirection Array。 並且, HiEngine索引中每個葉子節點存儲的是RowID而不是具體的tuple address。

Indirection Array的設計有如下幾點好處:

  1. 更新操作不用修改索引;
  2. 非唯一索引可以通過添加RoWID尾碼轉換為唯一索引;
  3. 記憶體元組和日誌記錄統一編址, Indirection Array中存放的address既可以是記憶體元祖的頭指針地址, 也可以是record對應的log record的offset地址;
  4. Indexed-Logging;
  5. Dataless Checkpoint;

下一章節我們將對Indexed logging和Dataless checkpoint展開描述。

2.3 Indexed-logging

HiEngine繼承了"the log is the database"日誌即資料庫的概念, 具體來說Indirection Array中存放的地址既可以是記憶體的tuple,也可以是一個對應在記憶體中的log offset。 (我們使用uint64的最高一個bit標識是記憶體地址還是磁碟偏移。 因為對於64bit的操作系統的指針高12bit都為0)。

另一方面, 多版本系統在恢復後, 只需要恢復最新版本的數據即可, 因為舊版本的數據在系統重啟後對事務不再可見。 因此, 在系統一旦故障時, HiEngine只需要並行掃描日誌流, 把對應的log record的offset偏移設置到Indirection array的對應位置即可。 註意這一過程中還可以對多個日誌流採用並行掃描和並行設置log offset的方式加速。

一旦系統恢復時,把最新版本的log offset設置到對應的Indirection Array的TID位置後。 HiEngine系統即可開始工作, 對於首次訪問到某一TID時, 系統會載入offset位置的record, 線上生成一個新版本的tuple數據。 我們稱作為bringOnline Lazily。

並且在系統運行期間, HiEngine可以識別冷Tuple數據, 對Tuple數據進行凍結並轉存成log record, 同時修改對應RoWID的address為log record的offset

2.4 Dataless checkpoint

檢查點執行的頻率決定了需要恢復的日誌量的上限, 因此為了追求儘可能快的恢復時間, 檢查點執行的頻度必須得高。 這就對檢查點演算法本身提出了更高的性能需求:(1) 單次檢查點執行時間必須要快; (2) 檢查點不能導致前端事務性能明顯的抖動;

因為記憶體元組支持多版本的優勢, 可以極其容易獲取事務一致性的快照數據, 常規的檢查點演算法是獲取該快照數據並對快照存檔。 但常規的方式必然導致需要存檔的快照數據量大, 進而導致checkpoint時間較長。

而HiEngine的做法不甚相同, (1) HiEngine在事務預提交階段, 把存檔日誌的offset反向回填到對應tuple數據的header中存放。 (2) 因此在Checkpoint獲取事務一致性快照後, 並不是把快照中的tuple數據存檔, 而是把對應tuple header中的offset進行持久化, 並且以一個序列化的Indirection Array存檔。

總結: HiEngine這種將快照對應的log offset存檔的checkpoint方法叫做DataLess Checkpoint, 其相比於對快照進行存檔的方式, 需要序列化存檔的數據量少, 對前端事務影響的時間也更短, 恢復時載入檢查點的時間也更短。

2.5 階段性優化與遺留瓶頸

Indexed Logging和Dataless checkpoint只是解決了章節2.1提到的STEP1和STEP2的性能瓶頸, 這也是當下很多學術工作關註的優化重心。 我們通過實驗對比, 在百GB規模的TPCC數據集下, 沒採用Indexed logging和Dataless checkpoint技術的恢復時間在310s左右, 採用了Indexed logging和Dataless checkpoint技術後,可以把恢復時間減少到50+ s。

但是50+ s離HiEngine期望的目標仍有距離, 因此我們的工作重心需要聚焦到如何優化STEP3中索引重建的時間, 進一步追求極致的RTO時間目標。

3. HiEngine對索引恢復的優化

3.1 索引檢查點的必要性

首先, 需要指出的是元組數據可以通過載入檢查點並回放日誌的方式得以恢復, 但索引數據則需要重建的方式才能得以恢復。

必要性: 主要原因在於索引並沒有檢查點, 如果索引也存在索引檢查點數據, 索引數據的恢復也可以載入索引檢查點數據, 然後通過重做insert和delete的log record恢復checkpoint之後的index索引項。

因此巨集觀朴素的想法是通過索引檢查點對HiEngine索引重建的耗時問題進行優化。 但是:

(1) 索引本身並不支持多版本, 因此無法無阻塞的獲取事務一致性的快照數據。 換句話說, 索引檢查點必然是模糊Fuzzy類型的檢查點。

(2) 而HiEngine的日誌只有redo沒有undo, 如何保證恢復出來的數據沒有臟數據,並且不丟失索引項。 總之, 如何保證數據的正確性。

(3) 並且由於索引不支持快照隔離, 如何無阻塞的獲取索引檢查點也是一項重要的性能問題。VLDB這篇論文針對正確性和性能兩個維度展開討論HiEngine的索引檢查點。

3.2 索引檢查點的正確性

我們通過一個示例展示, HiEngine如何保證檢查點數據的正確性。

如圖所示, 我們假設存在一個理想化的演算法能夠獲取快照隔離級別並且事務一致性的索引檢查點數據, 對應的元組檢查點和快照檢查點分別標識為TS和IS1。 此種情況數據元祖檢查點和索引檢查點獲取的都是時間戳在180時刻的事務一致性的快照數據, 恢復後很容易保證數據的正確性。

但是現實的情況是索引只能"嘗試"捕獲當前觸發檢查點時刻的數據, 此時在索引中必然存在尚未提交事務的索引項, 因此捕獲到的檢查點數據必然是非事務一致的, 或者說是模糊的(Fuzzy checkpoint)。 我們用IS2標識。

對比IS1和IS2可以發現, IS2相比於IS1差異的索引項是來自於phase2階段的操作。 前文已經說過, 因為Indirection array的設計, update操作不會修改索引, 因此我們需要針對insert和delete操作提出數據正確性保證的措施:

(1) 插入操作: 對於在phase2階段的插入操作, 一旦系統恢復時載入檢查點後, 我們應該能識別出phase2節點插入的臟數據。 因為tuple數據是可以保證事務一致性和數據正確性的。 在系統訪問index時,我們需要對index和對應tuple不匹配的索引認定為"臟數據", 並觸發補償性刪除動作, 同時給客戶端返回不存在該索引項。

(2) 刪除操作: 對於在phase2階段刪除的索引項, 因為恢復時只回放檢查點之後日誌, 該索引項必將在恢復後丟失lost了。 因此我們應該需要阻止phase2階段的index刪除動作的執行。 剛好, HiEngine和很多MVCC系統一樣, delete當做是交給GC模塊延後執行的。 我們只需要確保gc的watermark在檢查點觸發時滯後於checkpoint時間戳即可。也就是說 gc timestamp = min{minStartTs-1, minEndTs-1}。 詳細可以翻閱論文。

3.3 索引檢查點的性能目標

上一章節, 我們通過"恢復後識別並刪除臟索引數據"和"阻止滯後gc"的方式能夠保證的正確性, 但如何保證索引檢查點的性能仍是一個問題。

朴素的想法是停掉前端事務並複製索引數據, 但這肯定會導致很長時間的阻塞。 因此, 我們首先給出一個優化的索引檢查點演算法應該滿足一下4個條件:(1) Wait Free processing; (2) Efficient index operations; (3) Fast and frequent checkpoints; (4) Load friendly checkpoint file format。 具體對性能需求的描述, 可以查閱我們的論文。 並且, 我們提出了三種Index checkpoint的演算法。

3.4 ChainIndex

ChainIndex通過多顆物理索引樹維護一個邏輯索引, 其按照每次checkpoint產生一個新的索引樹的方式產生一顆新的索引樹, 索引樹組織成一個鏈表的形式, 鏈表頭的索引作為寫入索引, 維護一個檢查點周期內的增量索引樹。 非鏈表頭的索引樹都作為只讀結構存儲。 並且ChainIndex會在後臺合併若幹個delta樹。

檢查點過程: 在每次檢查點執行觸發時, HiEngine首先凍結鏈表頭的索引樹, 與此同時原子性產生一個新的索引結構用於接受新啟動事務的索引修改操作。 對於尚未結束的索引操作仍然寫入到凍結的索引樹, 待所有尚未提交的索引操作結束後, 我們採用後序遍歷的方式產生一個mmap友好的checkpoint文件。

恢復過程: 每次恢復時HiEngine只需通過mmap的方式載入checkpoint文件; 然後, 回放日誌恢復checkpoint之後的索引項。

總結: ChainIndex總體架構啟發來自於LSM, 對寫操作友好, 但(1)存在嚴重的讀放大問題。 (2) 並且ChainIndex只支持增量檢查點,不支持全量檢查點。

3.5 MirrorIndex

MirrorIndex在ChainIndex的基礎上, 通過引入一個額外的full tree或者說是mirror tree, 從而解決ChainIndex的讀放大缺點。 其在每一次insert或delete時, 同時對headTree和mirror tree進行修改, 可以確保headtree包含一個檢查點周期的增量數據, mirror tree包含全量數據。 因此, 讀操作直接訪問mirror index即可。

MirrorIndex的checkpoint流程和ChainIndex一樣。 但恢復流程有很大不同。 其恢復流程如下

  1. mmap映射增量檢查點文件到記憶體中
  2. 回放日誌恢復headTree的數據
  3. 步驟2完成後, 系統便可以接受服務了,但此時性能表現和ChainIndex類似, 有嚴重的讀放大問題。 與此同時, HiEngine觸發後臺rebuild mirror index的過程, 待mirrorIndex重建完成後, 讀放大問題消失

總結: MirrorIndex相比ChainIndex消除了讀放大的問題, 但卻(1)存在一定的讀放大。 (2)並且MirrorIndex需要引入額外的樹結構, 記憶體占用很多。 (3) MirrorIndex只支持增量檢查點。(4)恢復後,有一個短暫的性能"爬坡"階段。

3.6 Indirection Array CoW

ChainIndex和MirrorIndex總體思想都是採用delta數據的思想,維護增量檢查點。 另一大類的策略是採用Copy On Write的思想, 針對樹結構的CoW演算法是Path Copying, 其修改拷貝節點時會導致父節點的指針發生修改, 從而導致級聯修改。 這會導致性能下降很多, 並且路徑拷貝會導致索引併發的lock free演算法需要適配, 工作量大。

因此我們放棄了Path Copying的策略, 通過引入Indirection array的方式引入"邏輯索引節點"的概念, 從而消除級聯拷貝的問題。 IACoW對每個index node分配一個唯一的node ID, 並且parent node的child pointer存放的不在是記憶體指針地址, 而是修改為子節點的node id, 此時修改拷貝節點時不需要修改父節點指針。

另外我們引入checkpoint epoch number來識別index node的新舊版本。 具體來說, 每次checkpoint全局epoch自動加一, 不同checkpoint周期因為copy on write產生的新版本用不同epoch number標識。 checkpoint執行流程中, 我們通過掃描Indirection array, 並根據epoch number可以捕獲增量和全量兩種類型的檢查點數據。 恢復時, 通過mmap的方式即可恢復checkpoint數據。 具體的node版本管理, node的gc以及checkpoint數據組織形式等細節問題,可以查閱論文。

總結: IACoW同時支持增量和全量檢查點, 並且IACoW引入的額外記憶體並不多。 但是IACoW會因為pointer chasing導致少許讀放大。

4. HiEngine恢復性能評估

實驗過程中, 我們首先評估checkpoint對性能抖動的影響, 結果展示MirrorIndex和IACoW在checkpoint期間性能影響並不大, 但ChainIndex由於讀放大問題性能抖動嚴重。

同時我們測試了在相同配置下, 不同演算法的恢復時間。 結果顯示在異常下點時, IACoW可以保證在10s的時間內完成恢復。

在正常下電時, IACoW可以保證在2s的時間內完成恢復。

並且我們在TPC-C和microbench負載下, 實驗反應MirrorIndex和IACoW對端到端性能的影響在10%以內, 但卻可以換取10s級別的RTO保障。

我們在控制相同事務性能的前提下, 測試各自的索引記憶體空間開銷。 實驗表明, IACoW的額外記憶體開銷很小, 但MirrorIndex需要x2的記憶體開銷。

我們總結對比各種方案的優缺點如下:

5. 總結

論文首先發現記憶體資料庫的索引重建是一個性能瓶頸點, 並得到了評委們的一致認可, 摘錄VLDB Reviewers對論文的選題評價。

The authors observed that, in today’s systems, the performance bottleneck in recovery is in restoring indexes. This is a cute observation which I consider important to the system community.

Overall, it is an important contribution to point out index restoration as the new performance bottleneck - I wasn’t aware of this before.

As the techniques have been improved with database recovering, this work claims that index rebuilding becomes a bottleneck of in-memory database recovering. This observation is very interesting, and it motivates the need of fast index recovering (instead of fast index reconstruction).

針對索引重建的瓶頸點, 本文探討了索引正確性的保證,並提出了3個索引檢查點演算法。 最終在端到端的HiEngine系統中,對比評估了各自的優缺點。 實驗結果表明, IACoW演算法在100GB規模下可以達到10s級的恢復時間, 對於有極致RTO需求的場景, 可以引入該演算法提速恢復。

參考文獻:

[1] Yunus Ma, Siphrey Xie, Henry Zhong, Leon Lee, and King Lv. 2022. HiEngine: How to Architect a Cloud-Native Memory-Optimized Database Engine. In Proceedings of the 2022 International Conference on Management of Data (SIGMOD '22). Association for Computing Machinery, New York, NY, USA, 2177–2190. https://doi.org/10.1145/3514221.3526043

展現領先科研實力,華為雲資料庫創新LAB三篇論文入選國際資料庫頂級會議VLDB'2022

華為雲資料庫創新lab官網:https://www.huaweicloud.com/lab/clouddb/home.html

We Are Hiring:https://www.huaweicloud.com/lab/clouddb/career.html ,簡歷發送郵箱:[email protected]

華為雲資料庫創新Lab 時序資料庫openGemini正式開源,開源地址:https://github.com/openGemini,誠邀開源領域專家加入!

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題目 中文 實現一個以 T 作為泛型參數的 IsNever類型. 如果 T 是never, 返回 true, 否則返回 false. 示例: type A = IsNever<never>; // expected to be true type B = IsNever<undefined>; // ...
  • ▶ 簡介 aardio 可以非常方便地調用 .NET( 不需要任何複雜的步驟 )。 .NET 在 aardio 中很好用,系統自帶 .NET 組件以及各種開源 .NET 組件在 aardio 用戶中也很受歡迎。 aardio + .NET 生成的 EXE —— 可避免被 ILSpy 直接反編譯。 a ...
  • 要說捲,每分鐘轉xx圈,誰還能有它“捲”?! 要說捲, “承包”工業能耗30%, 雙碳壓力下,誰能有它非捲不可的壓力?! 要說捲,工業、汽車、航天、醫療……生活中處處有它的身影,更擔當決定性的角色,能不捲? 作為近代人類文明發展的重要推動力,電機在如今的社會中幾乎無處不在,為現代生活的大量基礎應用提 ...
  • 一、下載安裝包 archlinux-x86_64.iso 下載傳送門:Arch Linux BitTorrent Download 是磁鏈和種子下載,往下拉,找到 HTTP Direct Downloads , 選擇 China ,選擇適合自己的國內鏡像進行下載 Vmware 下載傳傳送門:VMwa ...
  • 1.俄羅斯延長接受簡化版認證流程的日期 2022年8月31日,俄羅斯聯邦政府發佈了第1255號法令,主題為“關於第353號法令附錄18的修正”,主要內容是俄羅斯延長接受“簡化版認證流程”的日期,從2022年9月1日延長至2023年9月1日為止。該法令發佈後立即生效。 “簡化版認證流程”的相關細則可以 ...
  • 1.視圖:view 視圖就是一張虛擬的表。表是真正存數據的,視圖只是顯示查詢結果。 視圖的作用:隱藏表的結構、簡化sql嵌套查詢操作 註意:視圖就是你要查詢數據的一個中間結果集,我們一般只用來做數據查詢的 創建視圖:create view view_name as 查詢語句 例如: mysql> c ...
  • 2022-09-09 1、左連接查詢(left join) 查詢條件的一種,以左表為主根據條件查詢右表數據,如果根據條件查詢右表數據不存在null值填充。 以“students表(id,name,age,gender,is_del,height,c_id,id,name)” "classes表(id ...
  • 不說那種建表的時候 設置好主鍵格式 的 解決方案. 事後諸葛啊. 誰都會不靠譜方案1 改主鍵表結構. 費時! 主鍵已經超長了.說明 數據量相當大. 改表結構的時間成本你能等得起嗎方案2 超長表 改表名作為歷史表 ,新建新表,然後根據業務情況將歷史表數據酌情複製到新表中. (比如最近3個月的數據. 不 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...