需求起源
SelectDB 設計多計算集羣架構初衷主要源於兩類典型的使用場景:
- 寫入與讀取隔離:傳統數倉架構中,數據的寫入和讀取在同一個計算集羣,當遇到業務寫入高峯期或突增的寫入壓力時,容易因資源相互搶佔影響查詢服務的性能和穩定性。如果能引入多個計算集羣,通過獨立的計算集羣分別進行寫入、讀取操作,即使在寫入壓力非常高時,也可放心執行計算任務,無需擔心影響到服務的穩定性。
- 在線業務和離線業務隔離:大量數據分析場景會使用相同的數據支撐多個業務,比如某業務使用一份數據支持面向 C 端用户的數據查詢,另一個業務需要使用相同數據支持企業內部用户的運營分析等,這兩個業務對於服務的延時、可用性要求完全不同。傳統架構通常會把數據冗餘存儲到不同系統中,用於滿足不同業務的需求,但這會帶來冗餘數據的存儲成本和多套系統的維護成本。如果支持多計算集羣架構,可基於同一份數據拷貝,並使用獨立隔離的計算資源分別滿足在線和離線業務需求,便能為用户帶來可觀的成本節省和簡單的運維體驗。
SelectDB Cloud 是基於 Apache Doris 研發的全託管實時數據倉庫服務,採用全新的雲原生存算分離架構。當計算層與存儲層進行了分離設計後,計算層由於沒有了數據狀態,可支持極其靈活快速的彈性伸縮;而存儲層由於和計算解耦,可以極為方便的供多個計算資源進行共享訪問。因此,我們在 SelectDB 中引入多計算集羣能力,通過數據倉庫架構上的創新來更好地滿足用户需求。
初識 SelectDB 多集羣
在 SelectDB 的架構設計中,一個倉庫實例可包含多個集羣,類似分佈式系統中的計算隊列和計算組。數據持久化在底層的共享存儲中,多個集羣均可共享訪問。每個集羣本身即為一套分佈式系統,包含一個或多個 BE 節點。由於存算分離架構中遠程存儲訪問速度較慢,我們在計算節點本地引入了緩存,以加速數據訪問。
例如下面架構圖中,倉庫 1 中包含集羣 1、集羣 2、集羣 3,它們均可訪問存儲在共享存儲中的數據。
對於多集羣的使用方式,用户連接 SelectDB 倉庫實例後,可通過命令切換使用不同的計算集羣。一個使用多計算集羣進行讀寫分離的樣例如下:
-
通過 MySQL Client 連接 SelectDB,使用集羣 cluster_1 進行數據庫、表的建立。
# 切換使用計算集羣 cluster_1 USE @cluster_1; # 創建 database、table CREATE DATABASE test_db; USE test_db; CREATE TABLE test_table ( k1 TINYINT, k2 DECIMAL(10, 2) DEFAULT "10.05", k3 CHAR(10) COMMENT "string column", k4 INT NOT NULL DEFAULT "1" COMMENT "int column" ) COMMENT "my first table" DISTRIBUTED BY HASH(k1) BUCKETS 16; -
通過 Stream Load 方式,使用集羣 cluster_2 寫入樣例數據。
curl --location-trusted -u admin:admin_123 -H "cloud_cluster:cluster_2" -H "label:123" -H "column_separator:," -T data.csv http://host:port/api/test_db/test_table/_stream_load其中 data.csv 中的樣例數據如下:
1,0.14,a1,20 2,1.04,b2,21 3,3.14,c3,22 4,4.35,d4,23 -
通過 MySQL Client 連接 SelectDB,使用集羣 cluster_3 進行數據查詢:
# 切換使用計算集羣 cluster_3 USE @cluster_3; # 進行查詢訪問 SELECT * FROM test_table;
多集羣的核心設計
在雲原生存算分離架構下,多計算集羣的實現從技術方案上看似乎並不存在過多難題。但從產品的角度而言,具備成熟易用的多計算集羣能力且能運用於用户實際業務場景中,還有較多核心要點需要深度設計。 下面,我們對其中部分關鍵點進行介紹。
如何保證強一致的數據共享?
存算分離後,數據存儲在共享存儲中,可以供多個集羣訪問。在一個集羣寫入完成後,另一個集羣是否能夠立即訪問到數據? 如果不能,將會存在一定的數據延遲,對很多實時性要求高的業務場景來説,這種方案難以接受。
為了達到數據的強一致訪問,SelectDB 不僅實現了數據的共享化,也進行了深度重構,實現元數據的共享化:當數據通過其中一個集羣寫入共享存儲後,會先更新共享的元數據,再返回數據寫入結果。當其他集羣進行數據訪問時,可通過訪問共享的元數據中心獲取最新的數據信息,從而做到強一致的數據共享。這意味着通過任一個集羣寫入 SelectDB 中的數據,一旦寫入成功,其他集羣立即可見。
如何實現數據的多寫多讀?
基於共享存儲,數據的多讀是比較容易實現的,但寫入是否只能由其中一個集羣進行?如果只能通過其中一個集羣寫入,那該集羣是事先人工確定、出問題時人工變更所有寫入作業,還是引入分佈式鎖在多集羣之間進行協調、以決定哪個集羣來負責寫入?
更麻煩的是,當原寫入集羣處於假死狀態,可能出現多個集羣嘗試去寫入的衝突情況,解決這些問題會導致數據倉庫的架構複雜度大幅增加。因此關係型數據庫在探索了很多年後,大量系統仍採用一寫多讀的架構。
SelectDB 結合數倉場景的特點,進行了深度思考設計,可實現數據的多寫多讀,以簡化用户的運維過程、降低系統複雜度。具體而言,數倉場景通過採用小批量、多併發的寫入方式,來達到寫入的高吞吐,數據延遲達到秒級即可滿足大多數用户的需求,可以看到數倉的寫入事務併發不高,並無關係型數據庫每秒數十萬的事務併發需求。因此 SelectDB 可以基於數據的 MVCC 多版本機制,藉助共享的元數據中心進行事務協調,數據先提交多個集羣進行轉化處理,然後在更新元數據階段(生效數據過程)進行分佈式協調,先獲取到鎖的集羣寫入成功,其他集羣則進行重試。由於數據寫入的開銷主要在轉化處理過程,基於這樣的分佈式協調機制和樂觀鎖設計,實現多讀多寫能力的同時,也可利用多集羣進一步提升併發寫入吞吐。
如何實現靈活可控的緩存能力?
存算分離架構通常採用對象存儲或 HDFS 類系統作為遠端共享存儲,其單次 IO 請求的訪問性能較差,相比本地存儲性能下降數十倍。如何保障存算分離架構中計算集羣的查詢性能?進一步的,當採用多集羣支持讀寫分離、在離線隔離場景時,如何保證多集羣的查詢性能呢?
SelectDB 通過提供精心設計的緩存管理機制,可自動化保障存算分離架構的查詢性能,也可按需滿足用户靈活多變的調優需求:
- 對於單個計算集羣,SelectDB 默認會根據 LRU 策略進行數據緩存,當緩存大小足夠存儲全部熱數據時,即可保障存算分離類系統的性能追平存算一體類系統,由於本地緩存的單副本設計、遠端存儲的低廉價格,存算分離架構的存儲成本要大幅低於存儲一體架構。SelectDB 同時提供了手動的緩存控制策略,可通過手動策略保證某些表的數據優先存儲於緩存中。此外,當集羣進行彈性伸縮時,SelectDB 會自動基於統計信息,提前進行緩存的預熱或遷移,以保障變更過程中查詢服務平穩。
- 對於多個計算集羣,SelectDB 提供了提供了跨集羣的緩存同步能力,可同步已有集羣的緩存數據到其他集羣,從而加速查詢性能,並且支持分區粒度的緩存同步控制能力。每個計算集羣的緩存是獨立的,用户可根據需要按需控制緩存大小。
如何進行權限控制與資源隔離?
一個倉庫中的多個計算集羣之間,由於計算資源互相獨立,因此計算集羣間完全隔離。然而,當倉庫下有多個計算集羣可用時,如何避免用户誤用集羣,導致業務間的互相干擾?另外,由於存儲資源共享,其帶寬和 QPS 能力有限,如何保障一個集羣對共享存儲的訪問不干擾其他的集羣?
SelectDB 提供完整的權限控制與資源隔離的方案,來保障多計算集羣架構有條不紊的運行:
- 對於計算集羣的使用,SelectDB 提供一套簡單易用的權限機制,集羣支持類似庫表的權限分配機制,只有給用户分配了某集羣的權限,用户才可以使用該集羣,從而避免集羣誤用情況。
- 對於存儲資源的訪問,SelectDB 支持按照集羣規格,進行存儲帶寬和 IOPS 的限流控制,當超過限速後存儲訪問請求將進行排隊,以避免多個集羣之間互相干擾。
解鎖更多使用場景
多計算集羣架構的最初設計目標主要是為了滿足讀寫隔離、在離線業務隔離等場景應用。SelectDB 的多計算集羣方案上線後,有近半用户使用過多計算集羣,我們意外發現多計算集羣的應用潛力正在持續延伸:
- 彈性臨時集羣:在實際使用過程中,考慮業務隔離性,用户經常需要一個集羣用於臨時性業務,例如管理員保留一個隔離的測試集羣用於日常訪問、新功能正式發佈前建立完全仿真的集羣進行測試驗證、月底或臨時性的數據處理任務通過獨立的集羣進行等。為更好的滿足此類需求,SelectDB 也提供了一系列配套能力,如同一個倉庫同時支持包月和按量集羣的混合計費模式、按量集羣支持通過停止閒置計算資源來降低成本等。
- 跨可用區容災:當前部署架構中,元數據中心、共享存儲已支持跨可用區容災,用户完全可以通過把多集羣放置在不同可用區中,來完成全鏈路的跨可用區容災。由於請求的處理過程主要在一個集羣內部完成,跨可用區的訪問僅在少量元數據獲取過程,這種方案對查詢性能也基本無影響。當某個可用區出現故障時,可通過一條命令,快速把業務切換到其他可用區。
- 集羣切換式變更:當用户需要對集羣進行某些變更操作時,可通過雙集羣切換方式進行平滑變更。比如對集羣緩存資源進行縮容場景,由於目前集羣彈性功能不支持緩存縮容,用户可通過新建低緩存容量的集羣替換老集羣。另外,後續我們可支持雙集羣切換來進行 SelectDB 大版本的平滑升級,當升級過程中發現問題時可隨時安全回滾,保障大版本升級的穩定性,這也是一個極為重要的應用場景。
設計自省
在線上運營過程中,我們也在持續收集用户使用反饋、觀察用户使用卡點,其中有兩點設計引起了我們的反思,並正在進行設計上的優化重構:
- 集羣命名設計:對於大量雲上用户,已經建立實例和集羣的專有概念,集羣是用户購買在雲控制枱上購買的最小單元,在 MongoDB、Elasticsearch 等產品中,集羣通常等價於實例。而在 SelectDB 的架構設計中,倉庫或實例是購買的最小單元,集羣是倉庫內部的一組計算資源。這裏概念設計上的不一致,給不少用户帶來了理解上的麻煩。SelectDB 目前正在逐步調整系統架構中的概念,逐步把“計算集羣”引導為“計算隊列”、“計算組”等更貼切的概念。
- 默認權限策略:為避免集羣誤用導致多集羣之間互相干擾,SelectDB 提供了多集羣的權限控制能力,默認普通用户沒有集羣使用權限,需分配權限後方可使用。此類設計給新用户快速上手帶來了較大門檻,不少用户在剛開始使用時會發現無法查詢,也增加了僅僅使用單集羣時的使用成本。SelectDB 目前正在思考重新設計集羣權限部分,默認情況下用户擁有所有集羣的使用權限,而把多集羣的權限控制作為高階功能,交給用户按需開啓使用。