騰訊遊戲 :我們如何基於 StarRocks 構建雲原生數倉

語言: CN / TW / HK
StarRocks 社群說
開源運動旗手 Eric S. Raymond 在《大教堂和集市》中說,一個專案若想成功,“要將使用者當做合作者”。這也一直是 StarRocks 社群的理念。對於 StarRocks社群,騰訊遊戲公共資料平臺部既是 StarRocks 社群的使用者,也是合作者。他們為騰訊數百款遊戲提供基礎的資料平臺支撐,業務環境複雜,技術元件多樣。
他們在資料分析加速專案中,經過多方的技術棧選型,引入 StarRocks 作為資料分析平臺的引擎底座。同時,在和 StarRocks 社群的不斷溝通設計討論中,他們為社群貢獻了一套全新的 Serverless 存算分離方案,已完成第一版開發測試和程式碼合入社群主幹的工作,並開始在騰訊遊戲內部業務落地。
360、歡聚時代、遊族等 StarRocks 社群成員對該方案特性也非常認同,接下來會一起參與方案的社群共建及優化落地,推動 StarRocks 在雲原生數倉方向的持續演進。非常感謝騰訊遊戲公共資料平臺部在 StarRocks 社群的大力支援和投入!

騰訊遊戲 :我們如何基於 StarRocks 構建雲原生數倉

作者:騰訊遊戲公共資料平臺部基礎資料平臺團隊
 

一、業務場景和痛點

騰訊遊戲公共資料平臺部為騰訊數百款遊戲提供基礎的資料平臺支撐,利用資料科學的方法,助力遊戲在商業化、遊戲品質和渠道效率層面進行提升。騰訊遊戲業務的品類和產品數量多,環境複雜。面對日新增資料量在百 T 萬億條級的挑戰,資料分析平臺不僅僅要滿足活躍、付費、新增等基礎使用者行為指標的分析,也要處理各種遊戲內的複雜資料,包括對局數、道具產出、消耗等對局情況。同時還需要基於海量使用者和資料進行分群、圈選等運營支援。業務的發展給資料分析帶來了三大挑戰:
  1. 遊戲業務對實時分析的需求越來越強烈,需要多維度、更及時的資料來支撐遊戲運營決策,希望能夠將實時和離線業務統一分析。
  2. 原有的解決方案依賴元件較多,架構偏複雜,運維難度大。
  3. 叢集的資料量和計算量的增長並不完全匹配,對計算和儲存的彈性要求越來越高。
經過選型評估,我們最終選擇了 StarRocks 作為資料平臺的底座,並且和 StarRocks 社群一起討論設計了一套全新的 Serverless 存算分離方案,目前已經完成了第一版本的開發測試工作。基於騰訊雲 Kubernetes(TKE)及物件儲存(COS) 平臺的 StarRocks 存算分離方案,目前已上線平穩執行。團隊同時也在公司內參與騰訊大資料技術委員會領導的天穹 Oteam(詳見 Part 5)開源協同建設,積極推動 StarRocks 成熟能力融入騰訊大資料體系之內。
 

二、StarRocks 存算分離方案

存算分離的想法提出

為了簡化騰訊遊戲公共資料平臺技術棧,提高查詢效率,我們從不同維度進行了技術棧的篩選:
  • 架構簡潔,資料自動均衡,確保運維複雜度不會太高
  • 查詢高效,秒級響應,提供極速的即席查詢體驗
  • 函式豐富,能夠為業務提供 UDF 函式支撐
  • 穩定支援實時和離線的資料來源匯入,支援流批一體架構
  • 架構擴充套件性強,存算一體的架構能通過定製擴充套件實現存算分離
