近日,第12屆中國數據庫技術大會(DTCC 2021)在北京國際會議中心召開。作為全球領先的雲計算、數據庫產品服務商,騰訊雲數據庫集結多位頂級技術大咖亮相本次大會,圍繞當前比較熱門的數據庫技術主題,共同探討最前沿的技術趨勢與實踐。
本期為大家帶來騰訊專家工程師朱閱岸老師在本次大會上的分享,主題為“HTAP系統的問題與主義之爭”。以下是分享實錄:
問題與主義之爭其實是上世紀初胡適與李大釗之間的一場論戰。胡適主張改良,提倡解決一個個問題,也就是少談些主義,多研究些問題;而李大釗則主張改革,認為只有解決了這個根本問題,其他的問題才能解決,二人代表着兩個截然不同的路線。其實圍繞着HTAP系統的演進也存在類似兩條路線,一條路線是改良,一個路線是通過改革的方式打造全新的系統。今天我就為大家分享HTAP系統的技術實現相關路線。
1. HTAP的定義與挑戰
我們先來解釋HTAP的定義與挑戰是什么。下圖是經典的數據處理框架,我們在里面划分出兩種數據庫系統:一種是事務型的系統,這是數據源頭產生的地方;另一種是分析型的系統,是我們的數倉。數據會定期從交易型數據庫中借助ETL的方式流入到數倉. 然后在數據倉庫做分析處理,產生相應的報表和報告。企業的經營決策者能夠通過分析報告和決策報表去觀察企業的經營行為,從而觀察到未來的發展趨勢。這是數據寶貴之處的體現之一。不少公司都在數據基礎設施上投入人力物力,期待在數據變現上獲得更好的回報。
研究表明,這些樣本公司在每13美金的投入中就有1美金投入到數據分析里,有74%的公司想成為一個數據驅動型的公司,如果一個公司采用更為先進的數據分析手段,那它超越競爭對手的可能性將達到兩倍。
數據分析具備巨大的商業價值。但在目前的數據處理框架中,OLTP和OLAP兩類系統是割裂開的,主要是通過ETL把數據從交易型數據庫導入到分析型數據庫,而ETL的時延比較大,可以達到數十分鍾到幾小時,甚至是幾天。上圖右下角的圖片顯示,數據的商業價值會隨着時間的流逝而下降。數據產生再經過ETL導入到數倉,在數倉里進行分析,然后做決策,執行相應的動作。在這時,數據的商業價值就會大打折扣。
因此最理想的情況是在數據產生后就能迅速對其進行分析。為了解決這個問題, HTAP系統應運而生,它的初衷就是要打破事務處理和分析處理的界限,使企業能夠通過HTAP系統更好地發現市場反饋,獲得更好的創新。這么先進的數據處理技術,為什么近年來才引起人們的關注呢?我個人認為,這主要得益於現代列存儲技術的發展,HTAP系統的出現才成為了可能。
以前客戶用SQL Server做查詢分析處理,需要十多個小時以上。在這種技術能力下是無法達到實現HTAP系統要求的。后來SQL Server采用列存儲技術,耗時十幾個小時的分析可以降到幾分鍾,甚至可以在秒級時間內把結果運行出來。列存儲技術及背后的向量查詢引擎的發展,使得HTAP登上了歷史舞台。
HTAP能讓數據產生后馬上就可以進入分析場景。但它面臨最大的問題是如何把OLTP和OLAP兩類工作負載更好放在一個系統上運行,畢竟這兩類工作負載本質上是互斥的。交易型的事務是短事務,以寫為主;分析型的事務是長事務,以讀為主,經常需要做全表掃描,在掃描的基礎上做統計、聚合等操作。這種情況下,OLAP的事務經常需要獨占系統資源,使交易型的事務吞吐量下降。有研究表明,把OLTP和OLAP放在一個系統里調度,OLTP的吞吐量可能會下降到原本的1/3到1/5。所以如何讓OLTP和OLAP在系統運行的過程中相互干擾最小,就成為HTAP系統設計的難題。
從過去十多年的發展來看,主要有兩種實現HTAP的方案:第一種是改良的方式,在現有業務系統上延伸擴展,打造一個HTAP的系統來滿足業務的需要,;第二種是從頭開始設計一個具有顛覆性的系統. 當然第二種方式會產生更多有價值的技術,也會涉及到比較多技術難題,包含技術突破、業務適配等。
從現在來看很難說哪種更好,今天的分享我們也不回答哪一條路線更好,我們會在這兩條路線上挑選典型的具有鮮明技術特色的系統,來和大家分享,同時會在最后給出最近十年來HTAP系統技術的演變過程和發展趨勢。
2. HTAP系統的架構實踐
2.1 HTAP系統的類別
總體來看,HTAP系統架構的實踐可以分成兩類:一類是改革,另一類是改良。前者采用One size fits all的策略,用一個大而全的系統同時滿足OLTP和OLAP的需求,后者采用One size doesn’t fit all模型,將OLTP和OLAP兩種系統組合起來,通過CDC的方式把OLTP上產生的數據以增量的方式導入到數倉進行分析。
第一類下又分為兩個子類。第一個子類是單拷貝系統,在一個系統里用一種數據格式滿足兩種業務需求,通常是采用PAX存儲。系統整體來看是采用行存儲,但是當它把數據打包存儲到某個頁面時轉換成列存儲的形式。另一種是雙拷貝系統,一個系統里同時存在行存儲和列存儲,行存儲上的更新會定期導入到列存儲里轉換成列存儲格式。在列存儲上進行分析,行存儲上執行更新。這在某種程度上降低了它們的競爭。第二類可以分為共享存儲和獨立存儲兩個子類。
下圖右上角就是這四種類型的系統實現HTAP特征時的比較,可以從兩個維度來刻畫,一是數據新鮮度,二是工作負載干擾程度。
One size fits all策略把OLTP和OLAP兩種工作負載放在一個系統上,如圖1左上角,就干擾程度而言,OLTP和OLAP相互干擾最強,而單系統單拷貝方式尤為明顯,其次就是單系統雙拷貝的方式。這兩種實現方式的缺點是OLTP/OLAP的干擾比較大會導致事務工作負載的吞吐嚴重下降,但優點是數據可見度高,因為不需要做數據的同步導入導出或數據轉換。
One size doesn’t fit all 即松耦合模型也有兩種類別,橙色橢圓代表共享存儲下的松耦合系統,好像目前還沒有有商業化的產品,只有IBM出了一個DEMO;另一種是采用類似proxy方式把TP與AP兩種獨立系統組合起來的松耦合系統。這兩類系統中,OLTP和OLAP分別在兩個獨立的系統上進行,可以把干擾降到最小,但數據需要同步,交易型數據庫更新的數據要通過CDC的方式同步到分析型系統上,數據的延遲會比較大。
列出了幾個典型的HTAP工作負載對時延的需求。系統監控的延遲在20毫秒,在線游戲、個性化廣告推薦、商品價格監控,則是在100-200之間。
2.2 單系統單拷貝之Hyper
接下來我們從四類系統實踐中挑選部分代表性的系統來看HTAP技術如何具體實現。首先是Hyper。Hyper是很典型的系統,它原本是德國慕尼黑工業大學的 Thomas Neumann教授團隊開發的原型產品,但是性能與創新性實在太好,后來被美國tableau公司收購,從學術型的產品變成了商業化的產品,不論從技術與經歷都具有較高的代表性。
Hyper的查詢執行模式很有考究。OLTP是串行執行,不需要加鎖。這是因典型OLTP數據庫把大部分時間都消耗在加鎖、緩沖區管理、日志管理上,這些操作消耗了系統80%左右的資源。在Hyper中沒有這些開銷,事務串行執行,去除維護事務隔離性等開銷。一個事務串行執行的耗時只有微秒級別,這個是可以接受的。VoltDB是類似的一個系統,事務執行同樣不需要加鎖,串行地執行(通過分片達到並行執行的效果)。OLAP則通過fork產生子進程在事務一致性的拷貝上運行查詢。更新時再把相關的數據頁拷貝出來,讓交易型事務在不同的數據頁上進行更新(Copy-on-Write)。
此外通過區分冷熱數據的方式,把數據分成熱數據、冷數據和溫數據。上圖右下角就是通過硬件的方式即MMU的內存管理單元去區分數據的訪問熱度。熱數據放在正常頁面即小頁面上,冷數據是壓縮存儲,放在4M的大頁面上。這種做法的好處是更新代價比較小,同時在做OLAP查詢的時候,在大頁面上會有比較好的性能。
Hyper的查詢引擎也是相當優秀的,它利用向量化的查詢引擎,用LLVM生成可執行的機器碼。這個技術非常具有代表性,連著名的Spark也參考了它的代碼生成技術。
2.3 單系統單拷貝之SAP HANA
HANA也是采用單系統單拷貝實現HTAP。它不太像一個數據庫系統,反而像是一個支持多引擎多工作負載類型的統一數據管理平台。HANA系統的分層結構做得很好,總體來看可以分為編譯層和執行層,上層又可以分為查詢的解析,生成抽象語法樹AST,再映射到計算圖模型,接着對計算圖模型進行物理優化。此后由分布式執行框架去構建實際的數據流,將具體的物理執行算子分發到特定的引擎執行。因為HANA支持多個工作引擎,比如數據倉的查詢引擎、文本、圖等,它向上提供了針對這些特定引擎的物理算子,比如關系操作算子、圖計算的算子等。
執行引擎下又有統一的表模型。它向上提供一個統一的接口,類似於MySQL下的handler接口,下面的存儲引擎負責實現具體的存儲,上面的查詢執行器只要實現handler接口就可以對接到系統里去。里面的存儲分成三級:首先是L1-delta,對應的是熱數據和無壓縮的行存儲;其次是L2-delta,對應的是輕量級壓縮的列存儲,比如字典壓縮;最后是L3-main store,對應的是重度壓縮列存儲。更新發生在L1-delta,數據會定量地導入到Main store里。Main store是讀友好的實現方式,滿足AP類型的查詢,而L1-delta是寫優化的實現。通過這種方式來滿足HTAP的需求。
它會定期地執行合並操作,把數據定期地合並到Main store里。在合並操作的過程中會生成Main2和Delta2,這時讀操作就在Main1、Delta1和Delta2進行。拷貝完成以后Main1和Delta1最終會合並到Main2,最后切換過來,在Main2上進行讀操作,寫操作發生在Delta2。數據加鎖的行為只是發生在緩沖區切換階段。L1-delta采用redo日志保持持久性,Main store采用影子頁技術減少日志的寫入,保持一致性與持久性。
2.4 單系統雙拷貝之SQL Server
SQL Server是一個雙拷貝系統,把數據按行切分成group,定期轉變成列存儲。具體來說是,每一百萬條數據做一個Group,進行切分,然后針對每列轉換成列存儲,叫做segment。每個列采用單獨的壓縮算法,比如有些適合用字典壓縮,有些適合用數值壓縮,因此不同的列采用不同的壓縮算法。轉換后的列存儲附加額外字典表(如有),存儲到Blob類型中。外面的directory追蹤這些segment的存放位置。SQL Server也針對列存儲提供了批量執行的算法,加速分析操作。
2.5 單系統雙拷貝之Oracle
Oracle是另外一個采用雙拷貝方式實現HTAP的系統,每個系統里針對有需要的表,會同時存在一份行存儲和列存儲,在列存儲上做分析操作;在行存儲上進行更新,定期同步到列存儲里。系統可以靈活指定需要采用行存與列存的表,也可以系統運行時更改表特性。Oracle利用RAC集群進行橫向拓展。
這里舉兩個例子,來介紹Oracle是如何利用列存儲加速分期操作的。假如我們查找Outlet這個商店類型所有的銷售額,首先掃描維表,根據“type把Outlet類型的商店ID拿到,生成一個map”,接着在事實表的對於外鍵列里把商品ID拿出來在這個map查找,如果找到就可以把Amount累加起來。它通過只掃描某些特定的列,生成相關的map,就可以把要訪問的數據找出來,即把關聯操作簡化成表掃描操作,提升性能。
另外一個比較復雜的是要掃描兩個維表,生成兩個vectors,在里面再去事實表找相關的外鍵列,就可以直接定位到相關的vector,如果符合條件,就分類寫到相應的臨時表里。優點在於可以把表關聯操作轉換成表掃描操作,只需要訪問查詢中涉及到的列。
2.6 松耦合共享存儲之Wildfire
目前還沒有商業化的HTAP產品采用松耦合共享存儲架構,但是IBM開發了一個原型,叫Wildfire。從技術細節來看,它的系統分成兩類節點:一類是有狀態的節點,一類是無狀態的節點。有狀態的節點處理事務型的請求,無狀態的節點處理OLAP型的請求。OLAP型的請求可以容忍一定的延遲。
OLTP型的數據不會直接寫入到共享文件系統里,會寫入私有組成的一個集群,按照表分片的模式在這里進行數據的快速寫入,再定期導入到共享文件系統里,然后供分析型查詢去執行。分析型查詢會自己去定制一個引擎,去對接spark executor。這個引擎是無狀態的,可以去定制修改,在數據分析領域也是比較強悍的引擎,叫BLU,是IBM自家的分析執行引擎。總體上看,這個系統分成兩個集群:一個是OLTP,一個是OLAP。
國內有部分產品的技術和該架構比較類似,利用spark的能力和生態去做分析型查詢,比如利用spark的查詢優化器和機器學習能力去構建OLAP能力,OLTP能力則自己構建,這樣就把數據和這兩套系統在某種程度上做了一定的融合,變成HTAP。
2.7 松耦合獨立存儲之F1 Lightning
松耦合獨立系統近幾年比較流行,有兩個典型代表,一個是谷歌的F1 Lightning,另外一個是IBM的IDAA。我們先來介紹F1 Lightning。
F1 Lightning把系統分成三個模塊:OLTP數據庫、Lightning、查詢執行引擎。Lightning通過Changepump捕獲OLTP數據庫的更新,以訂閱的方式把數據分發到訂閱者。Lightning內部還開發了一個適配器,將CDC的模式轉換成內部統一的格式。內部有兩級存儲:內存存儲和磁盤存儲。內存存儲是以行存儲的模式存在,采用B-tree索引,在這里沒有轉換成列存儲,只有在數據寫入磁盤時才把行存儲轉換成列存儲。上層查詢通過快照的機制讀取可見范圍的相關數據。F1 Lightning將捕獲的日志分成兩層存儲,為日志維護系統范圍的檢查點時間戳以及為適配不同數據庫而設計的客戶端接口很大程度上借鑒了Databus。這種實現方式帶來的問題是查詢延遲。從谷歌的測試來看,查詢延遲在8-10分鍾之間。因為采用CDC方式,要把OLTP數據轉換成CDC內部統一的格式,再批量提交,因此延遲會比較大。
2.8 松耦合獨立存儲之IDAA
接下來介紹IBM的IDAA。最初IBM也開發了類似松耦合的HTAP架構。下圖中左邊是Db2,右邊是他們的Warehouse,掛載到事務型引擎,事務型引擎將更新定期同步。但IBM系統設計者認為,CDC方案需要花費大量的時間和背景知識來維護額外的進程,且延遲比較大。基於這個原因,他們對此進行了改進,通過輕量級的集成同步方案規避上述問題,將延遲減少180倍。
CDC的方案需要在源端經歷6個步驟:讀取數據,解密;過濾無關的日志,按照LSN排序;之后還要對數據進行行列轉換;把數據暫存起來,把數據轉換成CDC統一內部的格式;再批量等待commit或Rollback,發送之前還要把Rollback數據去除。這種情況對源端的壓力是比較大的,延遲也會比較大。
IDAA則建議把這幾個步驟都挪到目的端執行。目的端能夠原生地識別從Db2里傳輸過來的數據,當然這個是比較定制化的方案,通用性沒那么好,但延遲可大幅降低,只有原來的1/180。現在延遲只有1-2秒左右就能讀到最新的數據。
2.9 HTAP技術發展一覽
這部分我們來對HTAP近10年來的發展脈絡做梳理。圖中的直線方向表示后者的技術借鑒前驅或者是從該產品演變過來的。
從圖上可以看到,HTAP技術在2015、2016年之前主要是以One size fits all 策略為主,2015、2016年以后則以松偶合架構為主。這幾年如F1 Lightning、IDAA等都是采用松偶合方式來實現HTAP,甚至SAP也是有采用松偶合的技術方案實現HTAP。從One size fits all 的演變趨勢來看,大多是從雙拷貝轉換成單拷貝,從行存儲轉換成單一的列存儲來應對OLTP/OLAP的請求。從原先在磁盤上用列存儲,到內存里用行存儲,再到現在統一改成列存儲。這就是最近10年來HTAP技術的演變趨勢。
3. 雲原生對於HTAP系統的啟示
這一部分我們來看看雲原生架構對HTAP系統實現是否能帶來幫助。
下面是三個值得思考的問題:首先是雲原生架構即存算分離架構能否為HTAP的設計帶來便利?其次是存算分離架構和彈性算力能否緩解資源競爭?因為這兩條技術下的系統,在資源競爭和數據可見度上的表現各有優缺點,並不能說哪種產品的表現最優,都是在數據延遲和資源爭用上做取舍。此外,雲環境下豐富的計算資源池和存儲資源池能否針對不同的計算、不同的業務特征進行划分從而降低用戶的成本,這也是值得大家去思考的問題。
下圖是我構想中的願景圖。總體來看,理想的情況是,在一個雲原生架構里,Share storage和Query processing 分層,在查詢入口處采用多租戶設計,這里執行查詢解析和查詢的優化,然后把查詢的執行推到查詢執行層。
查詢執行層分為有狀態和無狀態兩種,分別處理與OLTP和OLAP相關的請求。共享存儲層Share storage針對工作模式和工作負載采取不同的存儲設計策略。在OLAP方面可以主打性價比,用對象存儲和糾錯編碼模式降低成本。AWS Redshift團隊的調研也表明,OLAP型的用戶會更加關注成本,所以在Share storage里OLAP方面可以偏向性價比的權衡。而OLTP數據存儲則采用高性能的存儲,優化事務提交的關鍵路徑,達到用戶最優體驗,比如說高性能Nvme,加速事務的提交速度,然后定期把數據從OLTP型存儲導入到OLAP型的存儲。
希望在不久的未來,可以看到相關廠商或數據庫開發者實現這樣的方案或技術特征。
4.總結
總體來看,HTAP已有的問題是OLTP和OLAP這兩種互斥的屬性,如何在一個系統里共存而干擾盡可能小,數據可見度延遲盡可能短。
目前存在兩種架構實踐:一種是One size fits all,用一個數據庫系統來滿足OLTP和OLAP多樣化工作負載的需求;對系統相關的架構革新,針對兩種工作負載的特性做更好的適配優化。另外一種是采用松偶合的方式,通過CDC把兩類系統黏合起來,在上面架構一個類似於proxy的東西,為用戶呈現出一個系統的表象,用戶感知不到OLAP型系統的存在。這種方案能更好地降低兩類工作負載對資源的競爭,但是由於需要跨系統進行數據同步因此延遲較大。而前一種方案雖然資源競爭比較大,但不需要對數據進行跨系統同步,因此延遲比較小,數據能見度、新鮮度高,可以滿足緊急型任務的需求。
展望未來,我們認為雲原生的彈性算力可能更適合HTAP系統,在雲原生上會誕生更優秀的HTAP系統。