SQL Server內置的HTAP技術

SQL Server內置的HTAP技術

目錄

  • 背景
  • SQL Server在OLAP上的發展
  • SQL Server的初代HTAP
  • SQL Server逐漸增強的HTAP
  • SQL Server列存總結
  • HTAP發展

 

 

 

背景

2005年,Gartner正式提出了HTAP這一概念,並且迅速引起了一些企業的關注,被視爲是未來數據發展的重要趨勢之一。

到了2014年,Gartner又對HTAP數據庫給出了明確的定義:混合事務/分析處理(HTAP)是一種新興的應用體系結構,兼容兩種業務場景。

混合負載(HTAP Hybrid Transactional/Analytical Processing)是在保留原有在線交易功能的同時,強調了數據庫原生計算分析的能力。

HTAP體系架構解決的一個問題是 傳統的數據倉庫做數據分析的時效性問題,傳統數據倉庫架構需要用ETL工具從各種業務數據源(oltp)抽取數據到數據倉庫(olap)進行跑批分析,這個時效大概是T+1。

傳統數據類項目,如數據倉庫、數據集市等其他數據應用類項目有跑批日期的概念,即在T+1日跑T日的交易數據,直白的說就是在第二天跑昨天的交易。

T指的是每天或者每一個交易日,我們經常說的跑批日期也是T日的數據。

無論是過去的傳統數倉,還是現在的大數據技術棧,都存在這個時效性問題。HTAP體系架構的做法是,同時支持OLTP和OLAP場景,基於創新的計算存儲框架,在同一份數據上保證事務的同時支持實時分析,省去費時的ETL過程。

 

 

 

SQL Server在OLAP上的發展

過去,SQL Server自帶完整的數倉服務套件 ,方便用戶搭建傳統數倉,SQL Server企業版和數據中心版本身提供了三個服務

  • 做數據ETL的SQL Server集成服務(SSIS)
  • 做報表的SQL Server報表服務(SSRS)
  • 做數據多維分析的SQL Server 分析服務(SSAS   olap引擎)

相信大家在SQL Server安裝界面看到過上面幾個服務的安裝選項。

後來,爲了處理更大的數據量,微軟推出SQL Server並行數據倉庫(PDW),使用多個SQL Server數據庫服務器在大規模並行處理架構下存儲和處理數據。

再到最近十年,隨着大數據技術棧發展迅猛,微軟推出PolyBase用來整合SQL Server和Hadoop。

但是,以上技術還是需要ETL過程,存在時效性問題。

 

 

SQL Server的初代HTAP

初代HTAP首次出現在SQL Server2012版本,最初設計的目標,僅僅爲了在OLTP中提供數倉場景下的OLAP能力,讓用戶可以直接在一個DBMS的行存表上建列存索引然後執行分析型負載,省去費時的ETL過程。

面對這樣的目標,SQL Server2012提供的是一個面向OLAP的列存引擎,對應上層的接口就是Read-Only Columnstore Index,即在一個行存表上建立列存索引之後,這個表變爲只讀。

列存的存儲格式很簡單,每100萬行組成一個Row Group,Row Group中每一個字段組成一個Column Segment,每個Column Segment的元數據存儲在系統表中。列存索引只提供全表掃描。

 

圖3-1

這樣的設計,有兩個問題:

  1. 整個表都不支持更新,只讀狀態
  2. 列存索引只能是非聚集列存索引,不能是聚集列存索引

 

 

SQL Server逐漸增強的HTAP

到了SQL Server2014和SQL Server2016這兩個版本,微軟逐漸增強了列存引擎的能力,解決了初代HTAP的兩個缺點,開始支持更新,並支持表中只有列索引一份數據即聚集列存索引。

這時候,一個數據庫融合了3種存儲引擎,分別是:

  • Apollo引擎:列存引擎,面向olap
  • 傳統引擎:行存引擎,面向oltp,B+樹或堆結構
  • hekaton引擎:純內存行存引擎,面向oltp ,bwtree結構

 

圖4-1

圖4-2

 

爲了支持更新,SQL Server引入了delta store、delete flag、rowid。

Delete Flag

在列存索引裏刪除一行數據時,實際上只是對這行數據加一個delete flag標記(bitmap標記),並不會物理刪除這行數據

 

Delta Store

是相對磁盤上的列存Main Store來說的,用於緩存Insert。

Delta Store由Delta rowgroup實現,所有Delta rowgroup都統稱爲Delta Store,有些文獻也叫tail index(下文中Delta Store 和 Delta rowgroup是同一個意思)

所有的rowgroup也統稱爲Main Store(下文中Main Store 和 rowgroup是同一個意思)

Delta Store在結構上是聚集 B樹索引,提供熱數據的原地更新刪除,爲Main Store做緩衝。

 

RowID

由列存引擎生成,用來在列存索引中唯一標記一行數據。

列存rowid在數據行插入到rowgroup時候生成,這個rowid一直到數據行被刪除都不會改變。

當行存和列存組合時,需要在行存添加一個字段來存儲這個列存rowid,這樣來使列存和行存通信。

 

行存中存儲全量數據,列存分爲Delta Store和Main Store,其中Main Store以列存的形式存儲絕大部分數據,以Row Group爲單位劃分,每個Row Group對應行存中一定數量的記錄。

