中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

阿里如何實(shí)現(xiàn)海量數(shù)據(jù)實(shí)時(shí)分析?

2020-01-08    來(lái)源:raincent

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

挑戰(zhàn)

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

在線化和高可用,離線和在線的邊界越來(lái)越模糊,一切數(shù)據(jù)皆服務(wù)化、一切分析皆在線化。

高并發(fā)低延時(shí),越來(lái)越多的數(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ù)檢索和分析問(wèn)題。

阿里巴巴最初通過(guò)單節(jié)點(diǎn) Oracle 進(jìn)行準(zhǔn)實(shí)時(shí)分析, 后來(lái)轉(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 年開(kāi)始,在線分析這個(gè)技術(shù)領(lǐng)域,阿里實(shí)時(shí)數(shù)倉(cāng)堅(jiān)定的走上了自研之路。

 

 作者:AnalyticDB

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

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

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

經(jīng)過(guò)這 2 年的演進(jìn)和創(chuàng)新,AnalyticDB 已經(jīng)成長(zhǎng)為兼容 MySQL 5.x 系列、并在此基礎(chǔ)上增強(qiáng)支持 ANSI SQL:2003 的 OLAP 標(biāo)準(zhǔn)(如 window function)的通用實(shí)時(shí)數(shù)倉(cāng),躋身為實(shí)時(shí)數(shù)倉(cāng)領(lǐng)域極具行業(yè)競(jìng)爭(zhē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),開(kāi)始進(jìn)入全球分析市場(chǎng)。AnalyticDB 旨在幫客戶將整個(gè)數(shù)據(jù)分析和價(jià)值化從傳統(tǒng)的離線分析帶到下一代的在線實(shí)時(shí)分析模式。

整體架構(gòu)

經(jīng)過(guò)過(guò)去 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í)寫(xiě)入和查詢時(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 解析、重寫(xiě);分區(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í)寫(xiě)入,并根據(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ò)容、無(wú)縫升級(jí)、刪庫(kù)刪表的后臺(tái)異步數(shù)據(jù)清理等。

Connector Service:數(shù)據(jù)源連接服務(wù),負(fù)責(zé)外部各數(shù)據(jù)源(圖中右側(cè)部分)接入到 AnalyticDB。目前該服務(wù)開(kāi)發(fā)基本完成,即將上線提供云服務(wù)。

Monitoring & Alerting Service:監(jiān)控告警診斷服務(wù),既提供面向內(nèi)部人員的運(yùn)維監(jiān)控告警診斷平臺(tái),又作為數(shù)據(jù)源通過(guò) Management Console 面向用戶側(cè)提供數(shù)據(jù)庫(kù)監(jiān)控服務(wù)。

Resource Management Service:資源管理服務(wù),負(fù)責(zé)集群級(jí)別和 DB 級(jí)別服務(wù)的創(chuàng)建、刪除、DNS/SLB 掛載 / 卸載、擴(kuò)縮容、升降配,無(wú)縫升級(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ù)庫(kù)建立時(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 來(lái)說(shuō),事實(shí)表的每個(gè) List 分區(qū)是一個(gè)物理存儲(chǔ)單元(如果沒(méi)有指定 List 分區(qū)列,可認(rèn)為該 Hash 分區(qū)只有一個(gè) List 分區(qū))。一個(gè)分區(qū)物理存儲(chǔ)單元采用行列混存模式,配合元數(shù)據(jù)和索引,提供高效查詢。

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

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

阿里巴巴集團(tuán)某營(yíng)銷應(yīng)用單 DB 表數(shù)超過(guò) 20000 張

云上某企業(yè)客戶單 DB 數(shù)據(jù)量近 3PB,單日分析查詢次數(shù)超過(guò) 1 億

阿里巴巴集團(tuán)內(nèi)某單個(gè) AnalyticDB 集群超過(guò) 2000 臺(tái)節(jié)點(diǎn)規(guī)模

云上某業(yè)務(wù)實(shí)時(shí)寫(xiě)入壓力高達(dá) 1000w TPS

菜鳥(niǎo)網(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ù)倉(cāng)來(lái)說(shuō)至關(guān)重要,AnalyticDB 當(dāng)前既支持通過(guò)阿里云數(shù)據(jù)傳輸服務(wù) DTS、DataWorks 數(shù)據(jù)集成從各種外部數(shù)據(jù)源導(dǎo)入入庫(kù),同時(shí)也在不斷完善自身的數(shù)據(jù)導(dǎo)入能力。整體導(dǎo)入導(dǎo)出能力如下圖(其中導(dǎo)入部分?jǐn)?shù)據(jù)源當(dāng)前已支持,部分在開(kāi)發(fā)中,即將發(fā)布)。

 

 

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

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

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

