自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

萬字長文揭秘:阿里如何實(shí)現(xiàn)海量數(shù)據(jù)實(shí)時(shí)分析?

開發(fā) 開發(fā)工具
隨著數(shù)據(jù)量的快速增長,越來越多的企業(yè)迎來業(yè)務(wù)數(shù)據(jù)化時(shí)代,數(shù)據(jù)成為了最重要的生產(chǎn)資料和業(yè)務(wù)升級(jí)依據(jù)。本文由阿里AnalyticDB團(tuán)隊(duì)出品,近萬字長文,首次深度解讀阿里在海量數(shù)據(jù)實(shí)時(shí)分析領(lǐng)域的多項(xiàng)核心技術(shù)。

[[252839]]

挑戰(zhàn)

隨著數(shù)據(jù)量的快速增長,越來越多的企業(yè)迎來業(yè)務(wù)數(shù)據(jù)化時(shí)代,數(shù)據(jù)成為了最重要的生產(chǎn)資料和業(yè)務(wù)升級(jí)依據(jù)。伴隨著業(yè)務(wù)對(duì)海量數(shù)據(jù)實(shí)時(shí)分析的需求越來越多,數(shù)據(jù)分析技術(shù)這兩年也迎來了一些新的挑戰(zhàn)和變革:

  • 在線化和高可用,離線和在線的邊界越來越模糊,一切數(shù)據(jù)皆服務(wù)化、一切分析皆在線化。
  • 高并發(fā)低延時(shí),越來越多的數(shù)據(jù)系統(tǒng)直接服務(wù)終端客戶,對(duì)系統(tǒng)的并發(fā)和處理延時(shí)提出了新的交互性挑戰(zhàn)。
  • 混合負(fù)載, 一套實(shí)時(shí)分析系統(tǒng)既要支持?jǐn)?shù)據(jù)加工處理,又要支持高并發(fā)低延時(shí)的交互式查詢。
  • 融合分析, 隨著對(duì)數(shù)據(jù)新的使用方式探索,需要解決結(jié)構(gòu)化與非結(jié)構(gòu)化數(shù)據(jù)融合場(chǎng)景下的數(shù)據(jù)檢索和分析問題。

阿里巴巴最初通過單節(jié)點(diǎn)Oracle進(jìn)行準(zhǔn)實(shí)時(shí)分析, 后來轉(zhuǎn)到Oracle RAC,隨著業(yè)務(wù)的飛速發(fā)展, 集中式的Shared Storage架構(gòu)需要快速轉(zhuǎn)向分布式,遷移到了Greenplum,但不到一年時(shí)間便遇到擴(kuò)展性和并發(fā)的嚴(yán)重瓶頸。為了迎接更大數(shù)據(jù)集、更高并發(fā)、更高可用、更實(shí)時(shí)的數(shù)據(jù)應(yīng)用發(fā)展趨勢(shì),從2011年開始,在線分析這個(gè)技術(shù)領(lǐng)域,阿里實(shí)時(shí)數(shù)倉堅(jiān)定的走上了自研之路。

[[252840]]

分析型數(shù)據(jù)庫AnalyticDB

AnalyticDB是阿里巴巴自主研發(fā)、唯一經(jīng)過超大規(guī)模以及核心業(yè)務(wù)驗(yàn)證的PB級(jí)實(shí)時(shí)數(shù)據(jù)倉庫。自2012年第一次在集團(tuán)發(fā)布上線以來,至今已累計(jì)迭代發(fā)布近百個(gè)版本,支撐起集團(tuán)內(nèi)的電商、廣告、菜鳥、文娛、飛豬等眾多在線分析業(yè)務(wù)。

AnalyticDB于2014年在阿里云開始正式對(duì)外輸出,支撐行業(yè)既包括傳統(tǒng)的大中型企業(yè)和政府機(jī)構(gòu),也包括眾多的互聯(lián)網(wǎng)公司,覆蓋外部十幾個(gè)行業(yè)。AnalyticDB承接著阿里巴巴廣告營銷、商家數(shù)據(jù)服務(wù)、菜鳥物流、盒馬新零售等眾多核心業(yè)務(wù)的高并發(fā)分析處理, 每年雙十一上述眾多實(shí)時(shí)分析業(yè)務(wù)高峰驅(qū)動(dòng)著AnalyticDB不斷的架構(gòu)演進(jìn)和技術(shù)創(chuàng)新。

經(jīng)過這2年的演進(jìn)和創(chuàng)新,AnalyticDB已經(jīng)成長為兼容MySQL 5.x系列、并在此基礎(chǔ)上增強(qiáng)支持ANSI SQL:2003的OLAP標(biāo)準(zhǔn)(如window function)的通用實(shí)時(shí)數(shù)倉,躋身為實(shí)時(shí)數(shù)倉領(lǐng)域極具行業(yè)競(jìng)爭力的產(chǎn)品。近期,AnalyticDB成功入選了全球權(quán)威IT咨詢機(jī)構(gòu)Forrester發(fā)布"The Forrester Wave™: CloudData Warehouse,Q4 2018"研究報(bào)告的Contenders象限,以及Gartner發(fā)布的分析型數(shù)據(jù)管理平臺(tái)報(bào)告 (Magic Quadrant forData Management Solutions for Analytics),開始進(jìn)入全球分析市場(chǎng)。AnalyticDB旨在幫客戶將整個(gè)數(shù)據(jù)分析和價(jià)值化從傳統(tǒng)的離線分析帶到下一代的在線實(shí)時(shí)分析模式。

整體架構(gòu)

經(jīng)過過去2年的架構(gòu)演進(jìn)和功能迭代,AnalyticDB當(dāng)前整體架構(gòu)如下圖。

AnalyticDB是一個(gè)支持多租戶的Cloud Native Realtime Data Warehouse平臺(tái),每個(gè)租戶DB的資源隔離,每個(gè)DB都有相應(yīng)獨(dú)立的模塊(圖中的Front Node, Compute Node, Buffer Node),在處理實(shí)時(shí)寫入和查詢時(shí),這些模塊都是資源(CPU, Memory)使用密集型的服務(wù),需要進(jìn)行DB間隔離保證服務(wù)質(zhì)量。同時(shí)從功能完整性和成本優(yōu)化層面考慮,又有一系列集群級(jí)別服務(wù)(圖中綠色部分模塊)。

下面是對(duì)每個(gè)模塊的具體描述:

DB級(jí)別服務(wù)組件:

  • Front Node:負(fù)責(zé)JDBC, ODBC協(xié)議層接入,認(rèn)證和鑒權(quán),SQL解析、重寫;分區(qū)地址路由和版本管理;同時(shí)優(yōu)化器,執(zhí)行計(jì)劃和MPP計(jì)算的調(diào)度模塊也在Front Node。
  • Compute Node: 包含MPP計(jì)算Worker模塊,和存儲(chǔ)模塊(行列混存,元數(shù)據(jù),索引)。
  • Buffer Node: 負(fù)責(zé)實(shí)時(shí)寫入,并根據(jù)實(shí)時(shí)數(shù)據(jù)大小觸發(fā)索引構(gòu)建和合并。

集群級(jí)別服務(wù)組件:

  • Management Console: 管理控制臺(tái)。
  • Admin Service:集群管控服務(wù),負(fù)責(zé)計(jì)量計(jì)費(fèi),實(shí)例生命周期管理等商業(yè)化功能,同時(shí)提供OpenAPI和InnerAPI給Management Console和第三方調(diào)用。
  • Global Meta Service:全局元數(shù)據(jù)管理,提供每個(gè)DB的元數(shù)據(jù)管理服務(wù),同時(shí)提供分區(qū)分配,副本管理,版本管理,分布式DDL等能力。
  • Job Service:作業(yè)服務(wù),提供異步作業(yè)調(diào)度能力。異步作業(yè)包括索引構(gòu)建、擴(kuò)容、無縫升級(jí)、刪庫刪表的后臺(tái)異步數(shù)據(jù)清理等。
  • Connector Service:數(shù)據(jù)源連接服務(wù),負(fù)責(zé)外部各數(shù)據(jù)源(圖中右側(cè)部分)接入到AnalyticDB。目前該服務(wù)開發(fā)基本完成,即將上線提供云服務(wù)。
  • Monitoring & Alerting Service:監(jiān)控告警診斷服務(wù),既提供面向內(nèi)部人員的運(yùn)維監(jiān)控告警診斷平臺(tái),又作為數(shù)據(jù)源通過Management Console面向用戶側(cè)提供數(shù)據(jù)庫監(jiān)控服務(wù)。
  • Resource Management Service:資源管理服務(wù),負(fù)責(zé)集群級(jí)別和DB級(jí)別服務(wù)的創(chuàng)建、刪除、DNS/SLB掛載/卸載、擴(kuò)縮容、升降配,無縫升級(jí)、服務(wù)發(fā)現(xiàn)、服務(wù)健康檢查與恢復(fù)。