在經過一系列的對比後,我們選擇 StarRocks 作為分析平臺 OLAP 儲存引擎,並決定與 StarRocks 社群合作,將計算層從 BE 節點剝離,形成存算分離的結構。
在當前 StarRocks 的存算一體架構中,BE 既作為儲存節點,也作為計算節點負責執行查詢計劃任務。隨著接入業務查詢分析場景越來越多,定位發現很多查詢的瓶頸並不在 IO,而是在計算(CPU 和記憶體)。因此,如果我們希望提升使用者體驗,就只能選擇加 BE 節點。但是 BE 節點本身又是帶儲存的,不僅擴容時會帶來資料遷移,而且擴充的儲存資源也是一種資源浪費。同時,針對不同的查詢分析場景,如 SQL 相對固定的報表分析以及自定義 SQL 查詢,二者之間能進行節點的隔離,避免相互影響。
綜合上面兩點需求,我們認為需要對 BE 節點進行改造,實現了純計算節點 CN(Compute Node)以及 BE 資料的資料下沉,來構建存算分離後的 StarRocks 的 Serverless 架構。
在拆分了儲存層與計算層後,我們選擇 Kubernetes 作為 StarRocks 上雲的運維底座。基於 Kubernetes,我們開發了 StarRocks CRD 與 StarRocks Controller。StarRocks CRD 幫助我們可以通過宣告式 yaml 檔案進行 Operator 及 StarRocks 的部署,而 StarRocks Controller 幫助我們管理 pod 的狀態,將現實的狀態向期望狀態轉化。
 

存算分離的具體實現

StarRocks 中 SQL 的生命

在 StarRocks 中,FE 節點接收到客戶端發起的 SQL 請求,經過 Optimizer 生成一棵分散式執行計劃樹,然後轉換成 BE 可以直接執行的 PlanFragment,根據元資訊下發到相應的 BE 節點。
以簡單的聚合為例。原先 StarRocks 的邏輯是,StarRocks 會根據資料所在位置,選擇對應的 BE 進行資料讀取以及初次聚合操作,如果資料存在於外表中,也會由這些 BE 進行讀取聚合。然後給這些 BE 一個 partition id ,將資料根據聚合的 key 進行 hash 分組,將分組後的資料分發到對應 partitionId 的 BE 上,BE 通過 ExchangeNode 接收資料進行二次聚合,完成後最終交由原先選舉的 ResultSink 對應的 BE 進行最後的聚合計算。
 

計算節點的拆分

為了將計算操作從 BE 節點中拆分出來,我們需要完成以下步驟:
  1. 新增一種 DummyStoargeEngine 的儲存引擎,不儲存資料,只用來儲存 StarRocks cluster id
  2. 裁剪 BE 節點的 InternalService 和 HttpService,並支援使用空儲存路徑啟動
  3. 調整啟動引數和新增啟動指令碼,支援和 BE 同時執行
在經過拆分後,我們將 BE 的計算能力獨立出去成為一個無狀態的 Computer Node (CN) 節點,在設定了 CN 節點的排程引數後,整體的執行邏輯發生了變化,如下圖所示:
我們依然以簡單的聚合操作為例:
  1. OlapScanNode 會選 tablet 所在的 BE 進行資料讀取以及初次聚合操作,而 HdfsScanNode 則會根據資料情況均衡地分發給 CN 進行讀取與初次聚合。
  2. 為每個 CN 生成一個 partitionId,將 BE 與 CN 初次聚合後的資料根據聚合的 key 通過 hash 計算對應到 partitionId 然後傳送到所在的 CN 上,CN 通過 ExchangeNode 接收資料進行二次聚合
  3. 從這些 CN 節點選取一個作為 ResultSink,上一步完成後最終交由這臺 CN 進行最後的聚合計算

Kubernetes 運維底座