假設用戶建了一個行存索引和列存索引組合的表,事務插入數據時,會同時插入行存和Delta Store,Delta Store達到100W行閾值後凍結,會將其中較冷的數據遷移到Main Store,

冷熱通過統計信息來判斷。遷移過程中也會由新的Delta Store來緩存Insert。

遷移分爲兩個階段:

  • 第一階段:在一個事務中完成,將Delta Store冷記錄遷移到Main Store,在Main Store中把遷移過來的冷記錄標記delete flag刪除並分配RowID。事務提交後遷移的部分在列存索引中不可見,但在Delta Store中依然可見,數據是一致的,這時Delta Store中冷記錄並沒刪除。
  • 第二階段:在一些小事務中完成,每個事務將第一階段遷移的冷記錄從Delta Store中刪除,一個事務刪一條記錄,將對應的RowID更新到行存,並在Main Store中刪除這條記錄通過delete flag標記,事務提交後這條記錄在列存索引中可見,但在Delta Store中不可見,數據也是一致的。

SQL Server從兩個方面來減少數據遷移對行存性能的影響

  • 第一方面:第二階段更新行存中RowID時不記日誌,數據庫故障恢復時通過掃描列存重建行存RowID,減少日誌開銷。
  • 第二方面:第二階段每個事務只處理一條記錄,減少與前臺事務的寫-寫衝突(將對應的RowID更新到行存,如果有別的前臺事務也要update行存的這條記錄,會造成寫-寫衝突)。

 

 

事務刪除數據時,如果記錄在Delta Store中,則直接在行存和Delta Store中刪除,如果記錄在Main Store中,則需要根據行存中存儲的RowID在Main Store中通過全表掃描把對應記錄通過delete flag標記刪除。

爲了優化全表掃描刪除的性能,SQL Server引入了Delete Buffer,將多個刪除緩存,然後在一次全表掃描中批量刪除

 

圖4-3

圖4-4

 

Main Store中標記刪除的記錄太多也會影響scan的性能,也會帶來額外的內存開銷,因此需要進行重整。

列存索引的重整由Row Group中標記刪除的比例觸發(90%),由後臺任務將觸發重整的Row Group中的有效記錄重新插入Delta Store中,而重整的Row Group則被tuple-mover後臺線程回收。

 

 

事務更新數據時,通過先刪除 + 後插入實現,上文已經說了刪除 和插入的實現方式,這裏不再敘述。

 

事務查詢數據時,列存引擎需要掃描Main Store,並根據delete flag剔除已刪除數據,當第一次建列存索引時,列存引擎還需要通過Delta Store從行存表中獲取未遷移到Main Store的數據,

然後利用bulk load,把未遷移到Main Store的行存數據不經過Delta Store直接遷移到Main Store。

 

圖4-5

 

 

 

SQL Server列存總結

在概括SQL Server列存設計的優缺點之前,首先要看下數倉場景下更新的特點,這會影響到整個存儲設計。

數倉場景下更新的特點,更新中絕大部分的是Insert,只包含極少數的Update和Delete。

並且列存中原地Update的成本很高,所以Update的實現一般是一次Delete加上一次Insert。因此支持更新實際上只需要考慮Insert的性能,Delete的性能並不是很重要。

現在大部分的列存引擎普遍都會選擇Delta-Main架構,因爲本身按列存儲就不利於更新,因此需要使用Delta緩存架構來解決更新的問題。

 

SQL Server列存的優缺點

優點:

  • 通過引入delta store、delete flag、rowid,讓列存索引以append-only的方式更新,保證跨行存和列存索引上事務的ACID。

缺點:

  • 插入數據到列存、Row Group重整、更新列存數據帶來一定開銷,這個開銷就是都需要更新行存中的RowID,因此都會和行存的OLTP事務產生競爭,影響系統整體性能,這個是SQL Server行存和列存緊耦合導致的。

 

根據數倉場景的特點,SQL Server列存的開銷其實可以接受,然後使用類Delta-Main架構也是比較主流的做法,但是到了HTAP的場景,整個數據庫需要支撐高併發的查詢和更新,列存的開銷就會被放大。

在這方面,SQL Server也提供了很多優化方案,比如使用Mapping Index來減輕更新行存中的RowID的開銷問題。

 

有同學會問SQL Server2014開始支持聚集列存索引,整個表只有一個列存索引作爲primary index,就不會有更新行存RowID這個開銷,但是數據庫一般也需要唯一約束、外鍵約束等,要維護這些約束就需要行存B樹索引來輔助。

所以,最後還是要行存和列存組合來使用。

 

 

 

HTAP發展

最後,從SQL Server的發展來看,一份表數據兩種存儲格式,兩種存儲引擎處理,查詢時優化器自動選擇存儲引擎執行,對用戶透明,這些特性讓SQL Server走在了前列

當然,其他商業數據庫和開源數據庫也在向HTAP方向發展,例如Oracle、GreenPlum、SAP HANA等等

還有,兩大開源國產數據庫代表PingCAP、OceanBase,在成立之初就定位爲新一代分佈式的HTAP數據庫,通過行存和列存松耦合來解決性能問題,新型的分佈式架構確實比傳統數據庫更勝一籌。

 

 

 

本文版權歸作者所有,未經作者同意不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章