【跨國數倉遷移最佳實踐2】MaxCompute SQL執行引擎對復雜類型處理全面重構,保障客戶從BigQuery平滑遷移

本系列文章將圍繞東南亞頭部科技集團的真實遷移歷程展開,逐步拆解 BigQuery 遷移至 MaxCompute 過程中的關鍵挑戰與技術創新。本篇為第二篇,跨國數倉遷移背后 MaxCompute 的統一存儲格式創新。

注:客戶背景為東南亞頭部科技集團,文中用 GoTerra 表示。

業務背景和痛點

隨著大數據與AI時代的快速發展,全球數據總量已經突破了百ZB量級,其中半結構化(Json等)和嵌套數據結構(PB等)占比超50%,傳統技術處理此類數據,面臨存儲成本高,計算效率低等問題日益凸顯,亟需高效的性能優化技術。當前主流大數據處理引擎框架普通采用復雜數據類型(struct、map、array)來靈活處理半結構化等數據,相關功能支持和處理性能成為現代數據架構技術競爭焦點。

Google BigQuery和阿里云MaxCompute作為全球領先的商業化數據處理平臺,均歷經十余年產品和技術迭代。其中MaxCompute日均處理EB級數據和數千萬作業,服務覆蓋了全球多行業客戶,因此也一直在持續豐富復雜類型的功能完備和性能優化。在?GOTO項目從BigQuery遷移至MaxCompute?的過程中,?復雜數據類型的處理能力對標?成為關鍵任務,需確保功能和性能?持平甚至超越?BigQuery,以實現作業平滑遷移與資源成本優化。

技術現狀

簡單介紹三種典型復雜數據類型特征和使用場景:

  • Array類型: 一組同類型元素的集合(如array<bigint>),支持下標索引訪問元素,廣泛應用于存儲和處理列表形式的數據,例如商品列表,多值屬性等
  • Map類型:鍵值對集合(如map<bigint, string>),支持通過鍵直接訪問值,典型場景包括動態屬性、鍵值配置等
  • Struct類型: 包含多個字段的復合類型(如struct<id:bigint, value:string>),每個字段具有獨立名稱和類型,支持通過字段名訪問元素,常用于用戶畫像標簽、訂單信息等

MaxCompute支持復雜類型的現有能力和瓶頸:

  • 存儲層:支持復雜類型列式存儲(Aliorc文件格式),顯著降低存儲成本,具體用法參考官網介紹。
  • 計算層: 支持行式復雜類型數據處理。盡管功能完備,但性能仍有較大優化空間。

由此可見,一條復雜類型數據處理,需經歷列式讀取,換轉成行式計算,再轉換成列式寫入,多次轉換開銷巨大,并且大部分算子行式處理數據性能也較差,導致部分場景性能相比BigQuery存在一定的差距。

為徹底解決優化這些痛點,MaxCompute SQL執行引擎對復雜類型處理進行了全面重構,整體支持復雜類型列式的內存存儲結構,對各個算子進行深度適配優化,整體處理性能實現質的飛躍,部分場景提升超10倍,基本追平Bigquery對復雜類型的計算處理性能,且在某些場景實現性能超越,最終保障了GOTO項目海量作業的平滑遷移,同時大幅節省計算資源

技術方案簡述

這里主要介紹兩個核心優化重構,一個是復雜數據類型的計算優化重構,另一個是Unnest with subquery的框架優化重構,這兩項優化在復雜類型場景普遍都帶來1-10倍以上的性能提升。

列式復雜數據類型的計算優化重構

優化分成兩個階段:

  1. 各算子基于當前行式復雜類型結構持續優化計算邏輯,減少不必要的拷貝和計算。
  2. 將行式結果徹底改造成列式結構,并適配各算子列式計算模式。

行式復雜類型淺拷貝優化

現有算子接收到行式復雜類型的輸入數據,進行計算后輸出,需全量數據深拷貝,對于數據量大的復雜類型,開銷極高。因此數據結構和處理過程進行深入優化,支持絕大部份處理流程進行淺拷貝優化,只要數據不發生變更,只需拷貝數據引用即可,不涉及數據本身的拷貝,優化覆蓋表達式/聚合/Join/Window等主要算子,部分場景提升高達100倍+,效果顯著

復雜類型列式內存結構和計算優化重構

雖然行式優化取得了不少進展,但部分痛點依然存在,比如計算過程效率低下,無法高效適配向量化計算;計算過程中子元素列裁剪無法生效;每行數據的內存結構復雜,且需存儲重復的輔助結構,嚴重制約整體計算性能。