遊戲業務遇到週年慶、營銷活動、節假日等節點,會伴隨後端流量、日誌量的激增,也會帶來分析平臺負載激增。CN 計算節點拆分獨立後,我們進一步結合 Kubernetes(TKE)能力,打通公司算力平臺,最終使得 StarRocks 具備計算層面的彈性伸縮能力。基於雲原生的理念,我們通過容器化的方式來建立 CN 節點,並通過 K8s 的能力來做到快速的建立和擴縮容。
團隊實現了 StarRocks 的 Operator 自定義控制器,負責監控 k8s 叢集內的自定義資源的建立、改動、銷燬等事件,並觸發相應的邏輯。StarRocks Operator 主要分為兩個元件:
  • CRD 用來定義 ComputeNodeGroup 的資源型別,幫助我們通過宣告的方式進行節點在 Kubernetes 上的部署與管理。在 CRD 中,我們定義了 ComputeNodeGroup 資源型別,用來管理 CN 節點的狀態
  • StarRocks Controller 會根據宣告的資訊建立 Deployment,幫助我們管理叢集的狀態。當我們宣告式的擴容或縮容節點時,Controller 可以幫助我們將叢集向期望狀態轉化。
當容器啟動成功以後,自動呼叫 FE 的介面,將這些 CN 註冊到叢集裡面。當我們將 StarRocks 遷移到 Kubernetes 後,就可以利用 Kubernetes 原生的 HPA(Horizontal Pod Autoscale)資源物件,對 StarRocks 的 CN pod 進行動態伸縮管理,使 CN pod 可以根據資源指標實現流量變化的自適應,自動彈性地擴充新節點或者銷燬不需要的節點。
在 HPA 資源物件中,我們對 CPU、Memory 指標進行了監控,當指標發生變化時,Controller 會每 15s 檢查一次指標是否發生了變化。一旦觸發了伸縮條件,Controller 會向 Kuberneters 傳送請求,修改 CN pod 的數量。為了避免因抖動產生過於頻繁的伸縮,我們在 HPA 上做了限制,每 5 分鐘,Controller 只能傳送一次伸縮請求。

三、冷熱資料分層

在我們從 BE 節點將計算操作獨立抽出成為 CN 節點後,可以通過 Kubernetes 的 HPA 功能完成 CN 節點的彈性擴縮容。同時,針對 BE 的儲存功能,我們也與 StarRocks 社群一起規劃設計了冷熱資料分離儲存的功能。為了更好儲存一年甚至幾年的冷資料,我們決定將 BE 節點中的冷資料下沉到 HDFS 或 COS 等更為廉價的儲存。一方面期望大幅降低成本,另一方面,面向業務開發,期望湖倉技術在接下來演進中能夠更好融合。

冷資料的下沉儲存

基於前述架構,BE Cluster 儲存業務的熱資料(可以根據時間,如儲存近 2 個月的;也可以根據 BE 本地容量佔比),非熱資料則儲存到底層廉價的 COS 或者 HDFS 中。
在實際業務中,在如下兩個典型場景,我們達成了不同的資源使用及負載隔離的目的:
  • 高頻訪問熱資料的 BI 分析場景,預設走 BE Cluster 提供秒級高效的查詢分析效能;
  • 使用者自定義 SQL 的探索分析場景,會訪問更長週期歷史冷資料,分析平臺可以通過 CN Operator 拉起一個 CN Cluster,構建起該場景對應的分析叢集,優先訪問底層下沉資料。
同時,CN Cluster 叢集容量,可根據分析 workload 的負載,自助一鍵式伸縮;或通過配置叢集自動擴縮容策略,讓 CN Cluster 進行自動伸縮;當探索分析場景結束後,亦可釋放此次的 CN Cluster 資源,達到計算資源“按需使用”高性價比方式。

冷熱資料分層儲存功能實現

當前選擇了基於 Iceberg+(HDFS/COS) 的方案。以分割槽下沉方案為例,大概可分為四個步驟:
  1. 在 BE 上支援匯出 ORC 格式檔案,生成的 ORC 格式檔案通過 Broker 上傳到 COS/HDFS 中
  2. 提取生成的 ORC 檔案統計資訊,通過 Iceberg API 新增一個分割槽
  3. 新增定時任務生成需要下沉的分割槽資訊。當資料下沉之後,即可通過 StarRocks 進行查詢分析。在上述架構中,我們初期在 Iceberg 外表功能測試中遇到了若干問題,對應的優化項均已提交開源社群,後文將有所羅列。
  4. 當執行查詢語句時,我們通過分割槽元資料資訊,自動判斷資料存在本地還是外部儲存生成不同的 ScanNode。如果需要同時獲取兩邊的資料,則通過一個 Union 運算元,將兩個 ScanNode 的結果進行合併,獲得全量資料。

