首次揭秘云原生Hologres存储引擎
概要:剛剛結束的2020天貓雙11中,MaxCompute交互式分析(Hologres)+實時計算Flink搭建的云原生實時數倉首次在核心數據場景落地,為大數據平臺創下一項新紀錄。借此之際,我們將陸續推出云原生實時數倉雙11實戰系列內容。本文將會首次對外公開介紹Hologres的存儲引擎,深度剖析其實現原理和核心技術優勢。
一、背景介紹
MaxCompute 交互式分析(Hologres)是阿里云自研開發的HSAP(Hybrid Serving/Analytical Processing)服務/分析一體化系統 ,融合了實時服務和分析大數據的場景,全面兼容PostgreSQL協議并與大數據生態無縫打通。它的出現簡化了業務的架構,與此同時為業務提供實時做出決策的能力,讓大數據發揮出更大的商業價值。關于架構更詳細的介紹,請看文末VLDB論文?。
跟傳統的大數據和OLAP系統相比,HSAP系統面臨下面的挑戰:
- 高并發的混合工作負載:HSAP系統需要面對遠遠超出傳統的OLAP系統的并發查詢。在實踐中,數據服務的并發遠遠超出OLAP的查詢。比如說,我們在現實的應用中見到數據服務需要處理高達每秒鐘數千萬個查詢,這比OLAP查詢的并發高出了5個數量級。同時,和OLAP查詢相比,數據服務型查詢對延遲有著更加苛刻的要求。復雜的混合查詢負載對系統的延遲和吞吐有著非常不同的取舍。如何在高效地利用系統的資源同時處理好這些非常不一樣的查詢,并且保證每個查詢的SLO是個巨大的挑戰。
- 高吞吐實時數據導入:在處理高并發的查詢負載的同時,HSAP系統還需要處理海量的實時數據導入。從傳統的OLTP同步過來的數據只是這其中的一小部分,其他還有大量的數據來自日志等沒有強事務語意的系統。實時導入的數據量遠遠超過了傳統的HTAP或者OLAP系統。和傳統的OLAP系統的另外一個區別是對數據的實時性有著很高的要求,導入的數據需要在秒級甚至亞秒級可見,這樣才能保證我們服務和分析結果的時效性。
- 彈性和可擴展性:數據導入和查詢負載可能會有突發的高峰,這對HSAP系統提出了很高的彈性和可擴展性的要求。在現實的應用中,我們注意到數據導入峰值能達到是平均的2.5倍,查詢的峰值可能達到平均的3倍。數據導入和查詢的峰值可能不一定同時出現,這也需要系統有根據不同的峰值做迅速調整的能力。
?
基于上訴背景,我們自研了一款存儲引擎(Storage Engine),主要負責管理和處理數據, 包括創建,查詢,更新,和刪除(簡稱 CRUD)數據的方法。存儲引擎的設計和實現提供了HSAP場景所需要的高吞吐,高并發,低延遲,彈性化,可擴展性的能力。根據阿里集團業務和云上客戶的需求,我們不斷創新和打磨,發展到今天,能支持單表PB級存儲,并完美支撐2020年天貓雙11核心場景千億個級別的點查詢和千萬個級別的實時復雜查詢 。
下面,我們將會對Hologres底層的存儲引擎做詳細的介紹,并介紹存儲引擎落地Hologres的具體實現原理和技術亮點。
二、數據模型
Hologres存儲引擎的基本抽象是分布式的表,為了讓系統可擴展,我們需要把表切分為分片(Shard)。 為了更高效地支持JOIN以及多表更新等場景,用戶可能需要把幾個相關的表存放在一起,為此Hologres引入了表組(Table Group)的概念。分片策略完全一樣的一組表就構成了一個表組,同一個表組的所有表有同樣數量的分片。用戶可以通過“shard_count"來指定表的分片數,通過“distribution_key"來指定分片列。目前我們只支持Hash的分片方式。
表的數據存儲格式分為兩類,一類是行存表,一類是列存表,格式可以通過“orientation"來指定。
每張表里的記錄都有一定的存儲順序,用戶可以通過“clustering_key"來指定。如果沒有指定排序列,存儲引擎會按照插入的順序自動排序。選擇合適的排序列能夠大大優化一些查詢的性能。
表還可以支持多種索引,目前我們支持了字典索引和位圖索引。用戶可以通過“dictionary_encoding_columns"和“bitmap_columns"來指定需要索引的列。
下面是一個示例:
這個例子建了LINEITEM 和 ORDERS兩個表,由于LINEITEM表還指定了主鍵(PRIMARY KEY),存儲引擎會自動建立索引來保證主鍵的唯一。用戶通過指定“colocate_with“把這兩個表放到了同一個表組。這個表組被分成24個分片(由shard_count指定)。 LINEITEM將根據L_ORDERKEY的數據值來分片,而ORDERS將根據O_ORDERKEY的數據值來分片。LINEITEM的L_SHIPINSTRUCT以及ORDERS的O_ORDERSTATUS字段將會創建字典。LINEITEM的L_ORDERKEY, L_LINENUMBER, L_SHIPINSTRUCT字段以及ORDERS的O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS字段將會建立位圖索引。
三、存儲引擎架構
1)總體架構
每個分片(Table Group Shard, 簡稱Shard)構成了一個存儲管理和恢復的單元 (Recovery Unit)。上圖顯示了一個分片的基本架構。一個分片由多個tablet組成,這些tablet會共享一個日志(Write-Ahead Log,WAL)。存儲引擎用了Log-Structured Merge (LSM)的技術,所有的新數據都是以append-only的形式插入的。 數據先寫到tablet所在的內存表 (MemTable),積累到一定規模后寫入到文件中。當一個數據文件關閉后,里面的內容就不會變了。新的數據以及后續的更新都會寫到新的文件。 與傳統數據庫的B+-tree數據結構相比,LSM減少了隨機IO,大幅的提高了寫的性能。
?
當寫操作不斷進來,每個tablet里會積累出很多文件。當一個tablet里小文件積累到一定數量時,存儲引擎會在后臺把小文件合并起來 (Compaction),這樣系統就不需要同時打開很多文件,能減少使用系統資源,更重要的是合并后, 文件減少了,提高了讀的性能。
在DML的功能上,存儲引擎提供了單條或者批量的創建,查詢,更新,和刪除(CRUD操作)訪問方法的接口,查詢引擎可以通過這些接口訪問存儲的數據。
2)存儲引擎組件
下面是存儲引擎幾個重要的的組件:
- WAL 和 WAL Manager
WAL Manager是來管理日志文件的。存儲引擎用預寫式日志(WAL) 來保證數據的原子性和持久性。當CUD操作發生時,存儲引擎先寫WAL,再寫到對應tablet的MemTable中,等到MemTable積累到一定的規模或者到了一定的時間,就會把這個MemTable切換為不可更改的flushing MemTable, 并新開一個 MemTable接收新的寫入請求。 而這個不可更改的flushing MemTable就可以刷磁盤,變成不可更改的文件; 當不可更改的文件生成后,數據就可以算持久化。 當系統發生錯誤崩潰后,系統重啟時會去WAL讀日志,恢復還沒有持久化的數據。 只有當一個日志文件對應的數據都持久化后,WAL Manager才會把這個日志文件刪除。
- 文件存儲
每個tablet會把數據存在一組文件中,這些文件是存在DFS里 (阿里巴巴盤古或者Apache HDFS )。 行存文件的存儲方式是Sorted String Table(SST) 格式。 列存文件支持兩種存儲格式: 一種是類似PAX的自研格式, 另外一種是改進版的Apache ORC格式 (在AliORC的基礎上針對Hologres的場景做了很多優化)。 這兩種列存格式都針對文件掃描的場景做了優化。
- Block Cache (Read Cache)
為了避免每次讀數據都用IO到文件中取,存儲引擎通過BlockCache把常用和最近用的數據放在內存中,減少不必要的IO,加快讀的性能。在同一個節點內,所有的Shard共享一個Block Cache。 Block Cache有兩種淘汰策略: LRU (Least Recently Used,最近最少使用) 和 LFU (Least Frequently Used, 最近不常用)。 顧名思義,LRU算法是首先淘汰最長時間未被使用的Block,而LFU是先淘汰一定時間內被訪問次數最少的Block。
3)讀寫原理
Hologres支持兩種類型的寫入:單分片寫入和分布式批量寫入。兩種類型的寫入都是原子的(Atomic Write),即寫入或回滾。單分片寫入一次更新一個Shard,但是需要支持極高的寫入頻率。另一方面,分布式批寫用于將大量數據作為單個事務寫到多個Shard中的場景,并且通常以低得多的頻率執行。
- 單分片寫入
如上圖所示,WAL管理器在接收到單分片寫請求后,(1)為寫請求分配一條Log Sequence Number (LSN),這個LSN是由時間戳和遞增的序號組成,并且(2)創建一條新的日志,并在文件系統中的持久化這條日志。這條日志包含了恢復寫操作所需的信息。在完全保留這條日志后,才向tablet提交寫入。之后,(3)我們會在相應tablet的內存表(MemTable) 中執行這個寫操作,并使其對新的讀請求可見。值得注意的是,不同tablet上的更新可以并行化。當一個MemTable滿了以后,(4)將其刷新到文件系統中,并初始化一個新的MemTable。最后,(5)將多個分片文件在后臺異步合并(Compaction)。在合并或MemTable刷新結束時,管理tablet的元數據文件將相應更新。 - 分布式批量寫入
接收到寫入請求的前臺節點會將寫請求分發到所有相關的分片。這些分片通過兩階段提交機制(Two Phase Commit) 來保證分布式批量寫入的寫入原子性。 - 多版本讀
Hologres支持在tablet中多版本讀取數據。讀請求的一致性是read-your-writes,即客戶端始終能看到自己最新提交的寫操作。每個讀取請求都包含一個讀取時間戳,用于構造讀的snapshot LSN。如果有一行數據的LSN大于snapshot LSN的記錄, 這行數據就會被過濾掉, 因為他是在讀的snapshot產生后才被插入到這個tablet的。
四. Hologres存儲引擎技術亮點
1)存儲計算分離
存儲引擎采取存儲計算分離的架構,所有的數據文件存在一個分布式文件系統(DFS, 例如阿里巴巴盤古或者Apache HDFS)的里面。當查詢負載變大需要更多的計算資源的時候可以單獨擴展計算資源; 當數據量快速增長的時候可以快速單獨擴展存儲資源。計算節點和存儲節點可以獨立擴展的架構保證了不需要等待數據的拷貝或者移動就能快速擴展資源; 而且,可以利用DFS存多副本的機制保證數據的高可用性。 這種架構不但極大地簡化了運維,而且為系統的穩定性提供了很大的保障。
2)異步執行流程
存儲引擎采用了基于事件觸發, 非阻塞的純異步執行架構, 這樣能夠充分發揮現代CPU多core的處理能力,提高了吞吐量, 支持高并發的寫入和查詢。這種架構得益于HOS(HoloOS) 框架,HOS在提供高效的異步執行和并發能力的同時,還能自動地做CPU的負載均衡提升系統的利用率。
3)統一的存儲
在HSAP場景下,有兩類查詢模式,一類是簡單的點查詢(數據服務Serving類場景),另一類是掃描大量數據的復雜查詢(分析Analytical類場景)。 當然,也有很多查詢是介于兩者之間的。這兩種查詢模式對數據存儲提出了不同的要求。行存能夠比較高效地支持點查詢,而列存在支持大量掃描的查詢上有明顯的優勢。
為了能夠支持各種查詢模式,統一的實時存儲是非常重要的。存儲引擎支持行存和列存的存儲格式。根據用戶的需求,一個tablet可以是行存的存儲格式 (適用于Serving的場景); 也可以是列存的存儲格式(適用于Analytical的場景)。 比如,在一個典型HSAP的場景,很多用戶會把數據存在列存的存儲格式下,便于大規模掃描做分析;與此同時,數據的索引存在行存的存儲格式下,便于點查。并通過定義primary key constraint (我們是用行存來實現的)用來防止數據重復·。不管底層用的是行存還是列存,讀寫的接口是一樣的,用戶沒有感知,只在建表的時候指定即可。
4)讀寫隔離
存儲引擎采用了snapshot read的語意,讀數據時采用讀開始時的數據狀態,不需要數據鎖,讀操作不會被寫操作block住; 當有新的寫操作進來的時候,因為寫操作是append-only,所有寫操作也不會被讀操作block住。這樣可以很好的支持HSAP的高并發混合工作負載場景。
5)豐富的索引
存儲引擎提供了多種索引類型,用于提升查詢的效率。一個表可以支持clustered index 和 non-clustered index這兩類索引。一個表只能有一個clustered index, 它包含表里所有的列。一個表可以有多個non-clustered indices。在non-clustered indexes里,除了排序用的non-clustered index key外,還有用來找到全行數據的Row Identifier (RID)。 如果clustered index存在, 而且是獨特的,clustered index key就是RID; 否則存儲引擎會產生一個獨特的RID。?為了提高查詢的效率,在non-clustered index中還可以有其他的列, 這樣在某些查詢時,掃一個索引就可以拿到所有的列的值了 (covering index)。
在數據文件內部,存儲引擎支持了字典和位圖索引。字典可以用來提高處理字符串的效率和提高數據的壓縮比,位圖索引可以幫助高效地過濾掉不需要的記錄。
五. 結語
存儲引擎的設計思路和研發方向是為了更好的支持HSAP的場景,能高效的支持高吞吐的實時寫入和交互式查詢,而且對離線的批量寫入做了優化。在寫入量和存儲量每年都成倍的增長下,Hologres經受住了嚴苛的考驗,完美地度過了多個雙11。 “Hologres頂住了5.96億每秒的實時數據洪峰,單表存儲高達2.5PB。基于萬億級數據對外提供多維分析和服務,99.99%的查詢可以在80ms以內返回結果”。這組數據充分顯示了存儲引擎的技術能力, 同時也印證了我們技術架構和實現的優勢。
當然,Hologres還是一個新產品,HSAP是個新理念, “今天的最好只是明天的開始”, 我們還在不斷地精益求精,聆聽客戶的反饋,今后會在穩定性,易用性,以及功能和性能上持續提升。
另,后續還會持續推出有關HSAP存儲引擎和其他核心系統的技術揭秘,敬請期待!
論文:《Alibaba Hologres: A cloud-Native Service for Hybrid Serving/Analytical Processing》。
作者:江淵,阿里巴巴資深技術專家,在數據庫和大數據領域有多年豐富的經驗。
原文鏈接:https://developer.aliyun.com/article/779284?
版權聲明:本文內容由阿里云實名注冊用戶自發貢獻,版權歸原作者所有,阿里云開發者社區不擁有其著作權,亦不承擔相應法律責任。具體規則請查看《阿里云開發者社區用戶服務協議》和《阿里云開發者社區知識產權保護指引》。如果您發現本社區中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社區將立刻刪除涉嫌侵權內容。總結
以上是生活随笔為你收集整理的首次揭秘云原生Hologres存储引擎的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 还在自建代码仓库?阿里云的这款企业级代码
- 下一篇: 智稳双全--AnalyticDB如何助力