為了顯著提升性能,徹底改造復雜類型內存存儲和計算框架,由行式轉為列式內存結構,推動各個算子采用高效的列式計算思想適配優化,整體性能得到質的飛躍,部分場景提速超10倍。

列式內存結構重構

如上圖所示,重構之后,每行復雜類型數據不再單獨存儲,而且采用類arrow結構,對于Batch(多行數據集合)中某一列復雜類型,相同位置的子元素連續內存存儲,因此每個Batch僅需存儲一份輔助結構(如列名等),有效節省內存空間,而且子元素數據連續存儲,內存訪問效率也顯著提升。

算子適配列式復雜類型計算

列式結果改造完成后,各SQL算子需進一步適配優化,由于行式和列式計算方式差異顯著,此部分優化近乎完全重構,并針對不同場景進行了精細化適配。

列式復雜類型計算模式可分為以下三類:

  • 數據透傳模式: 數據從源表列式讀取后,中間處理無變更,全程零拷貝傳輸,最后直接列式寫入目標表,性能優化到極致。常見于數據搬遷,簡單列裁剪數據清洗等場景。
  • 數據追加模式: 算子一次性處理復雜類型數據后順序輸出到列式結構中,不會再次修改,可有效利用內存緩存優化和向量化處理提升整體性能。常見于表達式/Window/Join等主要算子。
  • 數據修改模式: 算子需多次隨機修改復雜類型數據,此模式不太適合列式內存結構,其存儲的多行數據內存是連續的,如果隨機修改中間某一行數據,可能破壞后繼其他行數據的內存結構,因此此場景需退化成行式處理。常見于聚合函數處理等少數算子。

Unnest with subquery 的框架優化重構

BigQuery的Unnest(array)操作極為常見,輸入參數通常是一個Array復雜類型,負責把Array中每一個子元素展開為一個單獨行進行輸出,GOTO項目大量任務使用此操作,遷移到MaxCompute之后,由于缺乏原生支持,需自動轉換成等效的Lateral View + Explode操作來執行。但當Unnest嵌套于SQL子查詢等較為復雜用法時,MaxCompute處理會變得極其復雜,性能急劇下降。

下面舉個例子:

create table src(a bigint, b array<struct<c:bigint, d:string>>);select(select max(c) from unnest(b)),a+100,(select collest_list(d) from unnest(b) where d='test')
from src; 

上述SQL示例中,MaxCompute執行時會轉換成如下Plan來執行(示意圖):

可見此Plan主要存在如下問題:

  • 同一源表多次讀取
  • 相同unnest操作重復執行
  • 需多次復雜Join拼接數據

因此如需大幅提升性能,需在語法解析,Plan構建,算子計算等各流程對此場景完全重構優化。

SQL Plan優化

為了優化上述三個問題,重構優化后的Plan如下圖所示(示意圖),

  1. 僅讀取一次源表,按需把讀取數據列推送至各Subquery計算
  2. 定義新的CorrelatedJoin操作,負責把每個Subquery定義成一個單獨的internal subplan,然后按行對齊和拼接每個Subquery的計算輸出列,整行輸出,消除計算量很重的多次Join操作
  3. 定義新的internal subplan結構,本質是一棵OperatorTree, 并做針對性的Plan優化改造,如消除shuffle操作
  4. 對于多個subquery中相同Unnest操作,支持子樹合并,消除冗余的unnest操作(在優化中)。

經過上述優化后,基本可解決之前的性能痛點,貼近性能最佳的計算Plan,后續還需要SQL執行層進行計算適配。

SQL執行層優化

主要負責執行物理Plan,并發處理數據,輸出結果,優化重構主要分以下幾步:

  1. 適配優化后的新物理Plan,解析為可執行算子
  2. 實現新CorrelatedJoin算子,負責驅動internal subplan執行,并且把各subplan執行的結果按行對齊和高效拼接,然后輸出整行結果到后續算子執行
  3. 實現新的internal subplan數據處理框架,需支持按照每行復雜類型進行一次性處理和輸出的語義,跟通用算子執行框架差異顯著。

上線效果和業務價值

提升效果案例

列式復雜類型重構優化性能提升案例

上圖示例展示的是用戶某個作業的其中一個Stage M6的處理過程,TableScan1從源表中讀取了多層嵌套的復雜類型數據,經過了TableScan / Project / TableFunction / Shuffle等算子處理,基于行式復雜類型結構進行處理,M6 Stage整體耗時超過5分鐘,切換到優化后的列式復雜類型處理,整體Stage耗時縮短到31秒,速度提升了10倍+,效果極為顯著。