分層後的效能優化

在資料下沉及查詢功能完成之後,效能壓測中,我們發現存算分離相比存算一體,在業務典型業務 SQL 場景,效能差距在 50-100 倍之間。通過分析 Profile,在以下方面做了優化:
  1. FE 生成執行計劃的時候,會多次呼叫 Iceberg 的 planFiles 介面來獲取計算 CBO 的統計資料和 HDFS NODE 的 Range location。而這兩個操作需要獲取 Iceberg 的元資料,需要和遠端儲存互動,這也是 FE 耗時最多的地方。對此,我們也參考 Iceberg 社群,儘量減少對依賴包改動的原則下,在 StarRocks 中新增 Iceberg FILEIO cache 機制,將 Iceberg metadata.josn, manifest, manifest-list 快取下來,加速 FE 的生成執行計劃。
  2. Iceberg 表頻繁重新整理,也會增加 100ms 左右的耗時,我們保證每條 SQL 只重新整理一次,跳過其他情況下的表重新整理。
  3. 除錯本地和外部儲存同時查詢的語句時,我們發現這種查詢比單獨查詢兩邊的資料都要慢,大概能有 5-8 倍的效能差異。通過定位,我們發現是生成的 Union 執行計劃不優導致的。具體來說,如果原來的執行計劃只有一個 ScanNode,並且上面包含 Aggregate(或者 Project)運算元的時候,這個運算元會被下推到 ScanNode 所在的 Fragment。而我們生成 Union 的時候,將 ScanNode 替換成了 Union,這個時候生成物理計劃的時候會插入一個 ExchangeNode,這就會導致每次執行都會做一次全量資料傳輸。為了解決這個問題,我們優化了執行計劃,將 Aggregate 的第一階段聚合下推到了 Union 下面,從而減少了大量 Exchange 傳輸資料量,達到了直接查詢外表相當的效能表現。
 
經過上述優化,截止目前,我們基於業務真實的 1TB,260億行單表資料量,CN 和 BE 均投入為 12 個節點,分別對應存算分離及存算一體兩條鏈路 ,採用典型 SQL 進行對比測試。效能差距從 50-100倍,縮減到了目前的 5-10倍。在整體方案具備按不同業務場景 ,不同 SQL 負載,可以互相隔離的前提下,達成了效能和成本平衡的初步目標。
 
 

四、StarRocks 雲原生的未來

存算分離是 StarRocks 邁向雲原生的第一步,我們已經初步完成了:
  • 獨立無狀態的 Compute Node 支援靈活的計算擴充套件。
  • 儲存層可以在物件儲存上進行靈活的資源擴充套件。
  • Compute Node 支援在熱儲存(BE)和 冷儲存(物件儲存)上執行查詢。
  • 通過資料下沉機制,可以實現資料在冷熱儲存的轉儲。
長期來看,我們會按照社群的路線圖一起繼續完善雲原生架構:
  • 支援多叢集模式,能夠讓獨立的叢集完成獨立的特定的任務,比如晚上有大規模 ETL 作業時可以彈性出一個專用的 ETL 叢集。
  • 完善 Primary Key 的存算分離機制,解決秒級實時更新場景下的存算分離難題。
  • 持續優化快取機制,讓存算分離架構的查詢效能可以媲美存算一體架構。在 Compute Node 上增加 Local cache,降低遠端資料訪問的延遲。
  • BE 會逐步演進成一個多叢集公用的 Global cache,為 Serverless 架構提供完整運算元下推能力的通用查詢加速層。
  • 實現 FE 存算分離,為更大規模的雲原生數倉設計元資料管理架構。