數(shù)據(jù)模型

AnalyticDB中表組(Table Group)分為兩類:事實(shí)表組和維度表組。

  • 事實(shí)表組(Fact Table Group),表組在AnalyticDB里是一個(gè)邏輯概念,用戶可以將業(yè)務(wù)上關(guān)聯(lián)性比較多的事實(shí)表放在同一個(gè)事實(shí)表組下,主要是為了方便客戶做眾多數(shù)據(jù)業(yè)務(wù)表的管理,同時(shí)還可以加速Co-location Join計(jì)算。
  • 維度表組(Dimension Table Group),用于存放維度表,目前有且僅有一個(gè),在數(shù)據(jù)庫建立時(shí)會(huì)自動(dòng)創(chuàng)建,維度表特征上是一種數(shù)據(jù)量較小但是需要和事實(shí)表進(jìn)行潛在關(guān)聯(lián)的表。

AnalyticDB中表分為事實(shí)表(Fact Table)和維度表(Dimension Table)。

事實(shí)表創(chuàng)建時(shí)至少要指定Hash分區(qū)列和相關(guān)分區(qū)信息,并且指定存放在一個(gè)表組中,同時(shí)支持List二級(jí)分區(qū)。

  • Hash Partition將數(shù)據(jù)按照分區(qū)列進(jìn)行hash分區(qū),hash分區(qū)被分布到多個(gè)Compute Node中。
  • List Partition(如果指定List分區(qū)列的話)對(duì)一個(gè)hash分區(qū)進(jìn)行再分區(qū),一般按照時(shí)間(如每天一個(gè)list分區(qū))。
  • 一個(gè)Hash Partition的所有List Partition默認(rèn)存放于同一個(gè)Compute Node中。每個(gè)Hash Partition配有多個(gè)副本(通常為雙副本),分布在不同的Compute Node中,做到高可用和高并發(fā)。

維度表可以和任意表組的任意表進(jìn)行關(guān)聯(lián),并且創(chuàng)建時(shí)不需要配置分區(qū)信息,但是對(duì)單表數(shù)據(jù)量大小有所限制,并且需要消耗更多的存儲(chǔ)資源,會(huì)被存儲(chǔ)在每個(gè)屬于該DB的Compute Node中。

下圖描述了從Database到List分區(qū)到數(shù)據(jù)模型:

對(duì)于Compute Node 來說,事實(shí)表的每個(gè)List分區(qū)是一個(gè)物理存儲(chǔ)單元(如果沒有指定List分區(qū)列,可認(rèn)為該Hash分區(qū)只有一個(gè)List分區(qū))。一個(gè)分區(qū)物理存儲(chǔ)單元采用行列混存模式,配合元數(shù)據(jù)和索引,提供高效查詢。

海量數(shù)據(jù)

基于上述數(shù)據(jù)模型,AnalyticDB提供了單庫PB級(jí)數(shù)據(jù)實(shí)時(shí)分析能力。以下是生產(chǎn)環(huán)境的真實(shí)數(shù)據(jù):

  • 阿里巴巴集團(tuán)某營銷應(yīng)用單DB表數(shù)超過20000張
  • 云上某企業(yè)客戶單DB數(shù)據(jù)量近3PB,單日分析查詢次數(shù)超過1億
  • 阿里巴巴集團(tuán)內(nèi)某單個(gè)AnalyticDB集群超過2000臺(tái)節(jié)點(diǎn)規(guī)模
  • 云上某業(yè)務(wù)實(shí)時(shí)寫入壓力高達(dá)1000w TPS
  • 菜鳥網(wǎng)絡(luò)某數(shù)據(jù)業(yè)務(wù)極度復(fù)雜分析場(chǎng)景,查詢QPS 100+

導(dǎo)入導(dǎo)出

靈活的數(shù)據(jù)導(dǎo)入導(dǎo)出能力對(duì)一個(gè)實(shí)時(shí)數(shù)倉來說至關(guān)重要,AnalyticDB當(dāng)前既支持通過阿里云數(shù)據(jù)傳輸服務(wù)DTS、DataWorks數(shù)據(jù)集成從各種外部數(shù)據(jù)源導(dǎo)入入庫,同時(shí)也在不斷完善自身的數(shù)據(jù)導(dǎo)入能力。整體導(dǎo)入導(dǎo)出能力如下圖(其中導(dǎo)入部分?jǐn)?shù)據(jù)源當(dāng)前已支持,部分在開發(fā)中,即將發(fā)布)。

數(shù)據(jù)導(dǎo)入

首先,由于AnalyticDB兼容MySQL5.x系列,支持通過MySQL JDBC方式把數(shù)據(jù)insert入庫。為了獲得最佳寫入性能,AnalyticDB提供了Client SDK,實(shí)現(xiàn)分區(qū)聚合寫的優(yōu)化,相比通過JDBC單條insert,寫入性能有10倍以上提升。對(duì)于應(yīng)用端業(yè)務(wù)邏輯需要直接寫入AnalyticDB的場(chǎng)景,推薦使用AnalyticDB Client SDK。

同時(shí),對(duì)于快速上傳本地結(jié)構(gòu)化的文本文件,可以使用基于AnalyticDB Client SDK開發(fā)的Uploader工具。對(duì)于特別大的文件,可以拆分后使用uploader工具進(jìn)行并行導(dǎo)入。

另外,對(duì)于OSS,MaxCompute這樣的外部數(shù)據(jù)源,AnalyticDB通過分布式的Connector Service數(shù)據(jù)導(dǎo)入服務(wù)并發(fā)讀取并寫入到相應(yīng)DB中。Connector Service還將支持訂閱模式,從Kafka,MQ,RDS等動(dòng)態(tài)數(shù)據(jù)源把數(shù)據(jù)導(dǎo)入到相應(yīng)DB中。AnalyticDB對(duì)大數(shù)據(jù)生態(tài)的Logstash,F(xiàn)luentd,F(xiàn)lume等日志收集端、ETL工具等通過相應(yīng)插件支持,能夠快速把數(shù)據(jù)寫入相應(yīng)DB。

今天在阿里巴巴集團(tuán)內(nèi),每天有數(shù)萬張表從MaxCompute導(dǎo)入到AnalyticDB中進(jìn)行在線分析,其中大量導(dǎo)入任務(wù)單表數(shù)據(jù)大小在TB級(jí)、數(shù)據(jù)量近千億。

數(shù)據(jù)導(dǎo)出

AnalyticDB目前支持?jǐn)?shù)據(jù)導(dǎo)出到OSS和MaxCompute,業(yè)務(wù)場(chǎng)景主要是把相應(yīng)查詢結(jié)果在外部存儲(chǔ)進(jìn)行保存歸檔,實(shí)現(xiàn)原理類似insert from select操作。insert from select是把查詢結(jié)果寫入到內(nèi)部表,而導(dǎo)出操作則是寫入外部存儲(chǔ), 通過改進(jìn)實(shí)現(xiàn)機(jī)制,可以方便地支持更多的導(dǎo)出數(shù)據(jù)源。

核心技術(shù)

高性能SQL Parser