Unnest with subquery重構優化性能提升案例

上圖示例展示了用戶某個作業經過Unnest With subquery重構優化后,整體作業性能提升了80%+,由于整體sql比較復雜,這個優化只涉及到其中部分stage,其中命中優化的算子提速3倍+,效果極為顯著。

業務價值

GOTO整體項目,包含復雜類型的表數量超4萬張,日均處理復雜類型的SQL作業超20萬+,通過上述優化重構之后,大部分SQL性能提升20%~10倍+,日均減少2000+ Cpu Core消耗,極大的助力了GOTO項目按時保質的從Bigquery平滑遷移到MaxCompute,實現降本增效的目標。

后續會持續完善打磨列式復雜類型在各個場景的數據處理優化,并全面推廣到MaxCompute平臺所有業務場景中,預計全域上百萬作業將顯著受益,大幅節省業務計算成本,技術普惠到所有用戶。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915474.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915474.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915474.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

react(基礎篇)

React由Meta公司研發&#xff0c;用于構建Web和原生交互界面的庫。 React 官方中文文檔 查看JSX &#xff08;一&#xff09;React組件 用戶界面的一部分&#xff0c;通俗的來講&#xff0c;最小的元素組成的單元&#xff0c;可以實現部分邏輯與功能 房子的門就可以看成一個…

數據結構-哈希表(一)哈希函數、哈希表介紹、優缺點

哈希表 哈希函數哈希表使用了哈希函數來完成key到地址的快速映射&#xff0c;所以在了解哈希表之前&#xff0c;需要先明白哈希函數的概念和特點。 哈希函數的定義 哈希函數 哈希函數是一種將任意長度輸入的數據&#xff0c;轉換成固定長度輸出的算法哈希函數H可以表示為yH(x) …

Shader開發(一)什么是渲染

前言在現代游戲開發和計算機圖形學領域&#xff0c;渲染技術是連接虛擬世界與視覺呈現的關鍵橋梁。無論你是剛接觸圖形編程的新手&#xff0c;還是希望深入理解渲染原理的開發者&#xff0c;掌握渲染的核心概念都是必不可少的第一步。什么是渲染&#xff1f;渲染&#xff08;Re…

策略模式+工廠模式(案例實踐易懂版)

最近,可以說這2025年度,自己更文的次數都大大減少,主要最近大環境不景氣,自己職業也受到波及,學習的東西也是因為AI而變得更多, 沒辦法,你不學,總有人會學,關于AI的我也準備出個專輯,相信絕對幫助到大家 額,好像說多了,言歸正傳,我們看一下今天的主題:策略模式工廠模式 本文主要…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - snowNLP庫實現中文情感分析

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解snowNLP庫實現中文情感分析 視頻在線地址&…

大根堆,小根堆,雙指針

碼蹄集OJ-大約 #include<bits/stdc.h> using namespace std; priority_queue<int>max2,maxDel; priority_queue<int,vector<int>,std::greater<int>>min2,minDel; const int N1e51; int n,result0,a[N]; int main( ) {cin>>n;for(int i1…

RS485和Modbus

UART協議中&#xff0c;空閑狀態為高電平&#xff0c;也就是1,R25和R27&#xff0c;485收發器特性MAX485 (美信)SSP485 (國產替代)AZRS3080 (安格)供電電壓5V5V3.3V ~ 5.5V靜態電流300μA (接收模式)120μA (接收模式)150μA (接收模式)傳輸速率2.5Mbps10Mbps20Mbps總線負載能力…

【Android】交叉編譯faiss庫 | 問題解決

目錄 一 解決 FAISS 交叉編譯到 Android 時的 BLAS/MKL 依賴問題 二 交叉編譯faiss ■禁用 BLAS并交叉編譯faiss ■使用 OpenBLAS 的 Android 移植版本并交叉編譯faiss 三 報錯處理 ■報錯 ■SWIG 一 解決 FAISS 交叉編譯到 Android 時的 BLAS/MKL 依賴問題

《使用 IDEA 部署 Docker 應用指南》

使用 IDEA 部署 Docker 應用的詳細步驟 一、創建 Dockerfile 配置文件 在項目根目錄下創建Dockerfile文件&#xff0c;配置內容如下&#xff1a; # 使用官方的OpenJDK鏡像作為基礎鏡像 FROM openjdk:17-jdk-slim# 設置維護者信息(可選) LABEL maintainer"三木豪"# 設…

【Docker#3】Window 和 Linux 上 docker安裝 相關知識