另外,對(duì)于 OSS,MaxCompute 這樣的外部數(shù)據(jù)源,AnalyticDB 通過(guò)分布式的 Connector Service 數(shù)據(jù)導(dǎo)入服務(wù)并發(fā)讀取并寫(xiě)入到相應(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 工具等通過(guò)相應(yīng)插件支持,能夠快速把數(shù)據(jù)寫(xiě)入相應(yīng) DB。

今天在阿里巴巴集團(tuán)內(nèi),每天有數(shù)萬(wàn)張表從 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é)果寫(xiě)入到內(nèi)部表,而導(dǎo)出操作則是寫(xiě)入外部存儲(chǔ), 通過(guò)改進(jìn)實(shí)現(xiàn)機(jī)制,可以方便地支持更多的導(dǎo)出數(shù)據(jù)源。

核心技術(shù)

高性能 SQL Parser

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

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

AnalyticDB 主打的場(chǎng)景是高并發(fā)、低延時(shí)的在線化分析,對(duì) SQL Parser 性能要求很高,批量實(shí)時(shí)寫(xiě)入等場(chǎng)景要求更加苛刻。FastSQL 通過(guò)多種技術(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 要高得多,通過(guò)分支預(yù)測(cè)可以減少判斷提升性能。

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

 

 

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

在結(jié)合 AnalyticDB 的優(yōu)化器的 SQL 優(yōu)化實(shí)踐中,F(xiàn)astSQL 不斷將 SQL Rewrite 的優(yōu)化能力前置化到 SQL Parser 中實(shí)現(xiàn),通過(guò)與優(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 的能力,例如:

 

 

玄武存儲(chǔ)引擎

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

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

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

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

 

 

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

業(yè)務(wù)實(shí)時(shí)數(shù)據(jù)通過(guò) JDBC/ODBC 協(xié)議寫(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)提交到盤(pán)古分布式文件系統(tǒng),同時(shí)更新實(shí)時(shí)數(shù)據(jù)版本,并返回 Front Node,F(xiàn)ront Node 返回寫(xiě)入成功響應(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)求通過(guò) 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ù)寫(xiě)入量比較大時(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 無(wú)法正常拉取最新版本的數(shù)據(jù),Compute Node 會(huì)直接從盤(pán)古上獲取數(shù)據(jù)(即便這樣需要忍受更高的延遲)來(lái)保證查詢的正常執(zhí)行。數(shù)據(jù)在 Compute Node 上也是備份存儲(chǔ)。如下圖所示,數(shù)據(jù)是通過(guò)分區(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 都是無(wú)狀態(tài)的,他們可以根據(jù)業(yè)務(wù)負(fù)載需求進(jìn)行任意的增減;2)玄武并不實(shí)際存儲(chǔ)數(shù)據(jù),而是將數(shù)據(jù)存到底層的盤(pán)古系統(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ù)庫(kù)一般采用行存儲(chǔ) (Row-oriented Storage) 加 B-tree 索引,優(yōu)勢(shì)在于其讀取多列或所有列 (SELECT *) 場(chǎng)景下的性能,典型的例子如 MySQL 的 InnoDB 引擎。但是在讀取單列、少數(shù)列并且行數(shù)很多的場(chǎng)景下,行存儲(chǔ)會(huì)存在嚴(yán)重的讀放大問(wèn)題。

數(shù)據(jù)倉(cāng)庫(kù)系統(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ì)帶來(lái)大量的隨機(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 在磁盤(pán)上連續(xù)存放。

Row Group 內(nèi)列 block 的數(shù)據(jù)可按指定列 (聚集列) 排序存放,好處是在按該列查詢時(shí)顯著減少磁盤(pán)隨機(jī) IO 次數(shù)。

每個(gè)列 block 可開(kāi)啟壓縮。

行列混存存儲(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ù)索引等,而用的最多的是倒排索引。

 

 

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

 

 

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

當(dāng)這些未構(gòu)建索引的數(shù)據(jù)(稱為實(shí)時(shí)數(shù)據(jù))積累到一定數(shù)量時(shí),玄武會(huì)開(kāi)啟多個(gè) MapReduce 任務(wù),來(lái)對(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ù)通過(guò)伏羲進(jìn)行分布式調(diào)度和執(zhí)行,異步地完成索引的構(gòu)建。這種異步構(gòu)建索引的方式,既不影響 AnalyticDB 的高吞吐寫(xiě)入,也不影響 AnalyticDB 的高性能查詢。

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

如下圖所示,玄武在將實(shí)時(shí)數(shù)據(jù)以 block 形式刷到磁盤(pán)之前,會(huì)根據(jù)每一列的實(shí)時(shí)數(shù)據(jù)生成對(duì)應(yīng)的排序索引。排序索引實(shí)際是一個(gè)行號(hào)數(shù)組,對(duì)于升序排序索引來(lái)說(shuō),行號(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ī)則,用來(lái)確保不會(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è)。通過(guò)類似于最長(zhǎng)公共子序列的算法,對(duì)整個(gè)執(zhí)行計(jì)劃進(jìn)行遍歷,并對(duì)一些可以忽略的算子進(jìn)行特殊處理,如 Projection,最終達(dá)到減少計(jì)算的目的。

 

 

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

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

 

 

在線分析的場(chǎng)景對(duì)優(yōu)化器有很高的要求,AnalyticDB 為此開(kāi)發(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ù)重分布的算子來(lái)保證其執(zhí)行語(yǔ)義的正確。 數(shù)據(jù)重分布帶來(lái)的物理開(kāi)銷非常大,涉及到數(shù)據(jù)的序列化、反序列化、網(wǎng)絡(luò)開(kāi)銷等等,因此避免多次數(shù)據(jù)重分布對(duì)于分布式計(jì)算是非常重要的。除此之外,優(yōu)化器也會(huì)考慮對(duì)數(shù)據(jù)庫(kù)索引的使用,進(jìn)一步減少 Join 過(guò)程中構(gòu)建哈希的開(kāi)銷。

調(diào)整 Join 順序時(shí),如果大多數(shù) Join 是在分區(qū)列,優(yōu)化器將避免生成 Bushy Tree,而更偏向使用 Left Deep Tree,并盡量使用現(xiàn)有索引進(jìn)行查找。

 

 

優(yōu)化器更近一步下推了謂詞和聚合。聚合函數(shù),比如 count(),和查詢過(guò)濾可以直接基于索引計(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ù)倉(cāng)庫(kù)僅收集有限的統(tǒng)計(jì)信息,例如列上典型的最常值(MFV)。商業(yè)數(shù)據(jù)庫(kù)為用戶提供了收集統(tǒng)計(jì)信息的工具,但這通常取決于 DBA 的經(jīng)驗(yàn),依賴 DBA 來(lái)決定收集哪些統(tǒng)計(jì)數(shù)據(jù),并依賴于服務(wù)或工具供應(yīng)商。

上述方法收集的統(tǒng)計(jì)數(shù)據(jù)通常都是靜態(tài)的,它可能需要在一段時(shí)間后,或者當(dāng)數(shù)據(jù)更改達(dá)到一定程度,來(lái)重新收集。但是,隨著業(yè)務(wù)應(yīng)用程序變得越來(lái)越復(fù)雜和動(dòng)態(tài),預(yù)定義的統(tǒng)計(jì)信息收集可能無(wú)法以更有針對(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ī)制來(lái)解決此問(wèn)題。守護(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ù)即將到來(lái)的查詢受益。對(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ù)來(lái)估計(jì)聚合中不同選項(xiàng)的成本并做出正確的決策。

計(jì)劃緩存

從在線應(yīng)用案件看,大多數(shù)客戶都有一個(gè)共同的特點(diǎn),他們經(jīng)常反復(fù)提交類似的查詢。在這種情況下,計(jì)劃緩存變得至關(guān)重要。為了提高緩存命中率,AnalyticDB 不使用原始 SQL 文本作為搜索鍵來(lái)緩存。相反,SQL 語(yǔ)句首先通過(guò)重寫(xiě)并參數(shù)化來(lái)提取模式。例如,查詢 “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è)問(wèn)題。假設(shè)我們?cè)诹?a 上有索引,“SELECT * FROM t1 WHERE a = 5”的優(yōu)化計(jì)劃可以將索引掃描作為其最佳訪問(wèn)路徑。但是,如果新查詢是“SELECT * FROM t1 WHERE a = 0”并且直方圖告訴我們數(shù)值 0 在表 t1 占大多數(shù),那么索引掃描可能不如全表掃描有效。在這種情況下,使用緩存中的計(jì)劃并不是一個(gè)好的決定。為了避免這類問(wèn)題,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 類查詢,盡量無(wú)中間 Stage 落盤(pán))且各個(gè) stage 之間都是 pipeline 方式協(xié)作,性能上要比 MapReduce 方式快一個(gè)數(shù)量級(jí)。

 

 

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

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

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