AnalyticDB經(jīng)過數(shù)年的發(fā)展,語法解析器也經(jīng)歷了多次更新迭代。曾經(jīng)使用過業(yè)界主流的 Antlr(http://www.antlr.org),JavaCC(https://javacc.org)等Parser生成器作為SQL 語法解析器,但是兩者在長期、大規(guī)模、復(fù)雜查詢場(chǎng)景下,Parser的性能、語法兼容、API設(shè)計(jì)等方面不滿足要求,于是我們引入了自研的SQL Parser組件FastSQL。

領(lǐng)先業(yè)界的Parser性能

AnalyticDB主打的場(chǎng)景是高并發(fā)、低延時(shí)的在線化分析,對(duì)SQL Parser性能要求很高,批量實(shí)時(shí)寫入等場(chǎng)景要求更加苛刻。FastSQL通過多種技術(shù)優(yōu)化提升Parser性能,例如:

  • 快速對(duì)比:使用64位hash算法加速關(guān)鍵字匹配,使用fnv_1a_64 hash算法,在讀取identifier的同時(shí)計(jì)算好hash值,并利用hash64低碰撞概率的特點(diǎn),使用64位hash code直接比較,比常規(guī)Lexer先讀取identifier,在查找SymbolTable速度更快。
  • 高性能的數(shù)值Parser:Java自帶的Integer.parseInt()/Float.parseFloat()需要構(gòu)造字符串再做parse,F(xiàn)astSQL改進(jìn)后可以直接在原文本上邊讀取邊計(jì)算數(shù)值。
  • 分支預(yù)測(cè):在insert values中,出現(xiàn)常量字面值的概率比出現(xiàn)其他的token要高得多,通過分支預(yù)測(cè)可以減少判斷提升性能。

以TPC-DS99個(gè)Query對(duì)比來看,F(xiàn)astSQL比Antlr Parser(使用Antlr生成)平均快20倍,比JSQLParser(使用JavaCC生成)平均快30倍,在批量Insert場(chǎng)景、多列查詢場(chǎng)景下,使用FastSQL后速度提升30~50倍。

無縫結(jié)合優(yōu)化器

在結(jié)合AnalyticDB的優(yōu)化器的SQL優(yōu)化實(shí)踐中,F(xiàn)astSQL不斷將SQL Rewrite的優(yōu)化能力前置化到SQL Parser中實(shí)現(xiàn),通過與優(yōu)化器的SQL優(yōu)化能力協(xié)商,將盡可能多的表達(dá)式級(jí)別優(yōu)化前置化到SQL Parser中,使得優(yōu)化器能更加專注于基于代價(jià)和成本的優(yōu)化(CBO,Cost-Based Optimization)上,讓優(yōu)化器能更多的集中在理解計(jì)算執(zhí)行計(jì)劃優(yōu)化上。FastSQL在AST Tree上實(shí)現(xiàn)了許多SQL Rewrite的能力,例如:

  • 常量折疊:
  1. SELECT * FROM t1 t 
  2. WHERE comm_week  
  3.   BETWEEN CAST(date_format(date_add('day',-day_of_week('20180605'), 
  4.                              date('20180605')),'%Y%m%d'AS bigint
  5.         AND CAST(date_format(date_add('day',-day_of_week('20180605'
  6.                             ,date('20180605')),'%Y%m%d'AS bigint
  7. ------> 
  8. SELECT * FROM t1 t 
  9. WHERE comm_week BETWEEN20180602AND20180602 
  • 函數(shù)變換:
  1. SELECT * FROM t1 t 
  2. WHERE DATE_FORMAT(t."pay_time",'%Y%m%d')>='20180529' 
  3.     AND DATE_FORMAT(t."pay_time",'%Y%m%d')<='20180529' 
  4. ------> 
  5. SELECT * FROM t1 t 
  6. WHERE t."pay_time">= TIMESTAMP'2018-05-29 00:00:00' 
  7. AND t."pay_time"TIMESTAMP'2018-05-30 00:00:00' 
  • 表達(dá)式轉(zhuǎn)換:
  1. SELECT a, b FROM t1 
  2. WHERE b +1=10; 
  3. ------> 
  4. SELECT a, b FROM t1 
  5. WHERE b =9; 
  • 函數(shù)類型推斷:
  1. -- f3類型是TIMESTAMP類型 
  2. SELECT concat(f3,1) 
  3. FROM nation; 
  4. ------> 
  5. SELECT concat(CAST(f3 AS CHAR),'1'
  6. FROM nation; 
  • 常量推斷:
  1. SELECT * FROM t 
  2. WHERE a < b AND b = c AND a =5 
  3. ------> 
  4. SELECT * FROM t 
  5. WHERE b >5AND a =5AND b = c 
  • 語義去重:
  1. SELECT * FROM t1 
  2. WHERE max_adate >'2017-05-01' 
  3.     AND max_adate !='2017-04-01' 
  4. ------> 
  5. SELECT * FROM t1 
  6. WHERE max_adate > DATE '2017-05-01' 

玄武存儲(chǔ)引擎

為保證大吞吐寫入,以及高并發(fā)低時(shí)延響應(yīng),AnalyticDB自研存儲(chǔ)引擎玄武,采用多項(xiàng)創(chuàng)新的技術(shù)架構(gòu)。玄武存儲(chǔ)引擎采用讀/寫實(shí)例分離架構(gòu),讀節(jié)點(diǎn)和寫節(jié)點(diǎn)可分別獨(dú)立擴(kuò)展,提供寫入吞吐或者查詢計(jì)算能力。在此架構(gòu)下大吞吐數(shù)據(jù)寫入不影響查詢分析性能。同時(shí)玄武存儲(chǔ)引擎構(gòu)筑了智能全索引體系,保證絕大部分計(jì)算基于索引完成,保證任意組合條件查詢的毫秒級(jí)響應(yīng)。

讀寫分離架構(gòu)支持大吞吐寫入

傳統(tǒng)數(shù)據(jù)倉庫并沒有將讀和寫分開處理,即這些數(shù)據(jù)庫進(jìn)程/線程處理請(qǐng)求的時(shí)候,不管讀寫都會(huì)在同一個(gè)實(shí)例的處理鏈路上進(jìn)行。因此所有的請(qǐng)求都共享同一份資源(內(nèi)存資源、鎖資源、IO資源),并相互影響。在查詢請(qǐng)求和寫入吞吐都很高的時(shí)候,會(huì)存在嚴(yán)重的資源競(jìng)爭,導(dǎo)致查詢性能和寫入吞吐都下降。

為了解決這個(gè)問題,玄武存儲(chǔ)引擎設(shè)計(jì)了讀寫分離的架構(gòu)。如下圖所示,玄武存儲(chǔ)引擎有兩類關(guān)鍵的節(jié)點(diǎn):Buffer Node和Compute Node。Buffer Node專門負(fù)責(zé)處理寫請(qǐng)求,Compute Node專門負(fù)責(zé)查詢請(qǐng)求,Buffer Node和Compute Node完全獨(dú)立并互相不影響,因此,讀寫請(qǐng)求會(huì)在兩個(gè)完全不相同的鏈路中處理。上層的Front Node會(huì)把讀寫請(qǐng)求分別路由給Buffer Node和Compute Node。

實(shí)時(shí)寫入鏈路:

  • 業(yè)務(wù)實(shí)時(shí)數(shù)據(jù)通過JDBC/ODBC協(xié)議寫入到Front Node。
  • Front Node根據(jù)實(shí)時(shí)數(shù)據(jù)的hash分區(qū)列值,路由到相應(yīng)Buffer Node。
  • Buffer Node將該實(shí)時(shí)數(shù)據(jù)的內(nèi)容(類似于WAL)提交到盤古分布式文件系統(tǒng),同時(shí)更新實(shí)時(shí)數(shù)據(jù)版本,并返回Front Node,F(xiàn)ront Node返回寫入成功響應(yīng)到客戶端。
  • Buffer Node同時(shí)會(huì)異步地把實(shí)時(shí)數(shù)據(jù)內(nèi)容推送到Compute Node,Compute Node消費(fèi)該實(shí)時(shí)數(shù)據(jù)并構(gòu)建實(shí)時(shí)數(shù)據(jù)輕量級(jí)索引。
  • 當(dāng)實(shí)時(shí)數(shù)據(jù)積攢到一定量時(shí),Buffer Node觸發(fā)后臺(tái)Merge Baseline作業(yè),對(duì)實(shí)時(shí)數(shù)據(jù)構(gòu)建完全索引并與基線數(shù)據(jù)合并。

實(shí)時(shí)查詢鏈路:

  • 業(yè)務(wù)實(shí)時(shí)查詢請(qǐng)求通過JDBC/ODBC協(xié)議發(fā)送到Front Node。
  • Front Node首先從Buffer Node拿到當(dāng)前最新的實(shí)時(shí)數(shù)據(jù)版本,并把該版本隨執(zhí)行計(jì)劃一起下發(fā)到Compute Node。
  • Compute Node檢查本地實(shí)時(shí)數(shù)據(jù)版本是否滿足實(shí)時(shí)查詢要求,若滿足,則直接執(zhí)行并返回?cái)?shù)據(jù)。若不滿足,需先到Buffer Node把指定版本的實(shí)時(shí)數(shù)據(jù)拖到本地,再執(zhí)行查詢,以保證查詢的實(shí)時(shí)性(強(qiáng)一致)。

AnalyticDB提供強(qiáng)實(shí)時(shí)和弱實(shí)時(shí)兩種模式,強(qiáng)實(shí)時(shí)模式執(zhí)行邏輯描述如上。弱實(shí)時(shí)模式下,F(xiàn)ront Node查詢請(qǐng)求則不帶版本下發(fā),返回結(jié)果的實(shí)時(shí)取決于Compute Node對(duì)實(shí)時(shí)數(shù)據(jù)的處理速度,一般有秒極延遲。所以強(qiáng)實(shí)時(shí)在保證數(shù)據(jù)一致性的前提下,當(dāng)實(shí)時(shí)數(shù)據(jù)寫入量比較大時(shí)對(duì)查詢性能會(huì)有一定的影響。

高可靠性

玄武存儲(chǔ)引擎為Buffer Node和Compute Node提供了高可靠機(jī)制。用戶可以定義Buffer Node和Compute Node的副本數(shù)目(默認(rèn)為2),玄武保證同一個(gè)數(shù)據(jù)分區(qū)的不同副本一定是存放在不同的物理機(jī)器上。Compute Node的組成采用了對(duì)等的熱副本服務(wù)機(jī)制,所有Compute Node節(jié)點(diǎn)都可以參與計(jì)算。另外,Computed Node的正常運(yùn)行并不會(huì)受到Buffer Node節(jié)點(diǎn)異常的影響。如果Buffer Node節(jié)點(diǎn)異常導(dǎo)致Compute Node無法正常拉取最新版本的數(shù)據(jù),Compute Node會(huì)直接從盤古上獲取數(shù)據(jù)(即便這樣需要忍受更高的延遲)來保證查詢的正常執(zhí)行。數(shù)據(jù)在Compute Node上也是備份存儲(chǔ)。如下圖所示,數(shù)據(jù)是通過分區(qū)存放在不同的ComputeNode上,具有相同hash值的分區(qū)會(huì)存儲(chǔ)在同一個(gè)Compute Node上。數(shù)據(jù)分區(qū)的副本會(huì)存儲(chǔ)在其他不同的Compute Node上,以提供高可靠性。

高擴(kuò)展性

玄武的兩個(gè)重要特性設(shè)計(jì)保證了其高可擴(kuò)展性:1)Compute Node和Buffer Node都是無狀態(tài)的,他們可以根據(jù)業(yè)務(wù)負(fù)載需求進(jìn)行任意的增減;2)玄武并不實(shí)際存儲(chǔ)數(shù)據(jù),而是將數(shù)據(jù)存到底層的盤古系統(tǒng)中,這樣,當(dāng)Compute Node和Buffer Node的數(shù)量進(jìn)行改變時(shí),并不需要進(jìn)行實(shí)際的數(shù)據(jù)遷移工作。

為計(jì)算而生的存儲(chǔ)

數(shù)據(jù)存儲(chǔ)格式

傳統(tǒng)關(guān)系型數(shù)據(jù)庫一般采用行存儲(chǔ)(Row-oriented Storage)加B-tree索引,優(yōu)勢(shì)在于其讀取多列或所有列(SELECT *)場(chǎng)景下的性能,典型的例子如MySQL的InnoDB引擎。但是在讀取單列、少數(shù)列并且行數(shù)很多的場(chǎng)景下,行存儲(chǔ)會(huì)存在嚴(yán)重的讀放大問題。

數(shù)據(jù)倉庫系統(tǒng)一般采用列存儲(chǔ)(Column-oriented Storage),優(yōu)勢(shì)在于其單列或少數(shù)列查詢場(chǎng)景下的性能、更高的壓縮率(很多時(shí)候一個(gè)列的數(shù)據(jù)具有相似性,并且根據(jù)不同列的值類型可以采用不同的壓縮算法)、列聚合計(jì)算(SUM, AVG, MAX, etc.)場(chǎng)景下的性能。但是如果用戶想要讀取整行的數(shù)據(jù),列存儲(chǔ)會(huì)帶來大量的隨機(jī)IO,影響系統(tǒng)性能。

為了發(fā)揮行存儲(chǔ)和列存儲(chǔ)各自的優(yōu)勢(shì),同時(shí)避免兩者的缺點(diǎn),AnalyticDB設(shè)計(jì)并實(shí)現(xiàn)了全新的行列混存模式。如下圖所示:

  • 對(duì)于一張表,每k行數(shù)據(jù)組成一個(gè)Row Group。在每個(gè)Row Group中,每列數(shù)據(jù)連續(xù)的存放在單獨(dú)的block中,每Row Group在磁盤上連續(xù)存放。
  • Row Group內(nèi)列block的數(shù)據(jù)可按指定列(聚集列)排序存放,好處是在按該列查詢時(shí)顯著減少磁盤隨機(jī)IO次數(shù)。
  • 每個(gè)列block可開啟壓縮。

行列混存存儲(chǔ)相應(yīng)的元數(shù)據(jù)包括:分區(qū)元數(shù)據(jù),列元數(shù)據(jù),列block元數(shù)據(jù)。其中分區(qū)元數(shù)據(jù)包含該分區(qū)總行數(shù),單個(gè)block中的列行數(shù)等信息;列元數(shù)據(jù)包括該列值類型、整列的MAX/MIN值、NULL值數(shù)目、直方圖信息等,用于加速查詢;列block元數(shù)據(jù)包含該列在單個(gè)Row Group中對(duì)應(yīng)的MAX/MIN/SUM、總條目數(shù)(COUNT)等信息,同樣用于加速查詢。

全索引計(jì)算

用戶的復(fù)雜查詢可能會(huì)涉及到各種不同的列,為了保證用戶的復(fù)雜查詢能夠得到秒級(jí)響應(yīng),玄武存儲(chǔ)引擎在行列混合存儲(chǔ)的基礎(chǔ)上,為基線數(shù)據(jù)(即歷史數(shù)據(jù))所有列都構(gòu)建了索引。玄武會(huì)根據(jù)列的數(shù)據(jù)特征和空間消耗情況自動(dòng)選擇構(gòu)建倒排索引、位圖索引或區(qū)間樹索引等,而用的最多的是倒排索引。

如上圖所示,在倒排索引中,每列的數(shù)值對(duì)應(yīng)索引的key,該數(shù)值對(duì)應(yīng)的行號(hào)對(duì)應(yīng)索引的value,同時(shí)所有索引的key都會(huì)進(jìn)行排序。依靠全列索引,交集、并集、差集等數(shù)據(jù)庫基礎(chǔ)操作可以高性能地完成。如下圖所示,用戶的一個(gè)復(fù)雜查詢包含著對(duì)任意列的條件篩選。玄武會(huì)根據(jù)每個(gè)列的條件,去索引中篩選滿足條件的行號(hào),然后再將每列篩選出的行號(hào),進(jìn)行交、并、差操作,篩選出最終滿足所有條件的行號(hào)。玄武會(huì)依據(jù)這些行號(hào)去訪問實(shí)際的數(shù)據(jù),并返回給用戶。通常經(jīng)過篩選后,滿足條件的行數(shù)可能只占總行數(shù)的萬分之一到十萬分之一。因此,全列索引幫助玄武在執(zhí)行查詢請(qǐng)求的時(shí)候,大大減小需要實(shí)際遍歷的行數(shù),進(jìn)而大幅提升查詢性能,滿足任意復(fù)雜查詢秒級(jí)響應(yīng)的需求。

使用全列索引給設(shè)計(jì)帶來了一個(gè)很大挑戰(zhàn):需要對(duì)大量數(shù)據(jù)構(gòu)建索引,這會(huì)是一個(gè)非常耗時(shí)的過程。如果像傳統(tǒng)數(shù)據(jù)庫那樣在數(shù)據(jù)寫入的路徑上進(jìn)行索引構(gòu)建,那么這會(huì)嚴(yán)重影響寫入的吞吐,而且會(huì)嚴(yán)重拖慢查詢的性能,影響用戶體驗(yàn)。為了解決這個(gè)挑戰(zhàn),玄武采用了異步構(gòu)建索引的方式。當(dāng)寫入請(qǐng)求到達(dá)后,玄武把寫SQL持久化到盤古,然后直接返回,并不進(jìn)行索引的構(gòu)建。

當(dāng)這些未構(gòu)建索引的數(shù)據(jù)(稱為實(shí)時(shí)數(shù)據(jù))積累到一定數(shù)量時(shí),玄武會(huì)開啟多個(gè)MapReduce任務(wù),來對(duì)這些實(shí)時(shí)數(shù)據(jù)進(jìn)行索引的構(gòu)建,并將實(shí)時(shí)數(shù)據(jù)及其索引,同當(dāng)前版本的基線數(shù)據(jù)(歷史數(shù)據(jù))及其索引進(jìn)行多版本歸并,形成新版本的基線數(shù)據(jù)和索引。這些MapReduce任務(wù)通過伏羲進(jìn)行分布式調(diào)度和執(zhí)行,異步地完成索引的構(gòu)建。這種異步構(gòu)建索引的方式,既不影響AnalyticDB的高吞吐寫入,也不影響AnalyticDB的高性能查詢。

異步構(gòu)建索引的機(jī)制還會(huì)引入一個(gè)新問題:在進(jìn)行MapReduce構(gòu)建索引的任務(wù)之前,新寫入的實(shí)時(shí)數(shù)據(jù)是沒有索引的,如果用戶的查詢會(huì)涉及到實(shí)時(shí)數(shù)據(jù),查詢性能有可能會(huì)受到影響。玄武采用為實(shí)時(shí)數(shù)據(jù)構(gòu)建排序索引(Sorted Index)的機(jī)制來解決這個(gè)問題。

如下圖所示,玄武在將實(shí)時(shí)數(shù)據(jù)以block形式刷到磁盤之前,會(huì)根據(jù)每一列的實(shí)時(shí)數(shù)據(jù)生成對(duì)應(yīng)的排序索引。排序索引實(shí)際是一個(gè)行號(hào)數(shù)組,對(duì)于升序排序索引來說,行號(hào)數(shù)組的第一個(gè)數(shù)值是實(shí)時(shí)數(shù)據(jù)最小值對(duì)應(yīng)的行號(hào),第二個(gè)數(shù)值是實(shí)時(shí)數(shù)據(jù)第二小值對(duì)應(yīng)的行號(hào),以此類推。這種情況下,對(duì)實(shí)時(shí)數(shù)據(jù)的搜索復(fù)雜度會(huì)從O(N)降低為O(lgN)。排序索引大小通常很小(60KB左右),因此,排序索引可以緩存在內(nèi)存中,以加速查詢。

羲和計(jì)算引擎

針對(duì)低延遲高并發(fā)的在線分析場(chǎng)景需求,AnalyticDB自研了羲和大規(guī)模分析引擎,其中包括了基于流水線模型的分布式并行計(jì)算引擎,以及基于規(guī)則 (Rule-Based Optimizer,RBO) 和代價(jià)(Cost-Based Optimizer,CBO)的智能查詢優(yōu)化器。

優(yōu)化器

優(yōu)化規(guī)則的豐富程度是能否產(chǎn)生最優(yōu)計(jì)劃的一個(gè)重要指標(biāo)。因?yàn)橹挥锌蛇x方案足夠多時(shí),才有可能選到最優(yōu)的執(zhí)行計(jì)劃。AnalyticDB提供了豐富的關(guān)系代數(shù)轉(zhuǎn)換規(guī)則,用來確保不會(huì)遺漏最優(yōu)計(jì)劃。

基礎(chǔ)優(yōu)化規(guī)則:

  • 裁剪規(guī)則:列裁剪、分區(qū)裁剪、子查詢裁剪
  • 下推/合并規(guī)則:謂詞下推、函數(shù)下推、聚合下推、Limit下推
  • 去重規(guī)則:Project去重、Exchange去重、Sort去重
  • 常量折疊/謂詞推導(dǎo)

探測(cè)優(yōu)化規(guī)則:

  • Joins:BroadcastHashJoin、RedistributedHashJoin、NestLoopIndexJoin
  • Aggregate:HashAggregate、SingleAggregate
  • JoinReordering
  • GroupBy下推、Exchange下推、Sort下推

高級(jí)優(yōu)化規(guī)則:CTE

例如下圖中,CTE的優(yōu)化規(guī)則的實(shí)現(xiàn)將兩部分相同的執(zhí)行邏輯合為一個(gè)。通過類似于最長公共子序列的算法,對(duì)整個(gè)執(zhí)行計(jì)劃進(jìn)行遍歷,并對(duì)一些可以忽略的算子進(jìn)行特殊處理,如Projection,最終達(dá)到減少計(jì)算的目的。

單純基于規(guī)則的優(yōu)化器往往過于依賴規(guī)則的順序,同樣的規(guī)則不同的順序會(huì)導(dǎo)致生成的計(jì)劃完全不同,結(jié)合基于代價(jià)的優(yōu)化器則可以通過嘗試各種可能的執(zhí)行計(jì)劃,達(dá)到全局最優(yōu)。

AnalyticDB的代價(jià)優(yōu)化器基于Cascade模型,執(zhí)行計(jì)劃經(jīng)過Transform模塊進(jìn)行了等價(jià)關(guān)系代數(shù)變換,對(duì)可能的等價(jià)執(zhí)行計(jì)劃,估算出按Cost Model量化的計(jì)劃代價(jià),并從中最終選擇出代價(jià)最小的執(zhí)行計(jì)劃通過Plan Generation模塊輸出,存入Plan Cache(計(jì)劃緩存),以降低下一次相同查詢的優(yōu)化時(shí)間。

在線分析的場(chǎng)景對(duì)優(yōu)化器有很高的要求,AnalyticDB為此開發(fā)了三個(gè)關(guān)鍵特性:存儲(chǔ)感知優(yōu)化、動(dòng)態(tài)統(tǒng)計(jì)信息收集和計(jì)劃緩存。

存儲(chǔ)層感知優(yōu)化

生成分布式執(zhí)行計(jì)劃時(shí),AnalyticDB優(yōu)化器可以充分利用底層存儲(chǔ)的特性,特別是在Join策略選擇,Join Reorder和謂詞下推方面。

  • 底層數(shù)據(jù)的哈希分布策略將會(huì)影響Join策略的選擇?;谝?guī)則的優(yōu)化器,在生成Join的執(zhí)行計(jì)劃時(shí),如果對(duì)數(shù)據(jù)物理分布特性的不感知,會(huì)強(qiáng)制增加一個(gè)數(shù)據(jù)重分布的算子來保證其執(zhí)行語義的正確。 數(shù)據(jù)重分布帶來的物理開銷非常大,涉及到數(shù)據(jù)的序列化、反序列化、網(wǎng)絡(luò)開銷等等,因此避免多次數(shù)據(jù)重分布對(duì)于分布式計(jì)算是非常重要的。除此之外,優(yōu)化器也會(huì)考慮對(duì)數(shù)據(jù)庫索引的使用,進(jìn)一步減少Join過程中構(gòu)建哈希的開銷。
  • 調(diào)整Join順序時(shí),如果大多數(shù)Join是在分區(qū)列,優(yōu)化器將避免生成Bushy Tree,而更偏向使用Left Deep Tree,并盡量使用現(xiàn)有索引進(jìn)行查找。

  • 優(yōu)化器更近一步下推了謂詞和聚合。聚合函數(shù),比如count(),和查詢過濾可以直接基于索引計(jì)算。

所有這些組合降低了查詢延遲,同時(shí)提高集群利用率,從而使得AnalyticDB能輕松支持高并發(fā)。

動(dòng)態(tài)統(tǒng)計(jì)信息收集

統(tǒng)計(jì)信息是優(yōu)化器在做基于代價(jià)查詢優(yōu)化所需的基本信息,通常包括有關(guān)表、列和索引等的統(tǒng)計(jì)信息。傳統(tǒng)數(shù)據(jù)倉庫僅收集有限的統(tǒng)計(jì)信息,例如列上典型的最常值(MFV)。商業(yè)數(shù)據(jù)庫為用戶提供了收集統(tǒng)計(jì)信息的工具,但這通常取決于DBA的經(jīng)驗(yàn),依賴DBA來決定收集哪些統(tǒng)計(jì)數(shù)據(jù),并依賴于服務(wù)或工具供應(yīng)商。

上述方法收集的統(tǒng)計(jì)數(shù)據(jù)通常都是靜態(tài)的,它可能需要在一段時(shí)間后,或者當(dāng)數(shù)據(jù)更改達(dá)到一定程度,來重新收集。但是,隨著業(yè)務(wù)應(yīng)用程序變得越來越復(fù)雜和動(dòng)態(tài),預(yù)定義的統(tǒng)計(jì)信息收集可能無法以更有針對(duì)性的方式幫助查詢。例如,用戶可以選擇不同的聚合列和列數(shù),其組合可能會(huì)有很大差異。但是,在查詢生成之前很難預(yù)測(cè)這樣的組合。因此,很難在統(tǒng)計(jì)收集時(shí)決定正確統(tǒng)計(jì)方案。但是,此類統(tǒng)計(jì)信息可幫助優(yōu)化器做出正確決定。

我們?cè)O(shè)計(jì)了一個(gè)查詢驅(qū)動(dòng)的動(dòng)態(tài)統(tǒng)計(jì)信息收集機(jī)制來解決此問題。守護(hù)程序動(dòng)態(tài)監(jiān)視傳入的查詢工作負(fù)載和特點(diǎn)以提取其查詢模式,并基于查詢模式,分析缺失和有益的統(tǒng)計(jì)數(shù)據(jù)。在此分析和預(yù)測(cè)之上,異步統(tǒng)計(jì)信息收集任務(wù)在后臺(tái)執(zhí)行。這項(xiàng)工作旨在減少收集不必要的統(tǒng)計(jì)數(shù)據(jù),同時(shí)使大多數(shù)即將到來的查詢受益。對(duì)于前面提到的聚合示例,收集多列統(tǒng)計(jì)信息通常很昂貴,尤其是當(dāng)用戶表有大量列的時(shí)候。根據(jù)我們的動(dòng)態(tài)工作負(fù)載分析和預(yù)測(cè),可以做到僅收集必要的多列統(tǒng)計(jì)信息,同時(shí),優(yōu)化器能夠利用這些統(tǒng)計(jì)數(shù)據(jù)來估計(jì)聚合中不同選項(xiàng)的成本并做出正確的決策。

