日前,字節跳動技術社區 ByteTech 舉辦的第四期字節跳動技術沙龍圓滿落幕,本期沙龍以《字節云數據庫架構設計與實戰》為主題。在沙龍中,字節跳動基礎架構數據庫開發工程師劉輝聰,跟大家探討了 《字節云數據庫未來方向的探索與實踐》,本文根據分享整理而成。
字節云數據庫概覽
字節云數據庫架構分為四層,示意圖如下:
DBEngine 層:我們對外會提供完備的數據庫,兼容全面的數據庫生態,包括 Mysql、PG、ES、Mongo 等;同時我們也支持混合負載,即 HTAP。
DB-Cache 層:這一層會存儲兩類數據,一類是日志流,另一類是用戶數據的緩存。我們在這一層引入一些新的硬件進行加速,為用戶提供極致的性能體驗。
DB-Store 層:這一層是低成本、跨 AZ、多格式的 DB-Store 層,用于存儲用戶數據。DB-Store 層是一個分布式的存儲平臺,它支持插件式的存儲格式,比如 veDB 中的行存格式、 ByteHTAP 的行列混合格式;它也支持 Segment 級別的 PITR 特性,提高數據的可用性;它還支持壓縮 和 Tail Segment 的特性,來極致降低存儲成本。
Store 層:這一層是冷數據存儲層,用于存儲備份數據或者分層的冷數據。
Severless:目前 veDB 部署在字節內部虛擬機上,同時我們支持在火山引擎上進行容器化部署。我們希望通過當前正在探索的 Serverless ,為用戶提供 pay by usage 的計費模式,提供自動 scale up 和 scale down 能力,來充分提高空閑資源的利用率。
Brian:這是數據庫的“大腦”,負責提供 AI 能力。
字節云數據庫架構的特點是支持三個分離,一是存儲與計算的分離,二是日志和數據的分離,三是緩存與計算的分離。
A-Store For veDB 探索與實踐背景
業界的很多產品證明了 veDB 云原生數據庫架構具有著強大優勢,如下:
- 極致彈性,存儲計算按需擴展,這是存儲和計算分離帶來的核心優勢,使得云原生數據庫在對外提供良好的兼容性同時提供良好的擴展性;
- 支持存儲層多租戶共享,能夠極致提高存儲資源利用率;
- 計算層超分超賣,提升計算利用率。
但是這種存儲與計算分離的架構也有一定的劣勢:
- 計算存儲間延時增加;
- Local: 100us VS Remote: 1-5msdryme。
存儲和計算分離后,我們將存儲拉到遠端的分布式存儲系統上,會導致計算和存儲之間的延時增加。之前 MySQL 在本地訪問 nvme,訪問時間大概在微秒級別,但是經過網絡延時后,訪問時間在毫秒級別。因此我們提出一個設想,是否有一個能和本地 NVME-SSD 同樣快且穩定的存儲層?新硬件的持久化內存和 RDMA 的出現為上述設想提供了可能。
Persistent Memory
在過去幾十年間,計算機系統已經實現了如下金字塔型存儲結構。
金字塔上層是易失存儲,容量小,延時低;金字塔下層是非易失存儲,容量大,延時高。對于 DRAM 及以上的易失存儲,CPU 可以通過 Load 和 Store 指令直接訪問,響應時間大致在幾十納秒到 100 納秒級別。對于 SSD 及以下的非易失存儲, CPU 就無法直接訪問,企業級 SSD 的響應時間可以達到 10 微秒到 100 微秒的級別。由此可以看出 SSD 和 DRAM 之間存在差不多 100 多倍的性能差距,在訪問時延上存在一個很大的跳變,但是持久化內存的出現彌補了它們之間的性能鴻溝。
持久化內存(PMEM)位于 DRAM 和 SSD 之間,它具有以下幾個核心的特性:
- 非易失性:持久化內存具備硬盤的特性,即掉電重啟,內存中的數據依舊存在;
- 字節可尋址;
- 大容量:對于單臺服務器,持久化內存容量可以達到 TB 級別;
- 低延時。
在數據庫領域,持久化內存目前主要有兩種使用模式,模式一:將其作為一個單機的持久化層,用來加速單個計算節點的性能;模式二:把它拉遠做一個分布式的持久化池。作為 veDB 產品的擴展,字節數據庫團隊在架構上是將 PMEM 作為分布式的共享存儲池,用于加速 veDB 的性能。相對于第一種單機模式,拉遠的存儲池存在一個缺陷:它仍舊需要通過網絡來訪問,性能低于單機的持久化內存。但是 RDMA 的出現能夠有效彌補該缺陷。
RDMA
RDMA 是一種遠程直接內存訪問的技術。在傳統的 TCP/IP 協議中,數據傳輸時會經過多次的數據拷貝,以及經過 CPU 的內核上下文切換。數據需要經歷從用戶態到內核態,從內核態再拷貝到網卡。同時,TPC/IP 協議會有一些處理開銷,包括 Buffer 管理,協議棧管理,以及發送完之后系統中斷引起的開銷。RDMA 技術能夠幫助計算機直接存取另外一個計算機的內存。
RDMA 具有以下三個核心優勢:
- 零拷貝(Zero-Copy):應用程序能夠直接執行數據傳輸,不需要經過多次數據拷貝,就能直接發送到遠端的計算機內存中去;
- 內核旁路(Kernal bypass):應用程序直接可以在用戶態執行數據傳輸,不用經過用戶態到內核態的上下文切換;
- 不需要 CPU 干預(No CPU invovlement)。
基于以上 PMEM 和 RDMA 的新硬件加持,存儲系統能夠提供極低的延時,非常適用于對性能要求很高、容量無需很大的場景,比如存儲系統中的 Cache、WAL 日志、內存數據庫等。
A-Store 架構
基于 AEP + RDMA 硬件,數據庫團隊設計了分布式、高性能存儲系統——A-Store。A-Store 對外提供的語義是 Append-only 寫接口和隨機讀,支持 RDMA 單雙邊的消息。
從圖中可以看出,A-store 架構包含三個模塊:
- AEP-SDK 模塊: SDK 會作為一個庫,連接到計算層的比如 veDB 的 DB Engine 中去,成為一個 IO 入口;
- AEP-Server 模塊:它是一個單獨的進程,部署在某個存儲節點上,就負責管理該節點上所有 AEP 的介質以及后臺任務;
- 集群管理模塊:這個模塊復用了 veDB 存儲層的集群管理模塊,對其進行了一些適配和修改,主要負責數據分布、節點故障發現、元數據的持久化。
最后,A-store 架構具有三個核心特點:一是高性能,硬件直通設計,旁路 Server 軟件棧,IO 路徑是完全無鎖化的設計,也沒有拷貝;二是分布式,底層的 Server 層可以擴展;三是高可用,存儲在 AEP-Server 的數據,一般都支持多副本部署,目前我們一般部署三副本,保證數據的高可靠性。
A-Store 應用
A-Store 主要有以下兩個應用方向:
- 緩解 veDB 存儲拉遠對性能的影響:veDB 存儲拉遠具體拉遠了哪些數據?比如在 MySQL 系統里通常會有兩類數據:Redo 日志和用戶數據,我們就將這兩類數據拉遠,此時我們通過 A-Store 加速這兩類數據訪問速度,因此 A-Store 的第一個應用是用于 Redo 日志加速。第二個應用是 Extend Buffer Pool。
- 特性增強:我們正在開發一款基于 A-store 的高性能存儲引擎, MemTable。
A-Store For Redo Log 加速
在之前的 veDB 部署中, Redo 日志是通過 Logstore 的組件,將數據寫到了遠端的 Append only 的分布式系統。當我們引入 A-Store 之后,我們將會替代原來的 Logstore 的組件,將 A-Store 的 SDK 集成到 DB Engine 內部。相比之前的 Logstore 實現,A-Store 具有兩個優勢:
- 無數據拷貝:在之前 Logstore 的實現里,除了有 TCP IP 的網絡拷貝,從用戶態到內核態的拷貝之外,在軟件棧上也有多次數據拷貝。使用 A-Store 能夠完全去掉這種內存拷貝, DB Engine 直接把 Redo 日志寫到 RDMA 注冊的內存上去,無需任何的數據拷貝;
- 無線程切換:在之前 Logstore 的實現里,我們會有多次的線程切換,從 DB Engine 的 Log writer 線程,切換到 Logstore 線程里去。使用 A-Store 之后,我們可以直接在 Log writer 的線程里調用 A-Store 接口,無需任何軟件棧的處理,就能夠直接寫到遠端的 AEP Server 上去。
Redo 日志的寫速度,對于寫負載是非常重要的。在我們目前的測試中,替換成 A-Store 之后,對于純寫的場景,性能能夠提高 20% -30%;線上真實 Workload(write-heave),性能提升 2 倍+。
A-Store For Extend Buffer Pool
原生的 mysql 處理查詢都是單線程的處理模型,訪問數據時都要先去判斷數據是否在 Buffer Pool 中,如果不在,我們需要通過同步的接口把數據從遠端存儲拉到 Buffer Pool。如果數據沒有命中 Buffer Pool,比如數據量很大,Buffer Pool 線上最多開 100 G ,對于用戶的請求,請求延時就會增加。為了緩解拉取遠端存儲的性能下降問題,我們擴展了原生的 Buffer Pool 設計,將 A-Store 作為一個遠程分布式的二級緩存,來擴大緩存空間的大小。它的一個主要優勢是:延時更低,容量更大。
除此之外,A-Store 還提供 Hot 特性。主節點在故障宕機,進行主備切換之后, 備機可以直接使用遠端 AEP Buffer pool 的數據,縮短冷啟動時間。我們在純讀、純寫的場景下都進行了測試,性能提高 30% - 70% 左右。
MemTable For veDB
第二個應用方向是提供特性增強。字節未來的發展方向是提供數據庫的縱向融合探索,重塑應用緩存和數據庫之間的邊界。基于 A-store 設計,我們正在開發一款內存數據庫引擎 MemTable,對外兼容 SQL 協議。
MemTable 架構
MemTable 架構也采用計算與分離的思路,中間通過 RDMA 進行通訊,它與當前的 veDB 存在幾點不同。一是,MemTable 在計算層引入編譯執行技術來大幅度提高 SQL 的執行速度;二是存儲和事務的處理與 InnoDB 不同:在索引結構上,我們目前采用 ART 索引結構;另外我們采用 MVOCC 并發控制算法進行事務控制;最后我們采用 Record 粒度的數據組織格式。
MemTable for veDB 架構
MemTable 出現之后,veDB 的整體架構如上圖所示,MemTable 將作為 MySQL 的插件式存儲引擎。同時,它會與 InnoDB 形成互補,InnoDB 可以滿足業務容量型需求,MemTable 則可以滿足業務高吞吐低延時需求,預計性能可以達到 InnoDB 的 10 倍 +。
ByteHTAP 探索與實踐
背景
HTAP 概念早在 2014 年由 Gartner 提出。HTAP 強調以下兩個核心理念:
- 打破 AP(Analytical Processing) 和 TP(Transaction Processing)系統中間的墻:在數據庫發展最初階段,其實存在只有一個系統,不用區分 TP 和 AP 。伴隨著數據量的增長,單個系統內部沒法既支持 TP 又支持 AP, 因此發展出兩個方向 OLTP 和 OLAP 。HTAP 的出現能夠打破 TP 到 AP 之間的墻,在一個系統中同時去支持這兩類負載。
- 實時性:伴隨著互聯網的發展,互聯網企業的數據呈現爆發式增長。TP 和 AP 的用戶 pattern 是完全不同的——TP 的 pattern 一般是命中二級索引的簡單類查詢,再加上一個增、刪、改的高頻更新操作,但是 AP 系統處理的都是一些復雜的查詢。這兩種 Workload 本身是非常不同的,所以如果在一個系統里,數據量比較大的前提下去支持這兩類負載,基本不太現實。目前許多公司都有兩套系統, TP 和 AP 系統,而這樣的架構會帶來三個問題:一是,實時性要求。數據產生在 OLTP 系統里,然后經過 ETL 的清洗流入到數據倉庫之后,數據通常會存在分鐘級甚至小時級、天級的延時。二是,數據一致性的要求。當前許多用戶的使用場景都是把數據從 TP 的系統導入到 AP 的系統,在多個系統之間維護一致性非常困難;三是,成本,包括人力/硬件成本。
以上是業界提出 HTAP 的背景,在字節跳動,我們希望進行橫向融合探索,通過對外提供 everything is SQL 的接口;在內部,不管是 TP 還是 AP,PG 還是 MySQL,通過設置統一的處理層來簡化業務應用數據管理體系。
架構
ByteHTAP 架構主要基于以下三個核心目標進行設計:
- 實時查詢(時延 < 1 sec):用戶希望在 AP 側實時看到 TP 側引入的數據修改,延時小于 1 秒鐘,該目標對于用戶十分重要。比如字節跳動的用戶增長部門就需要在數據不斷變化的同時,對其進行復雜的查詢;廣告、商業分析的用戶也希望能夠在秒級的范圍內對修改的數據進行應用。
- 強一致性(SI 隔離級別):實時分析的數據集支持強一致性,為用戶提供 snapshot 隔離級別,大大簡化用戶對一致性的處理成本。
- 高性能(更新/復雜查詢)。
整體架構
基于以上核心目標,數據庫團隊設計了如下的 ByteHTAP 整體架構。
目前業界存在很多 HTAP 產品,比如 Memory SQL 系統 、HANA 系統、還有在 TP 系統中擴展 AP 能力、或者在 AP 系統中擴展 TP 能力。2017 年 ACM 發表的一篇關于調研 HTAP 的論文將 HTAP 大致分為了兩類,第一類是 Single Engine 系統,這類系統有一個統一的查詢處理引擎,比如 Memory SQL 系統。第二類 Separate Engine 系統,這類系統使用分開的查詢處理引擎進行 TP 和 AP 的處理。對于 ByteHTAP 而言,它具有以下三個核心特性:
- 一是:TP/AP 引擎分離。ByteHTAP 系統使用的是分開的查詢處理引擎來處理 TP 和 AP,這么做帶來的好處是我們可以在字節內部或者是在開源的成熟產品里面選擇兩個不同的 TP 和 AP 系統來分別支持 Query Processing 的處理。這種處理對于用戶來說是透明的,我們對外會有一個智能代理層,它會自動將用戶的請求路由到 TP 系統或者 AP 系統。
- 二是:計算存儲分離。ByteHTAP 基于 veDB 擴展,使用 veDB 系統作為 OLTP 的引擎,它的一個核心組件是分布式日志框架,用來負責將日志復制和分發到底層的數據存儲頁面 PageStore 上。同時,在 ByteHTAP 系統中,數據庫團隊擴展了分布式日志框架,日志不僅能夠被分發到 PageStore,還能夠被分發到 HTAPStore。上層架構了 Query Processing,目前 Query Processing 采用的 Apache Flink 實現。
- 三是:共享行列存儲平臺。ByteHTAP 的另一個核心組件是 Meta Data Service,用來存儲 AP 系統的元信息,包括元信息的定義,統計信息,以此輔助用戶查詢。
關鍵技術點
數據庫團隊分別根據三個核心目標研發了對應的核心技術。針對實時查詢,我們提供了以下三個核心技術,達到時延 < 1sec 的目標:
- 引入輕量級的 Log Parser 設計。在 HTAP 系統里,我們復用了 veDB 中高效的日志復制框架,基于 column 協議對日志進行分發,避免寫入的一個長尾時延;其次如果日志有空洞,可以采用 gossip 協議進行補洞;我們設計了一個輕量級的 Log Parser 機制,按需解析字段并進行分發。
- 分布式并行 Apply。用戶在創建表時可以根據需求定制自己指定的分片策略。隨后,日志復制框架會將日記分發到存儲系統上,各個分片可以進行分布式并行 Apply 。
- In-memory Delta Store + Persistent Base Cloumn Store。該技術是針對存儲的,我們在存儲層采用一個 In-memory Delta Store,它是一種行存格式,以及 Persistent Base Cloumn Store,它是行列混合的存儲格式,用來加速 Apply 、Flash、 Compaction 流程。
針對強一致性,涉及以下三個核心技術點,實現 SI 隔離級別:
- 事務原子性更新可見點。我們實現了基于 lsn 的多本管理機制,我們在 AP 系統使用的日志是在 TP 系統里事務提交時產生的邏輯日志,所以事務原子性得到天然保障。我們為日志賦予了一個全局版本號,會原子地去更新版本號。
- 數據多版本。DataStore 支持多版本,每個用戶在查詢時都會攜帶一個全局一致的版本號,然后發送到 HTAPStore 上去,HTAPStore 會基于他的版本號給對應的數據。
- 元信息多版本。Meta Data Service 的元信息支持多版本存儲。HTAPStore 在進行日志回放時,會從邏輯日志里解析 DDL ,Meta Data Service 會拿到 DDL 的變更。
最后針對高性能,涉及以下三個核心技術點,實現更新/復雜查詢:
- 使用分布式計算引擎,提高執行效率。
- 支持算子下推,比如 Filter 算子、聚合算子都可以下推到 HTAPStore 上。
- 高效的數據導入。目前我們開發了一個快速導入的工具,該工具可以幫助我們從 veDB 的 TP 系統拿到一個一致性的點,直接進行數據頁面的解析和寫入,將解析出來的數據以批量的方式直接寫入到 BaseStore,大大提高數據遷移的速度。
應用
ByteHTAP 可以被應用到以下兩個典型應用場景:
- 用戶需求是實時性:投放分析師需要實時調整投放計劃,在使用 ByteHTAP 之前,實時性基本上是小時級,當系統切換到 ByteHTAP 之后,實時性可以達到秒級。
- 用戶需求是高性能查詢:之前數據主要存儲在 MySQL 上,人力科技做數據匯總查詢比較復雜。在使用 ByteHTAP 之后,用戶將系統遷到 veDB 上, TP 側用來作為用戶的寫入,ByteHTAP 一側用來作為用戶的查詢,性能提升從 10 分鐘級降到秒級。