AnalyticDB worker 接收 coordinator 下發(fā)的任務(wù), 負(fù)責(zé)該任務(wù)的物理執(zhí)行計(jì)劃的實(shí)際執(zhí)行。這項(xiàng)任務(wù)可以來(lái)自不同的查詢, 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)景,通過(guò)時(shí)間片的分配比例來(lái)體現(xiàn)不同查詢的優(yōu)先級(jí),AnalyticDB 實(shí)現(xiàn)了一個(gè)簡(jiǎn)單版本的類 Linux kernel 的調(diào)度算法。系統(tǒng)記錄了每一個(gè)查詢的總執(zhí)行耗時(shí),查詢總耗時(shí)又是通過(guò)每一個(gè) Task 耗時(shí)來(lái)進(jìn)行加權(quán)統(tǒng)計(jì)的,最終在查詢層面形成了一顆紅黑樹(shù),每次總是挑選最左側(cè)節(jié)點(diǎn)進(jìn)行調(diào)度,每次取出或者加入(被喚醒以及重新入隊(duì))都會(huì)重新更新這棵樹(shù),同樣的,在 Task 被喚醒加入這顆樹(shù)的時(shí)候,執(zhí)行引擎考慮了補(bǔ)償機(jī)制,即時(shí)間片耗時(shí)如果遠(yuǎn)遠(yuǎn)低于其他 Task 的耗時(shí),確保其在整個(gè)樹(shù)里面的位置,同時(shí)也避免了因?yàn)殚L(zhǎng)時(shí)間的阻塞造成的饑餓,類似于 CFS 調(diào)度算法中的 vruntime 補(bǔ)償機(jī)制。

 

 

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

 

 

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

 

 