計(jì)劃緩存

從在線應(yīng)用案件看,大多數(shù)客戶都有一個(gè)共同的特點(diǎn),他們經(jīng)常反復(fù)提交類似的查詢。在這種情況下,計(jì)劃緩存變得至關(guān)重要。為了提高緩存命中率,AnalyticDB不使用原始SQL文本作為搜索鍵來緩存。相反,SQL語句首先通過重寫并參數(shù)化來提取模式。例如,查詢 “SELECT * FROM t1 WHERE a = 5 + 5”將轉(zhuǎn)化為“SELECT * FROM t1 WHERE a =?”。參數(shù)化的SQL模版將被作為計(jì)劃緩存的關(guān)鍵字,如果緩存命中,AnalyticDB將根據(jù)新查詢進(jìn)行參數(shù)綁定。由于這個(gè)改動(dòng),即使使用有限的緩存大小,優(yōu)化器在生產(chǎn)環(huán)境也可以保持高達(dá)90%以上的命中率,而之前只能達(dá)到40%的命中率。

這種方法仍然有一個(gè)問題。假設(shè)我們?cè)诹衋上有索引,“SELECT * FROM t1 WHERE a = 5”的優(yōu)化計(jì)劃可以將索引掃描作為其最佳訪問路徑。但是,如果新查詢是“SELECT * FROM t1 WHERE a = 0”并且直方圖告訴我們數(shù)值0在表t1占大多數(shù),那么索引掃描可能不如全表掃描有效。在這種情況下,使用緩存中的計(jì)劃并不是一個(gè)好的決定。為了避免這類問題,AnalyticDB提供了一個(gè)功能Literal Classification,使用列的直方圖對(duì)該列的值進(jìn)行分類,僅當(dāng)與模式相關(guān)聯(lián)的常量“5”的數(shù)據(jù)分布與新查詢中常量“0”的數(shù)據(jù)分布類似時(shí),才實(shí)際使用高速緩存的計(jì)劃。否則,仍會(huì)對(duì)新查詢執(zhí)行常規(guī)優(yōu)化。