前置了解&#xff1a; X86 高并發&#xff1a;基于 x86 架構的處理器&#xff0c;在高負載下處理大量并發請求的能力。ARM &#xff1a;使用 ARM 架構處理器的移動設備&#xff0c;具有低功耗和高性能的特點。 操作系統&#xff1a; CentOS&#xff1a;基于 Red Hat Enterprise…

一次 POI 版本升級踩坑記錄

前言 結論先行。 開發過程中由于可能涉及到二次開發&#xff0c;若原系統開發時間久遠&#xff0c;沒有達成一致規范設計&#xff0c;導致風格各異&#xff0c;確實滿足當時開發場景&#xff0c;但增大了后續的更新的難度&#xff0c;容易出現俄羅斯套娃現象&#xff0c;新的更…

硬件設計學習DAY13——電源緩沖電路設計全解

每日更新教程&#xff0c;評論區答疑解惑&#xff0c;小白也能變大神&#xff01;" 目錄 一.緩沖電路介紹 1.1緩沖電路的作用 1.2寄生參數的來源 1.3緩沖電路的類型 1.4常見緩沖電路設計 1.5設計原則 二.吸收與緩沖 2.1吸收與緩沖的核心作用 2.2電壓尖峰與吸收措…

鴻蒙搜狐新聞如何在Native調用ArkTS方法

01前言鴻蒙作為一款新興的智能操作系統&#xff0c;現在適配鴻蒙系統的應用越來越多&#xff0c;同時會面臨三端兼容問題&#xff0c;如同一產品功能&#xff0c;需要維護iOS、Android、鴻蒙三端代碼。拿文件上傳、下載功能場景舉例&#xff0c;同時要適配iOS、Android、鴻蒙三…

Java行為型模式---中介者模式

中介者模式基礎概念中介者模式&#xff08;Mediator Pattern&#xff09;是一種行為型設計模式&#xff0c;其核心思想是通過一個中介對象來封裝一系列對象之間的交互&#xff0c;使各對象不需要顯式地相互引用&#xff0c;從而降低耦合度&#xff0c;并可以獨立地改變它們之間…

Python爬蟲實戰:研究Korean庫相關技術

一、引言 1.1 研究背景與意義 隨著韓流文化在全球的傳播,韓語網頁內容急劇增加。韓國在科技、娛樂等領域的信息具有重要研究價值。然而,韓語獨特的黏著語特性(如助詞體系、詞尾變化)給信息處理帶來挑戰。傳統爬蟲缺乏對韓語語言特點的針對性處理,本研究旨在開發一套完整…

表單校驗--數組各項獨立校驗

寫需求時遇到一個這樣的問題&#xff0c;就是校樣項是多個的&#xff0c;但是其字段名稱相同這時我們可以這樣校驗&#xff0c;注意字段之間的關聯性<div v-for"(item,index) in formData.hospitalDoctorList" :key"item.key || index"><el-form-…

基于SpringBoot和leaflet-timeline-slider的歷史敘事GIS展示-以哪吒2的海外國家上映安排為例

目錄 前言 一、哪吒2的海外之路 1、海外征戰歷程 2、上映國家空間查詢 二、后端接口的實現 1、模型層的實現 2、上映時間與國家 3、控制層的實現 三、基于leaflet-timeline-slider的前端實現 1、時間軸控件的引入及定義 2、時間軸綁定事件 3、成果展示 四、總結 前言…

tar 解壓:Cannot change ownership to uid 1000, gid 1000: Operation not permitted

tar 解壓 tar.gz 壓縮包報錯&#xff1a; # tar xzf $INPUT_FOLDER/archive.tar.gz -C /mnt/test-nas/[..] tar: xx.jpg: Cannot change ownership to uid 1000, gid 1000: Operation not permitted原因是用普通用戶執行的解壓縮腳本&#xff0c;用root用戶執行tar解壓縮&…

騰訊客戶端開發面試真題分析

以下是針對騰訊客戶端開發工程師面試問題的分類與高頻問題分析&#xff08;基于??105道問題&#xff0c;總出現次數118次??&#xff09;。按技術領域整合為??7大類別??&#xff0c;按占比排序并精選高頻問題標注優先級&#xff08;1-5&#x1f31f;&#xff09;&#x…

線上問題排查之【CPU飆高100%】

目錄 案例 發現問題 排查問題 步驟一 步驟二 步驟三 案例 import java.util.concurrent.TimeUnit;/*** 簡單寫一個CPU飆高的案例*/ public class CpuLoadUp {// 這里定義了一個標識private volatile static int flag 0;public static void main(String[] args) {// 執行…