同樣的在實(shí)際應(yīng)用中是很難要求用戶來(lái)辨別快慢查詢,因?yàn)橛脩舻臉I(yè)務(wù)本身可能就沒(méi)有快慢業(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),減少代碼開(kāi)發(fā)量,同樣在性能優(yōu)化方面也有著較多的應(yīng)用。但是同時(shí)基于 ANTLR ASM 的 AnalyticDB 代碼生成器也引入了數(shù)十毫秒編譯等待時(shí)間,這在實(shí)時(shí)分析場(chǎng)景中是不可接受的。為了進(jìn)一步減少這種延遲,分析引擎使用了緩存來(lái)重用生成的 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ū)增長(zhǎng)速度較快,更頻繁地觸發(fā) GC,從而導(dǎo)致查詢延遲抖動(dòng)。

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

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

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

在測(cè)試與線上場(chǎng)景中,經(jīng)過(guò)優(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ù)塊的行,偽代碼如下所示:

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

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

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

上面的優(yōu)化通過(guò)直接編碼是無(wú)法完成的,需要根據(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,有效避免了序列化和反序列化開(kāi)銷。

極致彈性

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

 

 

用戶開(kāi)始可以在云上開(kāi)通包含兩個(gè) C4 資源的 DB 進(jìn)行業(yè)務(wù)試用和上線(圖中的 P1, P2…代表表的數(shù)據(jù)分區(qū))

隨著業(yè)務(wù)的增長(zhǎng),當(dāng)兩個(gè) C4 的存儲(chǔ)或計(jì)算資源無(wú)法滿足時(shí),用戶可自主對(duì)該 DB 發(fā)起升配或擴(kuò)容操作,升配 + 擴(kuò)容可同時(shí)進(jìn)行。該過(guò)程會(huì)按副本交替進(jìn)行,保證整個(gè)過(guò)程中始終有一個(gè)副本提供服務(wù)。另外,擴(kuò)容增加節(jié)點(diǎn)后,數(shù)據(jù)會(huì)自動(dòng)在新老節(jié)點(diǎn)間進(jìn)行重分布。

對(duì)于臨時(shí)性的業(yè)務(wù)增長(zhǎng)(如電商大促),升配擴(kuò)容操作均可逆,在大促過(guò)后,可自主進(jìn)行降配縮容操作,做到靈活地成本控制。

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

GPU 加速

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

某客戶數(shù)據(jù)業(yè)務(wù)的數(shù)據(jù)量在半年時(shí)間內(nèi)由不到 200TB 增加到 1PB,并且還在快速翻番,截止到發(fā)稿時(shí)為止已經(jīng)超過(guò) 1PB。該業(yè)務(wù)計(jì)算復(fù)雜,查詢時(shí)間跨度周期長(zhǎng),需按照任意選擇屬性過(guò)濾,單個(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)過(guò)解析和邏輯計(jì)劃生成以后,Task Manager 先根據(jù)計(jì)算的數(shù)據(jù)量以及查詢特征選擇由 CPU Engine 還是 GPU Engine 來(lái)處理,然后根據(jù)邏輯計(jì)劃生成適合 GPU 執(zhí)行的物理計(jì)劃。

GPU Engine 收到物理計(jì)劃后先對(duì)執(zhí)行計(jì)劃進(jìn)行重寫(xiě)。如果計(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)過(guò)優(yōu)化以后通過(guò) LLVMNVPTX Target 轉(zhuǎn)換成 PTX 代碼。CUDA 運(yùn)行時(shí)庫(kù)會(huì)根據(jù)指定的 GPU 架構(gòu)型號(hào)將 PTX 轉(zhuǎn)換成本地可執(zhí)行代碼,并啟動(dòng)其中的 GPU kernel。Code Generator 可以支持不同的 Nvidia GPU。

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

VRAM Manager 用于管理各 GPU 的顯存。顯存是 GPU 中最稀缺的資源,需要合理管理和高效復(fù)用,有別于現(xiàn)在市面上其他 GPU 數(shù)據(jù)庫(kù)系統(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)帶來(lái)的時(shí)間開(kāi)銷,也降低通過(guò)顯卡驅(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è)過(guò)程如下所示:

 

 

★ 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 分鐘以上。無(wú)縫升級(jí)到 GPU 加速版 AnalyticDB 之后,所有查詢完全實(shí)時(shí)處理并保證秒級(jí)返回,其中 80% 的查詢的響應(yīng)時(shí)間在 2 秒以內(nèi)(如下圖),而節(jié)點(diǎn)規(guī)模降至原 CPU 集群的三分之一左右。 業(yè)務(wù)目前可以隨時(shí)嘗試各種圈人標(biāo)簽組合快速對(duì)人群畫(huà)像,即時(shí)鎖定廣告投放目標(biāo)。據(jù)客戶方反饋,此加速技術(shù)已經(jīng)幫助其在競(jìng)爭(zhēng)中構(gòu)建起高壁壘,使該業(yè)務(wù)成為同類業(yè)務(wù)的核心能力,預(yù)計(jì)明年用戶量有望翻番近一個(gè)數(shù)量級(jí)。

 

 

總結(jié)

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

高性能 SQL Parser:自研 Parser 組件 FastSQL,極致的解析性能,無(wú)縫集合優(yōu)化器

玄武存儲(chǔ)引擎:數(shù)據(jù)更新實(shí)時(shí)可見(jiàn),行列混存,粗糙集過(guò)濾,聚簇列,索引優(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ù)倉(cāng)庫(kù), 承載著整個(gè)集團(tuán)內(nèi)和云上客戶的數(shù)據(jù)價(jià)值實(shí)時(shí)化分析的使命。 AnalyticDB 為數(shù)據(jù)價(jià)值在線化而生,作為實(shí)時(shí)云數(shù)據(jù)倉(cāng)庫(kù)平臺(tái),接下來(lái)會(huì)在體驗(yàn)和周邊生態(tài)建設(shè)上繼續(xù)加快建設(shè),希望能將最領(lǐng)先的下一代實(shí)時(shí)分析技術(shù)能力普惠給所有企業(yè),幫助企業(yè)轉(zhuǎn)型加速數(shù)據(jù)價(jià)值探索和在線化。

本文轉(zhuǎn)載自公眾號(hào)阿里技術(shù)(ID:ali_tech)。

原文鏈接:https://mp.weixin.qq.com/s/kt-xtvM77UZ3kD-3dpU7sw

標(biāo)簽: 數(shù)據(jù)實(shí)時(shí)分析

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Spark 誕生頭十年:Hadoop 由盛轉(zhuǎn)衰,統(tǒng)一數(shù)據(jù)分析大行其道

下一篇:值得推薦的8個(gè)git/github項(xiàng)目數(shù)據(jù)分析工具