執(zhí)行引擎

在優(yōu)化器之下,AnalyticDB在MPP架構(gòu)基礎(chǔ)上,采用流水線執(zhí)行的DAG架構(gòu),構(gòu)建了一個(gè)適用于低延遲和高吞吐量工作負(fù)載的執(zhí)行器。如下圖所示,當(dāng)涉及到多個(gè)表之間非分區(qū)列JOIN時(shí),CN(MPP Worker)會(huì)先進(jìn)行data exchange (shuffling)然后再本地JOIN (SourceTask),aggregate后發(fā)送到上一個(gè)stage(MiddleTask),最后匯總到Output Task。由于絕大多情況都是in-memory計(jì)算(除復(fù)雜ETL類查詢,盡量無中間Stage 落盤)且各個(gè)stage之間都是pipeline方式協(xié)作,性能上要比MapReduce方式快一個(gè)數(shù)量級(jí)。

在接下來的幾節(jié)中,將介紹其中三種特性,包括混合工作負(fù)載管理,CodeGen和矢量化執(zhí)行。

混合工作負(fù)載管理

作為一套完備的實(shí)時(shí)數(shù)倉解決方案,AnalyticDB中既有需要較低響應(yīng)時(shí)間的高并發(fā)查詢,也有類似ETL的批處理,兩者爭用相同資源。傳統(tǒng)數(shù)倉體系往往在這兩個(gè)方面的兼顧性上做的不夠好。