從上圖可以看到,StarRocks 未來會支援兩種計算分離模式,左邊的模式類似 Snowflake 的架構,計算層上有一個本地的 Local cache,可以保證資料快取命中時的高效能。但是,在叢集做彈性的時候會導致 cache 資料的重新分佈和遠端載入,所以在擴容過程中會有一定的效能損失。此種模式比較適合對彈性要求不高,比較適合追求極致效能的業務場景。
在右側的架構中,我們在現在的計算和儲存層之間增加了一個公共的全域性資料快取,可以給上層所有 Compute Node 提供包括運算元下推內的計算能力。這樣就可以實現秒級的彈性以及彈性過程中叢集的效能穩定,同時可以針對每一個請求即時分配計算資源,計算完成以後馬上釋放,實現真正的 Serverless 級別的彈性伸縮。比較適合在滿足效能要求下追求彈性的業務場景。
通過支援兩種計算分離模式,可以非常好地利用 StarRocks 來統一滿足各類業務要求,實現“極速統一”的資料分析新正規化。
 

五、騰訊天穹 Oteam 介紹

天穹是協同騰訊內各 BG 大資料能力而生的 Oteam,作為騰訊大資料領域的代名詞,旨在拉通大資料各個技術元件,打造一個具有統一技術棧的公司級大資料平臺體系。從底層資料接入、資料儲存、資源管理、計算引擎、作業排程,到上層資料治理及資料應用等多個環節,支援騰訊內部近 EB 級資料的儲存和計算,為業務提供海量、高效、穩定的大資料平臺支撐和決策支援。
 

六、社群貢獻

我們選擇 StarRocks 作為騰訊遊戲公共資料平臺 OLAP 分析引擎的同時,也深刻感受到了 StarRocks 社群開放、包容、共創的開源文化。在騰訊遊戲業務落地的過程中,我們還參與了 UDF 函式開發、Iceberg 外表查詢優化以及 StarRocks CN Operator 等功能模組的共同開發:

漏斗函式

  • [#4985] Add window_funnel aggregate functionhttps://github.com/StarRocks/starrocks/pull/4985

外表優化

  • [#6846] Generate statistics for empty iceberg tablehttps://github.com/StarRocks/starrocks/pull/6846
  • [#6237] Support FileIO cache for iceberg tablehttps://github.com/StarRocks/starrocks/pull/6237
  • [#5680] Reduce call to get iceberg TableStatisticshttps://github.com/StarRocks/starrocks/pull/5680
  • [#5640] Reduce Iceberg metadata refresh operationhttps://github.com/StarRocks/starrocks/pull/5640

CN 節點和 FE 排程

  • [#5441] Add Compute node to support serveless https://github.com/StarRocks/starrocks/pull/5441
  • [#6394] Add compute node in FE https://github.com/StarRocks/starrocks/pull/6394

StarRocks CN Operator

  • https://github.com/StarRocks/starrocks-kubernetes-operator
隨著更多的業務落地 StarRocks 以及更深入的使用,我們會持續在執行計劃優化、物化檢視、CN 節點分組邏輯等功能以及雲原生數倉方向上深入建設,與大家一起在社群共創的路上行穩致遠。
 
 
關於 StarRocks
StarRocks 創立兩年多來,一直專注打造世界頂級的新一代極速全場景 MPP 資料庫,幫助企業建立“極速統一”的資料分析新正規化,助力企業全面數字化經營。
當前已經幫助騰訊、攜程、順豐、Airbnb 、滴滴、京東、眾安保險等超過 110 家大型使用者構建了全新的資料分析能力,生產環境中穩定執行的 StarRocks 伺服器數目達數千臺。
2021 年 9 月,StarRocks 原始碼開放,在 Github 上的星數已超過 3000 個。StarRocks 的全球社群飛速成長,至今已有超百位貢獻者,社群使用者突破 5000 人,吸引幾十家國內外行業頭部企業參與共建。