AnalyticDB worker接收coordinator下發(fā)的任務(wù), 負(fù)責(zé)該任務(wù)的物理執(zhí)行計(jì)劃的實(shí)際執(zhí)行。這項(xiàng)任務(wù)可以來自不同的查詢, worker會(huì)將任務(wù)中的物理執(zhí)行計(jì)劃按照既定的轉(zhuǎn)換規(guī)則轉(zhuǎn)換成對(duì)應(yīng)的operator,物理執(zhí)行計(jì)劃中的每一個(gè)Stage會(huì)被轉(zhuǎn)換成一個(gè)或多個(gè)operator。

執(zhí)行引擎已經(jīng)可以做到stage/operator級(jí)別中斷和Page級(jí)別換入換出,同時(shí)線程池在所有同時(shí)運(yùn)行的查詢間共享。但是,這之上仍然需要確保高優(yōu)先級(jí)查詢可以獲得更多計(jì)算資源。

根據(jù)經(jīng)驗(yàn),客戶總是期望他們的短查詢即使當(dāng)系統(tǒng)負(fù)載很重的時(shí)候也能快速完成。為了滿足這些要求,基于以上場(chǎng)景,通過時(shí)間片的分配比例來體現(xiàn)不同查詢的優(yōu)先級(jí),AnalyticDB實(shí)現(xiàn)了一個(gè)簡單版本的類Linux kernel 的調(diào)度算法。系統(tǒng)記錄了每一個(gè)查詢的總執(zhí)行耗時(shí),查詢總耗時(shí)又是通過每一個(gè)Task耗時(shí)來進(jìn)行加權(quán)統(tǒng)計(jì)的,最終在查詢層面形成了一顆紅黑樹,每次總是挑選最左側(cè)節(jié)點(diǎn)進(jìn)行調(diào)度,每次取出或者加入(被喚醒以及重新入隊(duì))都會(huì)重新更新這棵樹,同樣的,在Task被喚醒加入這顆樹的時(shí)候,執(zhí)行引擎考慮了補(bǔ)償機(jī)制,即時(shí)間片耗時(shí)如果遠(yuǎn)遠(yuǎn)低于其他Task的耗時(shí),確保其在整個(gè)樹里面的位置,同時(shí)也避免了因?yàn)殚L時(shí)間的阻塞造成的饑餓,類似于CFS 調(diào)度算法中的vruntime補(bǔ)償機(jī)制。

這個(gè)設(shè)計(jì)雖然有效解決了慢查詢占滿資源,導(dǎo)致其他查詢得不到執(zhí)行的問題,卻無法保障快查詢的請(qǐng)求延遲。這是由于軟件層面的多線程執(zhí)行機(jī)制,線程個(gè)數(shù)大于了實(shí)際的CPU個(gè)數(shù)。在實(shí)際的應(yīng)用中,計(jì)算線程的個(gè)數(shù)往往是可用Core的2倍。這也就是說,即使快查詢的算子得到了計(jì)算線程資源進(jìn)行計(jì)算,也會(huì)在CPU層面與慢查詢的算子形成競(jìng)爭。所下圖所示,快查詢的算子計(jì)算線程被調(diào)度到VCore1上,該算子在VCore1上會(huì)與慢查詢的計(jì)算線程形成競(jìng)爭。另外在物理Core0上,也會(huì)與VCore0上的慢查詢的計(jì)算線程形成競(jìng)爭。

在Kernel sched模塊中,對(duì)于不同優(yōu)先級(jí)的線程之間的搶占機(jī)制,已經(jīng)比較完善,且時(shí)效性比較高。因而,通過引入kernel層面的控制可以有效解決快查詢低延遲的問題,且無需對(duì)算子的實(shí)現(xiàn)進(jìn)行任何的改造。執(zhí)行引擎讓高優(yōu)先級(jí)的線程來執(zhí)行快查詢的算子,低優(yōu)先級(jí)的線程來執(zhí)行慢查詢的算子。由于高優(yōu)先級(jí)線程搶占低優(yōu)先級(jí)線程的機(jī)制,快查詢算子自然會(huì)搶占慢查詢的算子。此外,由于高優(yōu)先級(jí)線程在Kernel sched模塊調(diào)度中,具有較高的優(yōu)先級(jí),也避免了快慢查詢算子在vcore層面的CPU競(jìng)爭。

同樣的在實(shí)際應(yīng)用中是很難要求用戶來辨別快慢查詢,因?yàn)橛脩舻臉I(yè)務(wù)本身可能就沒有快慢業(yè)務(wù)之分。另外對(duì)于在線查詢,查詢的計(jì)算量也是不可預(yù)知的。為此,計(jì)算引擎在Runtime層面引入了快慢查詢的識(shí)別機(jī)制,參考Linux kernel中vruntime的方式,對(duì)算子的執(zhí)行時(shí)間、調(diào)度次數(shù)等信息進(jìn)行統(tǒng)計(jì),當(dāng)算子的計(jì)算量達(dá)到給定的慢查詢的閾值后,會(huì)把算子從高優(yōu)先級(jí)的線程轉(zhuǎn)移到低優(yōu)先級(jí)的線程中。這有效提高了在壓力測(cè)試下快查詢的響應(yīng)時(shí)間。

代碼生成器

Dynamic code generation(CodeGen)普遍出現(xiàn)在業(yè)界的各大計(jì)算引擎設(shè)計(jì)實(shí)現(xiàn)中。它不僅能夠提供靈活的實(shí)現(xiàn),減少代碼開發(fā)量,同樣在性能優(yōu)化方面也有著較多的應(yīng)用。但是同時(shí)基于ANTLR ASM的AnalyticDB代碼生成器也引入了數(shù)十毫秒編譯等待時(shí)間,這在實(shí)時(shí)分析場(chǎng)景中是不可接受的。為了進(jìn)一步減少這種延遲,分析引擎使用了緩存來重用生成的Java字節(jié)碼。但是,它并非能對(duì)所有情況都起很好作用。

隨著業(yè)務(wù)的廣泛使用以及對(duì)性能的進(jìn)一步追求,系統(tǒng)針對(duì)具體的情況對(duì)CodeGen做了進(jìn)一步的優(yōu)化。使用了Loading Cache對(duì)已經(jīng)生成的動(dòng)態(tài)代碼進(jìn)行緩存,但是SQL表達(dá)式中往往會(huì)出現(xiàn)常量(例如,substr(col1,1, 3),col1 like‘demo%’等),在原始的生成邏輯中會(huì)直接生成常量使用。這導(dǎo)致很多相同的方法在遇到不同的常量值時(shí)需要生成一整套新的邏輯。這樣在高并發(fā)場(chǎng)景下,cache命中率很低,并且導(dǎo)致JDK的meta區(qū)增長速度較快,更頻繁地觸發(fā)GC,從而導(dǎo)致查詢延遲抖動(dòng)。

  1. substr(col1,  1, 3) 
  2. =>  cacheKey<CallExpression(substr), inputReferenceExpression(col1),  constantExpression(1), constantExpression(3)>cacheValue bytecode; 

通過對(duì)表達(dá)式的常量在生成bytecode階段進(jìn)行rewrite,對(duì)出現(xiàn)的每個(gè)常量在Class級(jí)別生成對(duì)應(yīng)的成員變量來存儲(chǔ),去掉了Cachekey中的常量影響因素,使得可以在不同常量下使用相同的生成代碼。命中的CodeGen將在plan階段instance級(jí)別的進(jìn)行常量賦值。

  1. substr(col1,  1, 3) 
  2. =>  cacheKey<CallExpression(substr),  inputReferenceExpression(col1)>cacheValue bytecode; 

在測(cè)試與線上場(chǎng)景中,經(jīng)過優(yōu)化很多高并發(fā)的場(chǎng)景不再出現(xiàn)meta區(qū)的GC,這顯著增加了緩存命中率,整體運(yùn)行穩(wěn)定性以及平均延遲均有一定的提升。

AnalyticDB CodeGen不僅實(shí)現(xiàn)了謂詞評(píng)估,還支持了算子級(jí)別運(yùn)算。例如,在復(fù)雜SQL且數(shù)據(jù)量較大的場(chǎng)景下,數(shù)據(jù)會(huì)多次shuffle拷貝,在partitioned shuffle進(jìn)行數(shù)據(jù)拷貝的時(shí)候很容易出現(xiàn)CPU瓶頸。用于連接和聚合操作的數(shù)據(jù)Shuffle通常會(huì)復(fù)制從源數(shù)據(jù)塊到目標(biāo)數(shù)據(jù)塊的行,偽代碼如下所示:

  1. foreach row 
  2.    foreach column 
  3.       type.append(blockSrc, position, blockDest); 

從生產(chǎn)環(huán)境,大部分SQL每次shuffle的數(shù)據(jù)量較大,但是列很少。那么首先想到的就是forloop的展開。那么上面的偽代碼就可以轉(zhuǎn)換成

  1. foreach  row 
  2.    type(1).append(blockSrc(1), position,  blockDest(1)); 
  3.    type(2).append(blockSrc(2), position,  blockDest(2)); 
  4.    type(3).append(blockSrc(3), position,  blockDest(3)); 

上面的優(yōu)化通過直接編碼是無法完成的,需要根據(jù)SQL具體的column情況動(dòng)態(tài)的生成對(duì)應(yīng)的代碼實(shí)現(xiàn)。在測(cè)試中1000w的數(shù)據(jù)量級(jí)拷貝延時(shí)可以提升24%。

矢量化引擎和二進(jìn)制數(shù)據(jù)處理

相對(duì)于行式計(jì)算,AnalyticDB的矢量化計(jì)算由于對(duì)緩存更加友好,并避免了不必要的數(shù)據(jù)加載,從而擁有了更高的效率。在這之上,AnalyticDB CodeGen也將運(yùn)行態(tài)因素考慮在內(nèi),能夠輕松利用異構(gòu)硬件的強(qiáng)大功能。例如,在CPU支持AVX-512指令集的集群,AnalyticDB可以生成使用SIMD的字節(jié)碼。同時(shí)AnalyticDB內(nèi)部所有計(jì)算都是基于二進(jìn)制數(shù)據(jù),而不是Java Object,有效避免了序列化和反序列化開銷。

極致彈性

在多租戶基礎(chǔ)上,AnalyticDB對(duì)每個(gè)租戶的DB支持在線升降配,擴(kuò)縮容,操作過程中無需停服,對(duì)業(yè)務(wù)幾乎透明。以下圖為例:

  • 用戶開始可以在云上開通包含兩個(gè)C4資源的DB進(jìn)行業(yè)務(wù)試用和上線(圖中的P1, P2...代表表的數(shù)據(jù)分區(qū))
  • 隨著業(yè)務(wù)的增長,當(dāng)兩個(gè)C4的存儲(chǔ)或計(jì)算資源無法滿足時(shí),用戶可自主對(duì)該DB發(fā)起升配或擴(kuò)容操作,升配+擴(kuò)容可同時(shí)進(jìn)行。該過程會(huì)按副本交替進(jìn)行,保證整個(gè)過程中始終有一個(gè)副本提供服務(wù)。另外,擴(kuò)容增加節(jié)點(diǎn)后,數(shù)據(jù)會(huì)自動(dòng)在新老節(jié)點(diǎn)間進(jìn)行重分布。
  • 對(duì)于臨時(shí)性的業(yè)務(wù)增長(如電商大促),升配擴(kuò)容操作均可逆,在大促過后,可自主進(jìn)行降配縮容操作,做到靈活地成本控制。

在線升降配,平滑擴(kuò)縮容能力,對(duì)今年雙十一阿里巴巴集團(tuán)內(nèi)和公共云上和電商物流相關(guān)的業(yè)務(wù)庫起到了至關(guān)重要的保障作用。

GPU加速

客戶業(yè)務(wù)痛點(diǎn)

某客戶數(shù)據(jù)業(yè)務(wù)的數(shù)據(jù)量在半年時(shí)間內(nèi)由不到200TB增加到1PB,并且還在快速翻番,截止到發(fā)稿時(shí)為止已經(jīng)超過1PB。該業(yè)務(wù)計(jì)算復(fù)雜,查詢時(shí)間跨度周期長,需按照任意選擇屬性過濾,單個(gè)查詢計(jì)算涉及到的算子包括20個(gè)以上同時(shí)交并差、多表join、多值列(類似array)group by等以及上述算子的各種復(fù)雜組合。傳統(tǒng)的MapReduce離線分析方案時(shí)效性差,極大限制了用戶快速分析、快速鎖定人群并即時(shí)投放廣告的訴求,業(yè)務(wù)發(fā)展面臨新的瓶頸。

AnalyticDB加速方案

GPU加速AnalyticDB的做法是在Compute Node中新增GPU Engine對(duì)查詢進(jìn)行加速。GPU Engine主要包括: Plan Rewriter、Task Manager、Code Generator、CUDA Manager、Data Manager和VRAM Manager。

SQL查詢從Front Node發(fā)送到Compute Node,經(jīng)過解析和邏輯計(jì)劃生成以后,Task Manager先根據(jù)計(jì)算的數(shù)據(jù)量以及查詢特征選擇由CPU Engine還是GPU Engine來處理,然后根據(jù)邏輯計(jì)劃生成適合GPU執(zhí)行的物理計(jì)劃。

GPU Engine收到物理計(jì)劃后先對(duì)執(zhí)行計(jì)劃進(jìn)行重寫。如果計(jì)劃符合融合特征,其中多個(gè)算子會(huì)被融合成單個(gè)復(fù)合算子,從而大量減少算子間臨時(shí)數(shù)據(jù)的Buffer傳輸。

Rewriting之后物理計(jì)劃進(jìn)入Code Generator,該模塊主功能是將物理計(jì)劃編譯成PTX代碼。Code Generator第一步借助LLVM JIT先將物理計(jì)劃編譯成LLVM IR,IR經(jīng)過優(yōu)化以后通過LLVMNVPTX Target轉(zhuǎn)換成PTX代碼。CUDA運(yùn)行時(shí)庫會(huì)根據(jù)指定的GPU架構(gòu)型號(hào)將PTX轉(zhuǎn)換成本地可執(zhí)行代碼,并啟動(dòng)其中的GPU kernel。Code Generator可以支持不同的Nvidia GPU。

CUDA Manager通過jCUDA調(diào)用CUDA API,用于管理和配置GPU設(shè)備、GPU kernel的啟動(dòng)接口封裝。該模塊作為Java和GPU之間的橋梁,使得JVM可以很方便地調(diào)用GPU資源。

Data Manager主要負(fù)責(zé)數(shù)據(jù)加載,將數(shù)據(jù)從磁盤或文件系統(tǒng)緩存加載到指定堆外內(nèi)存,從堆外內(nèi)存加載到顯存。CPU Engine的執(zhí)行模型是數(shù)據(jù)庫經(jīng)典的火山模型,即表數(shù)據(jù)需逐行被拉取再計(jì)算。這種模型明顯會(huì)極大閑置GPU上萬行的高吞吐能力。目前Data Manager能夠批量加載列式數(shù)據(jù)塊,每次加載的數(shù)據(jù)塊大小為256M,然后通過PCIe總線傳至顯存。

VRAM Manager用于管理各GPU的顯存。顯存是GPU中最稀缺的資源,需要合理管理和高效復(fù)用,有別于現(xiàn)在市面上其他GPU數(shù)據(jù)庫系統(tǒng)使用GPU的方式,即每個(gè)SQL任務(wù)獨(dú)占所有的GPU及其計(jì)算和顯存資源。為了提升顯存的利用率、提升并發(fā)能力,結(jié)合AnalyticDB多分區(qū)、多線程的特點(diǎn),我們?cè)O(shè)計(jì)基于Slab的VRAM Manager統(tǒng)一管理所有顯存申請(qǐng):Compute Node啟動(dòng)時(shí),VRAM Manager先申請(qǐng)所需空間并切分成固定大小的Slab,這樣可以避免運(yùn)行時(shí)申請(qǐng)帶來的時(shí)間開銷,也降低通過顯卡驅(qū)動(dòng)頻繁分配顯存的DoS風(fēng)險(xiǎn)。

在需要顯存時(shí),VRAM Manager會(huì)從空閑的Slab中查找空閑區(qū)域劃分顯存,用完后返還Slab并做Buddy合并以減少顯存空洞。性能測(cè)試顯示分配時(shí)間平均為1ms,對(duì)于整體運(yùn)行時(shí)間而言可忽略不計(jì),明顯快于DDR內(nèi)存分配的700ms耗時(shí),也利于提高系統(tǒng)整體并發(fā)度。在GPU和CPU數(shù)據(jù)交互時(shí),自維護(hù)的JVM堆外內(nèi)存會(huì)作為JVM內(nèi)部數(shù)據(jù)對(duì)象(如ByteBuffer)和顯存數(shù)據(jù)的同步緩沖區(qū),也一定程度減少了Full GC的工作量。

GPU Engine采用即時(shí)代碼生成技術(shù)主要有如下優(yōu)點(diǎn):

  • 相對(duì)傳統(tǒng)火山模型,減少計(jì)劃執(zhí)行中的函數(shù)調(diào)用等,尤其是分支判斷,GPU中分支跳轉(zhuǎn)會(huì)降低執(zhí)行性能
  • 靈活支持各種復(fù)雜表達(dá)式,例如projection和having中的復(fù)雜表達(dá)式。例如HAVING SUM(double_field_foo) > 1這種表達(dá)式的GPU代碼是即時(shí)生成的
  • 靈活支持各種數(shù)據(jù)類型和UDF查詢時(shí)追加
  • 利于算子融合,如group-by聚合、join再加聚合的融合,即可減少中間結(jié)果(特別是Join的連接結(jié)果)的拷貝和顯存的占用

根據(jù)邏輯執(zhí)行計(jì)劃動(dòng)態(tài)生成GPU執(zhí)行碼的整個(gè)過程如下所示:

GPU 加速實(shí)際效果

該客戶數(shù)據(jù)業(yè)務(wù)使用了GPU實(shí)時(shí)加速后,將計(jì)算復(fù)雜、響應(yīng)時(shí)間要求高、并發(fā)需求高的查詢從離線分析系統(tǒng)切換至AnalyticDB進(jìn)行在線分析運(yùn)行穩(wěn)定,MapReduce離線分析的平均響應(yīng)時(shí)間為5到10分鐘,高峰時(shí)可能需要30分鐘以上。無縫升級(jí)到GPU加速版AnalyticDB之后,所有查詢完全實(shí)時(shí)處理并保證秒級(jí)返回,其中80%的查詢的響應(yīng)時(shí)間在2秒以內(nèi)(如下圖),而節(jié)點(diǎn)規(guī)模降至原CPU集群的三分之一左右。 業(yè)務(wù)目前可以隨時(shí)嘗試各種圈人標(biāo)簽組合快速對(duì)人群畫像,即時(shí)鎖定廣告投放目標(biāo)。據(jù)客戶方反饋,此加速技術(shù)已經(jīng)幫助其在競(jìng)爭中構(gòu)建起高壁壘,使該業(yè)務(wù)成為同類業(yè)務(wù)的核心能力,預(yù)計(jì)明年用戶量有望翻番近一個(gè)數(shù)量級(jí)。

總結(jié)

簡單對(duì)本文做個(gè)總結(jié),AnalyticDB做到讓數(shù)據(jù)價(jià)值在線化的核心技術(shù)可歸納為:

  • 高性能SQL Parser:自研Parser組件FastSQL,極致的解析性能,無縫集合優(yōu)化器
  • 玄武存儲(chǔ)引擎:數(shù)據(jù)更新實(shí)時(shí)可見,行列混存,粗糙集過濾,聚簇列,索引優(yōu)化
  • 羲和計(jì)算引擎:MPP+DAG融合計(jì)算,CBO優(yōu)化,向量化執(zhí)行,GPU加速
  • 極致彈性:業(yè)務(wù)透明的在線升降配,擴(kuò)縮容,靈活控制成本。
  • GPU加速:利用GPU硬件加速OLAP分析,大幅度降低查詢延時(shí)。

分析型數(shù)據(jù)AnalyticDB, 作為阿里巴巴自研的下一代PB級(jí)實(shí)時(shí)數(shù)據(jù)倉庫, 承載著整個(gè)集團(tuán)內(nèi)和云上客戶的數(shù)據(jù)價(jià)值實(shí)時(shí)化分析的使命。 AnalyticDB為數(shù)據(jù)價(jià)值在線化而生,作為實(shí)時(shí)云數(shù)據(jù)倉庫平臺(tái),接下來會(huì)在體驗(yàn)和周邊生態(tài)建設(shè)上繼續(xù)加快建設(shè),希望能將最領(lǐng)先的下一代實(shí)時(shí)分析技術(shù)能力普惠給所有企業(yè),幫助企業(yè)轉(zhuǎn)型加速數(shù)據(jù)價(jià)值探索和在線化。

【本文為51CTO專欄作者“阿里巴巴官方技術(shù)”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】 

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2021-10-18 11:58:56

負(fù)載均衡虛擬機(jī)

2022-02-15 18:45:35

Linux進(jìn)程調(diào)度器

2022-09-06 08:02:40

死鎖順序鎖輪詢鎖

2021-06-01 08:29:08

dubbo線程池服務(wù)暴露

2021-01-19 05:49:44

DNS協(xié)議

2022-09-14 09:01:55

shell可視化

2020-07-15 08:57:40

HTTPSTCP協(xié)議

2020-11-16 10:47:14

FreeRTOS應(yīng)用嵌入式

2020-07-09 07:54:35

ThreadPoolE線程池

2022-10-10 08:35:17

kafka工作機(jī)制消息發(fā)送

2022-07-19 16:03:14

KubernetesLinux

2024-03-07 18:11:39

Golang采集鏈接

2024-05-10 12:59:58

PyTorch人工智能

2023-06-12 08:49:12

RocketMQ消費(fèi)邏輯

2022-09-08 10:14:29

人臉識(shí)別算法

2024-01-11 09:53:31

面試C++

2024-01-05 08:30:26

自動(dòng)駕駛算法

2022-07-15 16:31:49

Postman測(cè)試

2021-08-26 05:02:50

分布式設(shè)計(jì)

2021-06-04 07:27:24

sourcemap前端技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)